面试题问答
几种常见for循环的区别与不足之处 (for,for of,for in ,foreach)
区别通过作用体现
foreach
作用:用于调用数组的每个元素,并将元素传递给回调函数,回调函数的三个分别是value,index,arr(数组本身)
不足: 不能同时遍历多个集合,在遍历的时候无法修改和删除集合数据,方法不能使用break,continue语句跳出循环,或者使用return从函数体返回,对于空数组不会执行回调函数,不可以遍历对象
for of
作用: 遍历可迭代的对象(部署了Symbol.iterator),包括 Array,Map,Set,String,arguments等等,可以为一个数据结构部署iterator或者generator来实现for..of...循环
不足:只能遍历可迭代的对象,不能遍历原生对象
for in
作用:用于循环遍历数组或对象属性
不足: 某些情况下,会出现随机顺序的遍历,key的值是string类型,增加了转换过程,增大开销
for
作用: 实现基本的循环语句
不足: 不可以遍历对象
什么是深拷贝,什么是浅拷贝?
-
浅拷贝:就是拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会是使得所有对象的值被修改,因为它们公用一条数据,或者说对于一个深层次的对象只拷贝的第一层
-
深拷贝: 不会拷贝引用类型的引用,拷贝的是引用类型的值,形成一个新的引用类型。就是说拷贝到的最低的一个层级
generator与async/await有什么关系
async/await是generator的一个语法糖,并且内部实现了自动执行generator
function myAwait(genF) {
return new Promise(function(resolve, reject) {
const gen = genF();
function step(nextF) {
let next;
try {
next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
step(function() { return gen.next(undefined); });
});
}
如何实现generator的自动调用
-
通过
Thunk
函数 执行返回回调函数,递归执行next -
使用 co 模块,将异步操作包装成 Thunk 函数或者promise函数,递归执行next
new一个对象做了什么(讲述一下new的原理)
- 创建一个空对象,作为将要返回的对象实例。
- 将这个空对象的原型,指向构造函数的prototype属性。
- 将这个空对象赋值给函数内部的this关键字。
- 开始执行构造函数内部的代码。
什么是事件委托
事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件委托
事件的回调函数 e.target与e.currentTarget分别指向谁
e.target
指向触发事件的源组件
e.currentTarget
指向 事件绑定的当前组件
-
如果绑定的事件所在组件没有子元素,则用e.target===e.currentTarget一样;
-
当用e.currentTarget时,不管点击父元素所在区域还是子元素(当前事件),都正确执行,
若用e.target时,点击父元素所在区域无错,点击子元素区域,执行报错-