face

2020-05-20  本文已影响0人  Luoyilin
html&css 部分
BFC和IFC

FC是页面中的一块渲染区域,并且有一套渲染规则,他决定了子元素如何定位,以及和其他元素的关系和相互作用。BFC和IFC都是常见的FC
1.BFC 块及格式上下文的 规则:

CSS清楚浮动

1.父元素定高 手动撑开;
2.浮动元素末尾添加空标签,设置clear:both
3.父元素设置overflow:hidden
4.父元素添加伪类after和zoom,常用的方法是双伪元素法清楚浮动防塌陷

.clearfix:before,
.clearfix:after{
  content :''
  display:block
  clear :both
 }
.clearfix{
  zoom:1
 }
盒模型

盒模型包括: content, padding, border, margin 盒模型分为: IE 盒模型(怪异盒模型 border-box) 和 w3c 盒模型(标准盒模型 content-box) border-box: 盒子宽度由 content, padding, border 组成 content-box: 盒子宽度由 content 组成 其余类似

css选择器优先级
!important > 内联样式(style) > (ID)选择器>类/属性/伪类>元素> 关系
CSS实现三列布局(左右固定,中间自适应)
H5 自适应方案
rem 布局 vw  vh 和 calc 函数
JS 部分
DOM 节点的创建和常用API
Call / bind / apply 的作用和区别

他们都可以改变作用域 :

谈一谈EventLoop (事件循环)

