一、vue的各个生命周期适合做哪些操作
-
beforeCreate(vue实例创建前):这个阶段实例的data、mothods是读不到的
-
created(vue实例创建后):这个阶段已经完成了数据观测(data observer),属性和方法的计算,watch/event事件的回调。
-
beforeMount:在挂载开始之前调用此函数,相关的render()方法首次被调用。
-
mounted:el选项的DOM节点被新创建的vm.$el替换,并挂载到实例上面之后调用此生命周期函数。此时实例的数据在DOM节点上进行渲染。
-
beforeUpdate:数据更新时调用,但不进行DOM重新渲染(在数据更新时而DOM没渲染前可以在这个生命周期函数里进行状态处理)
-
updated:这个状态下数据更新并且DOM重新渲染,当这个生命周期函数被调用时,组件DOM已经更新。(此时可以执行依赖DOM的操作)
-
beforeDestroy:实例销毁之前被调用
-
Destroyed(Vue实例销毁后调用):调用后,Vue实例指示的所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
Vue生命周期在真实场景下的业务应用:
created():进行ajax请求异步数据的获取、初始化数据 Mounted():挂在元素内DOM节点的获取 nextTick():针对单一事件更新数据后立即操作DOM updated():任何数据的更新,如果要做统一的业务逻辑处理 watch():监听具体数据变化,并作相应处理
二、闭包的特点以及好处(用法)
-
什么是闭包:函数嵌套函数,内部函数可以引用外部函数的变量/参数
-
好处:可以使一个变量长期驻扎在内存中;避免全局变量的污染(代码模块化);私有成员的存在(外部只能访问,不能修改)
-
用法:代码模块化,避免全局污染;循环中找到对应元素的索引(循环在加载js时立即执行,var定义的循环变量自动变化到边界值,绑定的事件和索引不匹配,用闭包和函数立即调用,分别绑定事件和索引值)
- 要注意的问题:内存泄漏(不再使用的内存没有及时释放)
三、let,const和var之间的区别;
-
var关键字用于声明局部变量,在ES6之前,只存在函数作用域和全局作用域,因此var声明的变量可能存在变量提升问题(其实就是由于缺少块级作用域,导致var声明的变量作用域向上提升,比如for循环中定义的循环变量在循环外部也可以访问并修改)
-
let 关键字增加了块级作用域,let声明的变量仅在let所在的作用域内有效,在块级作用域以外无法被访问(用babel把es6=>es5 :let=>闭包+函数的立即调用)
-
const关键字用于定义常量,用const声明的变量不能再被修改(但实际上const锁定的只是声明的变量对应的内存地址,而地址内的数据依然可以改变,简单来说,不能用等号重新赋值;比如用const 声明的数组不能重新赋值,但依然可以通过push等方法修改数组内容)
四、ES6常用的一些数据结构和方法,Set和Map,Iterator 和 for...of ,foreach循环
- 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)
-
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) -
Iterator(遍历器)是一种接口,它为不同的数据结构提供统一的访问机制,任何部署了Iterator接口(通过设置数据结构的Symbol.iterator属性,即数据结构本身的遍历器生成函数)的数据结构,都认为是Iterable的(可以完成遍历操作,即依次处理该数据结构的所有成员)
遍历过程:
(1)创建遍历指针对象指向数据结构的起始位置(闭包,返回一个具有next()方法的对象) (2)不断调用指针对象的next(),指向下一个成员 (3)直到数据结构的结束为止(undefined),遍历结束调用Iterator接口的场合:
(1)解构赋值[] (2)扩展运算符 (3)for...of、Array.from()、Map()/Set()、Promise.all()、... -
for...of循环:ES6借鉴其他语言引入了一种遍历所有数据结构统一方法(只要部署了Iterator接口,就可以使用for...of循环进行遍历),其内部调用的是数据结构的Symbol.iterator方法
五、JavaScript的事件循环机制(event loop)
-
js是单线程异步执行
同步任务:在主线程上排队执行的任务,只有前一个执行完毕,才能执行后一个 异步任务:不进入主线程,二是“任务队列”的任务,只有“任务队列”通知主线程,某个异步任务可以执行,这个任务才会进入主线程执行 -
任务队列
宏任务:包括整体代码script,setTimeout,setInterval 宏任务队列可以有多个 微任务:new Promise.then(回调),process.nextTick 微任务队列只有一个
上一个宏任务完成后,如果有微任务队列则执行微任务队列的全部任务
当一个宏任务队列的宏任务全部完成后,会查看当前微任务队列是否有微任务,完成微任务队列之后,再执行下一个宏任务队列
-
事件循环(本质是任务队列循环)
(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指针指向正确,为什么?
-
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> -
显式函数绑定call(),apply(),bind();
-
ES5函数和ES6箭头函数语法:
ES5显式声明函数名:function 函数名(){}
ES5匿名函数表达式:var f = function(){}
箭头函数:var f=()=>{}
-
箭头函数的独特性:
(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) 任何DOM对象都可以使用该方法, (3)实现了Js和html的分离,提高可读性,有利于代码维护 (4)可以实现对冒泡/捕获的控制 -
参数:
event:事件的类型(如:click、mousedown) function:event发生时执行的函数/方法 useCapture(可选):false(冒泡:由内向外响应处理、默认值)/true(捕获:由外向内响应处理)
-
补充:默认先捕获后冒泡,如何实现先冒泡后捕获?
给对应元素同一事件添加两个addEventListen,分别设置第三个参数false(在前)、true(在后) -
补充:如何阻止事件冒泡/捕获
在绑定的事件处理函数中调用event.stopPropagation()方法。其中,event绑定的是引起事件处理函数响应的事件对象。
十二、简单的算法题: 遍历输出一棵树中的所有对象的name
- 主要考察了遍历和函数的递归调用,结合引用数据类型的深拷贝方法可以进行同类型算法题的总结归纳