滴滴一面总结

264 阅读10分钟

一、vue的各个生命周期适合做哪些操作

  1. beforeCreate(vue实例创建前):这个阶段实例的data、mothods是读不到的

  2. created(vue实例创建后):这个阶段已经完成了数据观测(data observer),属性和方法的计算,watch/event事件的回调。

  3. beforeMount:在挂载开始之前调用此函数,相关的render()方法首次被调用。

  4. mounted:el选项的DOM节点被新创建的vm.$el替换,并挂载到实例上面之后调用此生命周期函数。此时实例的数据在DOM节点上进行渲染。

  5. beforeUpdate:数据更新时调用,但不进行DOM重新渲染(在数据更新时而DOM没渲染前可以在这个生命周期函数里进行状态处理)

  6. updated:这个状态下数据更新并且DOM重新渲染,当这个生命周期函数被调用时,组件DOM已经更新。(此时可以执行依赖DOM的操作)

  7. beforeDestroy:实例销毁之前被调用

  8. Destroyed(Vue实例销毁后调用):调用后,Vue实例指示的所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    Vue生命周期在真实场景下的业务应用:

     created():进行ajax请求异步数据的获取、初始化数据
     Mounted():挂在元素内DOM节点的获取
     nextTick():针对单一事件更新数据后立即操作DOM
     updated():任何数据的更新,如果要做统一的业务逻辑处理
     watch():监听具体数据变化,并作相应处理
    

二、闭包的特点以及好处(用法)

  1. 什么是闭包:函数嵌套函数,内部函数可以引用外部函数的变量/参数

  2. 好处:可以使一个变量长期驻扎在内存中;避免全局变量的污染(代码模块化);私有成员的存在(外部只能访问,不能修改)

  3. 用法:代码模块化,避免全局污染;循环中找到对应元素的索引(循环在加载js时立即执行,var定义的循环变量自动变化到边界值,绑定的事件和索引不匹配,用闭包和函数立即调用,分别绑定事件和索引值)

  • 要注意的问题:内存泄漏(不再使用的内存没有及时释放)

三、let,const和var之间的区别;

  1. var关键字用于声明局部变量,在ES6之前,只存在函数作用域和全局作用域,因此var声明的变量可能存在变量提升问题(其实就是由于缺少块级作用域,导致var声明的变量作用域向上提升,比如for循环中定义的循环变量在循环外部也可以访问并修改)

  2. let 关键字增加了块级作用域,let声明的变量仅在let所在的作用域内有效,在块级作用域以外无法被访问(用babel把es6=>es5 :let=>闭包+函数的立即调用)

  3. const关键字用于定义常量,用const声明的变量不能再被修改(但实际上const锁定的只是声明的变量对应的内存地址,而地址内的数据依然可以改变,简单来说,不能用等号重新赋值;比如用const 声明的数组不能重新赋值,但依然可以通过push等方法修改数组内容)