js是一门单线程语言,同一时间只能执行一个任务,即代码执行时同步并且阻塞的只能同步执行肯定有问题, 索引引入异步函数, EventLoop就是为了确保异步代码可以在同步代码执行后继续执行

  function loginfo(){
    console.log('this is  something……'
  }
  function do(){
    console.log('start~')
    loginfo()
  }
以上代码在调用栈中的运行顺序如下:

1.do()
2.do(), console.log('start!')
3.do()
4.do(), logInofo()
5.do(), logInofo(), console.log('this is someting...')
6.do(), logInofo()
7.do()
Empty, 执行完毕

以上都是同步代码,代码在运行时,只用调用栈解释就可以了如果是一个request请求,或者定时器,该如何执行呢?因此引出 事件表格(Event table)和事件队列(Event Queue)

宏任务和微任务

  1. 浏览器环境下常见的宏任务和微任务 :
    • 宏任务 : script标签里的代码 , setTimeout setInterval I/O UI render
    • 微任务 : process.nextTick,promise,Object.observe(废弃), MutationObserve
     setTimeout(()=>{
            console.log('1')
        })
        new Promise((reslove)=>{
            console.log('2')
            reslove()
        }).then(()=>{
            console.log('3')
        })
        console.log("4")
    // log  2 4 3 1

/**
 过程:
 1. 遇到setTimeout, 将其回调函数注册后分发到宏任务队列等待执行
 2.接下来遇到Promise, new Promise 立即执行, 遇到console.log('2')打印 2, then函数分发到微任务队列等待执行
 3.接下来遇到console.log('4'), 理解执行, 打印 4
 4.此时 Event Loop 会去检查微任务队列是否有微任务需要执行, 有, 立即执行, 打印 3
 5.到此, 整体代码作为第一轮宏任务执行结束, 打印了 2 4 3
 6.开始第二轮宏任务, 发现console.log('1'), 打印 1
 7.全部执行完毕, 打印 2 4 3 1

node 环境更为复杂, 暂不做讨论....
*/
get 和 post 的区别

const express = require('express')
const router = require ('express').Router()
const app = express()
router.get('/getData',getDataHander)
app.listen(31001,()=>{
console.log('http://localhost:31001'
})
getDataHander((req,res)=>{
let callback = req.callback
let data={
  content:{
    name:'zs'
    age :18
  }
}
 res.send(`callback(${Json.stringify(data)})`)
})
//前端
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="localhost:31001?callback=getData"></script>
    <script>
      function getData(data) {
        // ...
      }
    </script>
  </body>
</html>
防抖与节流

防抖和截流都是希望在同一时间内,不要重复处理请求,一般场景用在搜索和网页滚动事件中

// 1. 防抖
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="localhost:31001?callback=getData"></script>
    <script>
      function getData(data) {
        // ...
      }
    </script>
  </body>
</html>
//2 节流
//01) 时间戳版本
function throttle(func, delay) {
  let prev = Date.now();
  return function () {
    const context = this;
    const args = arguments;
    const now = Date.now();
    if (now - prev >= delay) {
      func.apply(context, args);
      prev = Date.now();
    }
  };
}
// 02) 定时器版本
fucntion throttle(func, delay){
  let timer = null;

  return funtion(){
    let context = this;
    let args    = arguments;
    if(!timer){
      timer = setTimeout(function(){
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  }
}
// 03) 时间戳定时器综合版本
function throttle(func, delay) {
  let timer = null;
  let startTime = Date.now();

  return function () {
    let curTime = Date.now();
    let remaining = delay - (curTime - startTime);
    const context = this;
    const args = arguments;

    clearTimeout(timer);
    if (remaining <= 0) {
      func.apply(context, args);
      startTime = Date.now();
    } else {
      timer = setTimeout(func, remaining);
    }
  };
}
常用的设计模式
遍历的方法
js 执行上下文
function fn(){
console.log(a) //undefined
var a = 1;
}
fn()
// 为什么打印出来是undefined 呢?
/**
概念 : 当代码运行时,会产生一个对应的执行环境,在这个环境中,所有变量会被事先提出来(变量提升),有的直接赋值,有的为默认值undefind,代码从上往下开始执行,就叫做执行上下文。
在javascipt 中,运行环境有三种,分别是:
1.全局环境: 代码首先进入的环境(在浏览器环境中 指向window)
2.函数环境 : 函数被调用时执行的环境(函数被调用时创建的)
3.eval函数(不常用)
特点:
1.单线程,在主线程上运行
2.同步执行,从上往下顺序执行
3.全局上下文之后一个,浏览器关闭时弹出栈
4.函数的执行上下文没有数目限制
5.函数每被调用一次,都会产生一个新的执行上下文环境(同一个函数被多次调用,都会创建一个新的上下文)
执行上下文的三个阶段
1.创建阶段(1)生成变量对象(2)建立作用域链(3)确定this 指向
2.执行阶段(1)变量赋值(2)函数引用(3)执行其他代码
3.销毁阶段 执行完毕出栈 等待回收被销毁
**/
作用域链

var name ='你好 前端'
function hello(){
  console.log(name)
}
原形链

概念 : 每个函数都有一个prototype 属性,每个实例对象都有一个proto属性 ,而这个属性指向函数的prototype. 当我们访问实例对象的属性或者方法时,会先从自身构造函数中查找,如果没有,就通过proto去原型中查找,这个查找的过程就是原型链(和作用域链有点像)

function Animal()/**定义动物-父类*/{
 this.age =10;
this.say = function(){
return 'hello tom'
}
}
function Cat()/**定义动物-子类*/{
this.name = 'tom'
}
Cat.prototype = new Animal()//通过原型继承动物类
const cat = new Cat()//实例化一个cat 对象
cat._proto_ === Cat.prototype;//打印返回true
console.log(cat.age)// 打印age 回先查找cat 在查找Animal
闭包

概念: 函数中嵌套函数,闭包是一个函数,能够访问其他函数作用域中的变量叫做闭包

//正常访问
var lan = 'zh'
function hello(){
  let name = 'jack'
}
console.log(name) // 明显访问不到,返回undefined 
//闭包
function  hello(){
let name ="jsom";
return function demo(){
  console.log(name) // jsom
}
}
继承有哪些方法?
function Person(){
this.name = '人类'
}
function Student(){}
Student.prototype = new Person()
let s = new Student()
console.log(s.name)//人类
function Person(){
this.name = name ;
}
function Doctor(){
Person.call(this,'jones');
this.age = 18
}
let d = new Doctor()
console.log(d.name) // jones
console.log(d.age) //18
function Person(name){
 this.name = name || '屈原'
 this.write = function(){
  console.log('床前明月光,疑是地上霜')
}
}
function Writer(){
 let instance = new Person()
 instance.name = name || '李白'
return instance
}
let w = new Writer()
console.log(w.name) // '李白'
w.write() //床前明月光,疑是地上霜
console.log(w instanceof Person) // true
console.log(w instanceof Writer) //false
function Person(name){
  this.name = name;
}
function Doctor(name){
  Person.call(this);
 this.name = name || 'Tom';
}
Doctor.prototype = new Person()
let d = new Doctor()
console.log(d.name) // Tom
console.log(d instanceof Person) // true
console.log(d instanceof Doctor) // true
class Person {
   name = ''
   constructor(name){
      this.name = name || '文';
}
}
class Doctor extends Person{
  constructor (name){
     super(name)
     this.name = name || '姜' 
 }
}
let d = new Doctor('法拉利')
console.log(d.name) // 法拉利
console.log(d instanceof Person) //true
console.log(d instanceof Doctor) // true
深/浅拷贝

理解 : JS数据类型分别为:基本数据类型和引用数据类型,基本数据类型保存的是值,引用类型保存的是引用地址(this指针). 浅拷贝公用一个引用地址,深拷贝会创建一个新的内存地址

  1. Object.assgin(目标对象,源对象),返回目标对象,key一样则被覆盖
const target = {a:1,b:2}
const source = {b:4,c:5}
const returntarget = Object.assgin(target,source);
console.log(target) //{a:1,b:4,c:5}
console.log(returntarget) // {a:1,b:4,c:5}
  1. 复制
 function copy(source,target={}){
            for(let key in source){
                target[key] = source[key]
            }
        }
        const source = {
            a:1,
            b:2
        }
        const target = {
            b:4,
            c:5
        }
       copy(source,target)
       console.log(target) //{b: 2, c: 5, a: 1}
  let source = {a:1,b:2,c:10}
       let traget = JSON.parse(JSON.stringify(source));
       console.log(traget)//{a:1,b:2,c:10}
       let source1 = {a:1,b:2,c:10,d:undefined}
       let traget1 = JSON.parse(JSON.stringify(source1));
       console.log(traget1) //{a:1,b:2,c:10}

2 . 手动实现深拷贝

 function _deepclone(obj){
            if(!obj && typeof obj !=='object'){
                throw Error('error arguments')
            }
            const targetObj = Array.isArray(obj) ? [] :{}
            console.log(targetObj)
            for(let key in obj){
                if(obj.hasOwnProperty(key)){
                    if(obj[key] && typeof obj[key]==='object'){
                        targetObj[key] = _deepclone(obj[key])
                    }else {
                    targetObj[key] = obj[key]
                 } 
                }
            }
            return targetObj
        }
console.log(_deepclone({})) // {}
console.log(_deepclone([])) //[]
2.1 手动实现深拷贝 理解版
function _deepcopy(target){
    let result ;
    //判断target 的数据类型
    if(typeof target ==='object'){
        if(Array.isArray(target)){
            result = [];
            for (let key in target){
                result.push(_deepcopy(target[key]))
            }
        }else if(target ===null ){
            result = null
        }else if (target.constructor===RegExp ){
            result = target
        }else{
            result ={}
            for(let key in target){
                result[key] = _deepcopy(target[key])
            }
        }
    }else {
        result = target
    }
    return result
}

let obj1 = {
    a: {
        c: /a/,
        d: undefined,
        b: null
    },
    b: function () {
        console.log(this.a)
    },
    c: [
        {
            a: 'c',
            b: /b/,
            c: undefined
        },
        'a',
        3
    ]
}
console.log(_deepcopy(obj1))
image.png
逻辑或(||) 逻辑与(&&)
// 逻辑或:有true返回true ,同为false 返回false ; 
// 逻辑与 : 有false返回false ,同为true 返回true;
异步函数的发展史
  function callback(){}
window.addEventlistener('click',callback);
function getData(){
  return new Promise((reslove,reject)=>{
  axios.get(url,{})
  .then((data)=>{})
  .catch(error=>{})
})
}
function* doSomething() {
  yield console.log(1);
  yield console.log(2);
  yield console.log(3);
  return true;
}
let d = doSomething(); // 返回的其实是一个迭代器
d.next(); // 1
d.next(); // 2
d.next(); // 3
d.next(); // { value: true, done: true }
    function delay(val,timer){
           return new Promise((res,rej)=>{
               setTimeout(()=>{
                   res(val)
               },timer)
           })
       }
       async function dosometing(){
           let val1 = await delay(1,2000)
           console.log(val1) // 2秒打印 1
           let val2 = await delay(2,1000)
           console.log(val2) // 3秒 打印2
       }
       dosometing() //总共用了3秒
如何解决跨域?生产环境和开发环境都要写出来

Vue相关

mvvm 框架是什么?


vue的优点是什么?

vue两大核心点

三大框架的优缺点(vue react angular)
渐进式框架的理解

单页面应用和多页面应用区别及优缺点?
SPA首屏加载慢的解决办法!

1.组件懒加载 babel-plugin-syntax-dynamic-import
2.不要把js打包到一个文件 配置webpack output 使用chunkname hash等
3.公共资源可以使用 CDN配置vue理由, 使用 import 方式引入组件, 指定输出js文件名
4.首页使用 loading 图, 不留白屏
5.使用骨架屏

组件通信

react 相关


什么是react ?
声明式编程?

   //声明式编程
        const number = [1,2,3,4,5]
        const dobulenumber = number.map(number=>number*2)
        console.log(dobulenumber) //[2, 4, 6, 8, 10]
        //命令式编程
        const number1 = [1,2,3,4,5]
        let dobulenumber2=[]
        for(let i =0 ;len = number1.length,i<len;i++){
            let targetnumber = number1[i]*2
            dobulenumber2.push(targetnumber)
        }
       console.log(dobulenumber2) //[2, 4, 6, 8, 10]
函数式编程?

什么是虚拟DOM?

什么是JSX?

函数/无状态/展示组件&类/有状态组件
组件生命周期钩子
redux
Hooks
vuex或者redux 刷新页面,怎么保留状态管理中的数据?
在浏览器输入url到页面渲染处理,中间发生了什么?
前端性能优化

前端安全

webpack相关
const path = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin') // html模板插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 打包时清除dist目录
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 抽离js中的css
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') // css压缩

const webpackPlugins = {
    entry: {
        main: path.resolve(__dirname, 'src', 'index.js')
    },
    output: {
        publicPath: './',
        path: path.resolve(__dirname, 'dist'),
        filename: './static/js/[name].[hash:10].js',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.css/,
                exclude: /node_modules/,
                use: [
                    { loader: 'style-loader' },
                    { loader: MiniCssExtractPlugin.loader, options: { publicPath: './static/css' } },
                    { loader: 'css-loader' },
                    { loader: 'postcss-loader' }
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
outputPath: 'static/images',
                            publicPath: '../images'
                            // esModule: false,
                        },
                    }
                ]
            },
            {
                test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
                loader: 'url-loader',
                options: {
                    // 把较小的图片转换成base64的字符串内嵌在生成的js文件里
                    limit: 1024 * 1, //10000
                    // 路径和生产环境下的不同,要与修改后的publickPath相结合
                    // name: 'images/[name].[ext]?[hash:7]',
                    name: '[name].[ext]',
                    publicPath: '../images', //会在打包后图片路径拼上该设置
                    outputPath: '/static/images'//输出的图片会生成并放在当前设置的文件夹下
                }
            }
        ]
    },
    resolve: {
        alias: {
            "@": path.resolve(__dirname)
        }
    },
    plugins: [
        new CleanWebpackPlugin({
            dry: false,
            cleanOnceBeforeBuildPatterns: [
                path.resolve(__dirname, 'dist'),
            ],
        }),

        new HtmlWebPackPlugin({
            title: 'App',
            minify: { // 压缩 html
                removeComments: true, // 移除注释
                collapseWhitespace: true, // 删除空白符和换行
                minifyCSS: true, // 压缩内敛 css
            },
            template: path.resolve(__dirname, 'public', 'index.html'), //模板
 filename: 'index.html',
            inject: true, // true || body script位于body底部
            favicon: path.resolve(__dirname, 'public', 'favicon.ico'),
            chunks: ['main'] // 多入口 对应 entry里的
        }),
        new MiniCssExtractPlugin({ filename: './static/css/[name].[hash:10].css' }),
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano'),
            // cssProcessorOptions: cssnanoOptions,
            cssProcessorPluginOptions: {
                preset: ['default', {
                    discardComments: {
                        removeAll: true,
                    },
                    normalizeUnicode: false
                }]
            },
            canPrint: true
        })
    ]
}
TCP 三次握手/四次挥手

