注意:console.dir()可以显示一个对象所有的属性和方法。
1.prototype和__proto__区别
prototype可以给函数和对下添加可共享的方法。
__proto__查找某函数或对象的原型链方式, constructor包含了一个指针,指回原构造函数。
可以理解为prototype是类中的属性,而__proto__是实例的属性。同样Person在这里是一个对象,拥有prototype和__proto__属性,函数与类相同
function Person(){
this.name = '展示'
}
console.dir(Person)
console.log(Person.prototype.constructor === Person) //true
let zhangsan = new Person()
console.log(zhangsan.__proto__ === Person.prototype) //true
2.call和bind和apply区别
都是改变this指向,它们的区别主要是在于方法的实现形式和参数传递上的不同
let obj = {
myname: '张三'
}
function fn(...args){
console.log(this, args)
}
// fn.call(obj, 1, 2)
// fn.apply(obj, [1 ,2]) //apply接触的是数组
// fn.bind(obj)(1 ,2) //改变函数this指向
3.如何终端ajax请求
xhr有一中abort方法可以中断ajax请求
let xhr = new XMLHttpRequest()
document.querySelector('.a').onclick = function(){
console.log('请求停止')
xhr.abort()
}
4.v-for与v-if谁的优先级更高
1.v-for要高于v-if
2.如果v-for和v-if在标签中同时存在,在vue的源码中会先执行v-for后执行v-if,不管v-if是否为真,v-for循环都会执行,造成不必要的性能浪费。
3.解决方式将v-if和v-for分离,v-for外嵌套一个template,先执行v-if避免v-for性能浪费
4.如果条件出现在循环内可以使用watch函数进行过滤,过滤掉不显示的项
5.vue中data为什么以函数形式存在
因为vue中有多个实例,data以对象传入会导致data数据公用,造成data污染,源码中initdata会作为工厂函数返回全新的data对象,避免了环境污染,而根路径因为只有一个,没有污染的情况.
6.vue中key的作用
1.key的作用只要为了高效虚拟dom,vue在patch里通过key判断两个节点是否是同一个,避免重复变更不同元素,使得patch过程更加高效,提高性能。
2.若不设置可能引发一些隐蔽的bug
3.vue在使用相同的标签名元素的过渡切换,会使用key属性,目的为了让vue可以区分他们,否则只会替换属性而不促发过渡
不加入key值引发不同元素重复变更,容易出错。
// 首次循环patch A A B C D E
A B F C D E
// 第2次循环patch B B C D E
B F C D E
// 第3次循环patch E C D E
F C D E
// 第4次循环patch D C D
F C D
// 第5次循环patch C C
F C
// oldCh全部处理结束,newCh中剩下的F,创建F并插入到C前面
7.vue中的diff算法
总结:
1.diff算法是虚拟dom技术的必要产物,通过新旧虚拟dom做对比,将变化的地方更新在真实dom上,也需要diff高效的执行对比过程,降低时间复杂度为o(n)
2.vue2.0中降低watcher粒度,每个组件只有一个watcher与之对应,只有引入diff才能找到变化的地方。
3.vue中diff执行是组件实例执行更新函数时,他会对比上一次渲染结果oldVnode和新的渲染结果newVnode,此过程为patch
4.diff过程整体遵循深度优先、同层比较,两个节点之间互相比较,借助key可以精确找到相同节点。