四、ES6常用的一些数据结构和方法,Set和Map,Iterator 和 for...of ,foreach循环

  1. Set结构是一个去重数组结构,用Set()构造函数来生成Set结构,可以接受一个数组(或者其他具有iterable接口的数据结构)作为参数,向Set结构加入值时,不会发生类型转换
  • 常用于:

    (1) 数组去重:[...new Set(array)]

    (2) 字符串去重:[...new Set(str)].join(‘’)

      Set实例的2个属性:
      Set.prototype.constructor:构造函数,默认是Set();
      Set.prototype.size:返回Set实例的成员总数;
    
      Set实例的4个操作方法:
      Set.prototype.add(value):添加某个值,返回Set结构
      Set.prototype.delete(value):删除某个值,返回true/false(是否成功)
      Set.prototype.has(value):返回true/false(value是否是Set实例的成员)
      Set.prototype.clear():清空所有成员,没有返回值
    
      Set实例的4个遍历方法:
      > keys()返回键名、values()返回键值、entries()返回键值对
          事实上,Set结构key=value,即keys()和values()方法的返回值一样,而entries()返回多个数组([key,value],key=value)
      > foreach(function)
    
  1. Map结构类似对象,也是一种键值对集合(hash结构);优点在于:相比Object结构,Map结构的键不局限与字符串,各种数据类型(包括对象)都可以作为键,即:Object =>“字符串--值”,Map => “值--值”。

    Map实例属性:

     Map.prototype.size()返回Map实例的成员总数;
    

    Map实例的5个操作方法:

     Map.prototype.set(key,value)设置键名key对应键值为value,返回整个Map实例;可以采用链式写法(连缀语法);
     Map.prototype.get(key):读取key对应的键值,找不到返回undefined;
     Map.prototype.has(key):返回true/false(key是否是Map实例的键);
     Map.prototype.delete(key):删除键key,返回true/fals;
     Map.prototype.clear():清除全部成员,没有返回值
    

    Map实例的4个遍历方法:

     keys()返回所有键名
     values()返回全部键值
     entries()返回全部键值对
     foreach(function)
    
  2. Iterator(遍历器)是一种接口,它为不同的数据结构提供统一的访问机制,任何部署了Iterator接口(通过设置数据结构的Symbol.iterator属性,即数据结构本身的遍历器生成函数)的数据结构,都认为是Iterable的(可以完成遍历操作,即依次处理该数据结构的所有成员)

    遍历过程:

     (1)创建遍历指针对象指向数据结构的起始位置(闭包,返回一个具有next()方法的对象)
     
     (2)不断调用指针对象的next(),指向下一个成员
     
     (3)直到数据结构的结束为止(undefined),遍历结束
    

    调用Iterator接口的场合:

     (1)解构赋值[]
     (2)扩展运算符
     (3)for...of、Array.from()、Map()/Set()、Promise.all()、...
    
  3. for...of循环:ES6借鉴其他语言引入了一种遍历所有数据结构统一方法(只要部署了Iterator接口,就可以使用for...of循环进行遍历),其内部调用的是数据结构的Symbol.iterator方法

五、JavaScript的事件循环机制(event loop)

  1. js是单线程异步执行

     同步任务:在主线程上排队执行的任务,只有前一个执行完毕,才能执行后一个
     异步任务:不进入主线程,二是“任务队列”的任务,只有“任务队列”通知主线程,某个异步任务可以执行,这个任务才会进入主线程执行
    
  2. 任务队列

     宏任务:包括整体代码script,setTimeout,setInterval
         宏任务队列可以有多个
     微任务:new Promise.then(回调),process.nextTick
         微任务队列只有一个
    

上一个宏任务完成后,如果有微任务队列则执行微任务队列的全部任务

当一个宏任务队列的宏任务全部完成后,会查看当前微任务队列是否有微任务,完成微任务队列之后,再执行下一个宏任务队列

  1. 事件循环(本质是任务队列循环)

     (1)所有同步队列都在主线程上执行,形成一个执行栈;
     (2)在主线程之外还有任务队列,有运行结果的异步任务进入任务队列;
     (3)当主线程的同步任务全部执行完毕,系统才开始读取任务队列,被读取的异步任务结束等待,进入执行栈执行;
     (4)随着主线程的运行,系统不断重复第(3)步。
    

六、JavaScript数据类型

undefined,null,boolean,number,string;object

typeof操作符:

typeof				return

未定义				undefined
数字				number
字符(串)			string
true/false			boolean
对象/null/数组		        object
函数				function 		