http的发展史

https怎么加密传输, https中间人攻击

公众号后台开发简介

node.js相关

根据时间戳 转换成日期格式
function format(timer)/**new Date().getTime() 获取当天时间转换成时间戳*/ {
    if (!timer || typeof timer != "number") return "";
    const date = new Date(timer);
    return `${date.getMonth() + 1}/${date.getDate()}`;
  }
  console.log(format(1595411812239))//   7/22
时间戳之差 实现js 倒计时
  function NextTime(next, cb) {
    var t = null ;
    (function ft(){
        var dif = (next.getTime() - (new Date()).getTime()) / 1000; //秒  new Date()).getTime() 获取当前时间时间戳
        if(dif > 0){
            t = setTimeout(ft, 1000);
            if(cb)
                cb(Math.floor(dif/60/60/24),Math.floor(dif/60/60%24),  Math.floor(dif/ 60 % 60), Math.floor(dif % 60));
        } else {
            clearTimeout(t);
        }
    })();
    return function(){
        clearTimeout(t);
    };
}
function lpad(num, n) {
    var len = num.toString().length;
    while(len < n) {
        num = "0" + num;
        len++;
    }
    return num;
}
var next = new Date('2020/07/27 12:00:00'); // 过期时间
new NextTime(next, function(day,hour, minute, second){
  console.log(lpad(day, 1)+'天'+lpad(hour, 2) + ':' + lpad(minute, 2) + ':' + lpad(second, 2))
});
根据时间戳 转换成年月日时分秒
function formatDate(timer) {
    const date = new Date(timer)
    let year = date.getFullYear(),
        month = date.getMonth() + 1,
        day = date.getDate(),
        hours = date.getHours(),
        minutes = date.getMinutes(),
        seconds = date.getSeconds()

    return `${year}-${morethanTen(month)}-${morethanTen(day)} ${morethanTen(hours)}:${morethanTen(minutes)}:${morethanTen(seconds)}`
}

function morethanTen(params) {
    return params < 10 ? '0' + params : params
}
console.log(formatDate(1545230489000))//2018-12-19 22:41:29
封装判断javascript类型的函数
  function getType(value){
            if(typeof value ===null ){
                return value+''
            }
            if(typeof value==='object'){
                let valClass = Object.prototype.toString.call(value),
                type = type.split(' ')[1].split('');
                type.pop();
                return type.join('').toLowerCase()
            }else{
                return typeof value
            }
        }
        let a1='string'
       console.log(getType(a1)) // string

[about js 掘金]:https://juejin.im/post/5f1412ad6fb9a07e944eff6b?utm_source=gold_browser_extension#heading-22

上一篇下一篇

猜你喜欢

热点阅读