七、JavaScript的箭头函数的this指针指向正确,为什么?

  1. this关键字(自引用指针):指的是它所属的对象。

    方法中,指代它的拥有者对象:

     Person.prototype.report=function(){console.log(this.name)}
     //返回实例的name
    
     setTimeout(function,time)
     //系统方法—定时器,属于全局对象window,
    
    • 单独使用,指代全局对象[object Window]

    函数中,指代该函数的拥有者(严格模式下undefined、箭头函数没有this)

    事件中,指代接收事件的元素:

     <p onclick=“this.style.display=‘none’”>点击来删除我</p>
    
  2. 显式函数绑定call(),apply(),bind();

  3. ES5函数和ES6箭头函数语法:

    ES5显式声明函数名:function 函数名(){}

    ES5匿名函数表达式:var f = function(){}

    箭头函数:var f=()=>{}

  4. 箭头函数的独特性:

    (1)箭头函数不同于一般函数,它的this是固定的,总是指向定义时所在的对象,而不是使用时所在的对象。比如:定时器延时调用方法setTimeout(function,time)属于全局对象;在对象中person调用时,如果用ES5语法定义function,那么function绑定执行时setTimeout所属的window对象作为this的指向;如果箭头函数定义function,则function绑定function所属的person实例对象作为this的指向。

    (2)ES6箭头函数转ES5:

     //ES6
     function Foo(name){
         this.name = name
         say:setTimeout(()=>{
             console.log(this)
         })
     }
     var foo = new Foo(‘Tom’)
     
     //ES5
     function Foo(name){
         this.name = name
         var _this = this
         say:setTimeout(function(){
             console.log(_this)
         })
     }
    
    • 从(2)中可以看出箭头函数this指向的固定化是因为箭头函数并没有this,从而导致内部函数引用外部代码的this作为自己的this。也正是因为箭头函数没有自己的this,所以箭头函数不能作为构造函数。

八、实现水平垂直居中的方法有哪些

已知宽高:

(1)利用margin写死
(2)子元素绝对定位(50%)& margin(-50%)
(3)子元素绝对定位(0)& margin:auto

未知宽高:

(1)transform:translate(-50%,-50%)相当于margin-left:-50%;margin-top:50%;
(2)父元素设置弹性盒布局:
    display:flex;//弹性盒布局
    justify-content:center;//主轴(相当于默认主轴方向row时,水平居中)
    align-item:center;//交叉轴居中(相当于默认时的垂直居中)
(3)父元素设置table-cell
    display:table-cell;
    text-align:center;
    vertical-align:center;

九、== 和 === 的区别,1==true,""==false why?

  • == 判断数值是否相等

  • === 判断数值和数据类型是否都相等

  • 1 == true ,“”==false 是因为在比较时做了隐式类型转换,转化成功且值相等返回true,转换失败或值不相等返回false 类似的,还有isNaN(value)在判断时会先尝试把value隐式转换成number类型,转换成功(可以转换number类型)返回false,失败(不能转换成number类型)返回true

十、CSS选择器优先级/权重值

属性后添加!important 最高(一般不推荐使用)
内联样式(1000)
id选择器(100)
class选择器(10)
标签选择器(1)
通配符*、子代>、相邻+(0)

十一、DOM对象的事件监听器:addEventListener(event,function,useCapture)

  1. 用于为元素添加事件处理操作;

  2. 好处:

     (1) 能为同一个元素添加多个事件处理操作,而不会相互覆盖
     (2) 任何DOM对象都可以使用该方法,
     (3)实现了Js和html的分离,提高可读性,有利于代码维护
     (4)可以实现对冒泡/捕获的控制
    
  3. 参数:

     event:事件的类型(如:click、mousedown)
     function:event发生时执行的函数/方法
     useCapture(可选):false(冒泡:由内向外响应处理、默认值)/true(捕获:由外向内响应处理)
    
  • 补充:默认先捕获后冒泡,如何实现先冒泡后捕获?

      给对应元素同一事件添加两个addEventListen,分别设置第三个参数false(在前)、true(在后)
    
  • 补充:如何阻止事件冒泡/捕获

      在绑定的事件处理函数中调用event.stopPropagation()方法。其中,event绑定的是引起事件处理函数响应的事件对象。
    

十二、简单的算法题: 遍历输出一棵树中的所有对象的name

  • 主要考察了遍历和函数的递归调用,结合引用数据类型的深拷贝方法可以进行同类型算法题的总结归纳