2018-10-30
1、浅拷贝和深拷贝的区别,实现。
区别:
浅拷贝:只拷贝指向对象的指针;
深拷贝:拷贝一个对象的值,重新生成一个对象
实现:
浅拷贝:直接赋值
深拷贝:
function deepCopy(obj){ if(!(obj instanceof Object)) return; var res; if(obj instanceof Array) res = []; else res = {}; for(key in obj){ if(!(obj[key] instanceof Object)) res[key] = obj[key]; else res[key] = deepCopy(obj[key]); } return res; }
2、ES6中的箭头函数。
作用:
- 与变量解构结合使用
- 使表达更加简洁
- 简化回调函数
注意点:
- 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
- 不可以当作构造函数,即不可以使用new命令,否则会抛出错误。
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。
- 不可以使用yield命令,因此箭头函数不能用作Generator函数。
3、理解闭包。
推荐一篇博客:前端基础进阶(四):详细图解作用域链与闭包
闭包更确切的说是一项技术或者一个特性,函数作用域中的变量在函数执行完成只有就会被垃圾回收。正常情况下无法访问函数作用域中的变量,而通过闭包可以实现,即通过在函数作用域中创建内部函数,使得函数执行完成后变量不会被回收。
应用场景:
- 柯里化
- 模块化
算法题:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
function minNumberInRotateArray(rotateArray)
{
// write code here
if(rotateArray.length===0) return 0;
if(Array.from(new Set(rotateArray)).length === 1) return rotateArray[0];
for(let i=0; i<rotateArray.length-1; i++){
if(rotateArray[i]>rotateArray[i+1]){
return rotateArray[i+1];
}
}
}
2018-10-31
4、理解this。
this的指向,是在函数被调用的时候确定的,也就是执行上下文(execution context)被创建时确定的。
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。如果函数独立调用,那么该函数内部的this,则指向undefined。但是在非严格模式中,当this指向undefined时,它会被自动指向全局对象。匿名函数的this对象通常指向window。
推荐一篇博文:前端基础进阶(五):全方位解读this
5、实现一个bind函数。
定义:bind()是ES5中定义的函数的方法。
作用:创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
典型例子:
var color = 'red'; var o = { color : 'blue' } function getColor(){ return this.color; } getColor(); // "red" var newGetColor = getColor.bind(o); newGetColor(); // "blue"
借助闭包和apply方法,封装一个bind方法。
function bind(fn, o){ return function(){ return fn.apply(o, arguments); } }
6、通过new操作符调用构造函数的实际过程。
- 创建一个新的对象
- 将构造函数的this指向这个新对象
- 为这个对象添加属性,方法等
- 返回新对象
7、对于作用域链的理解。
作用域链是指向变量对象的指针列表,每个变量对象关联着一个执行上下文,标识符的解析沿着作用域链从下到上层级搜索,保证对执行上下文有权访问的变量和函数的有序访问。
2018-11-1
8、在给事件绑定回调函数的时候,event和e的区别是什么。
IE和Chrome中的事件对象是作为全局对象(window.event)存在的,Firefox中则是作为句柄(handler)的第一个参数传入内的。
所以常见获取事件的方法是:
// Dom0级事件处理 ele.onEventName = handler; // Dom2级事件处理 // 与上者实现相同的效果 // 第三个参数默认为false,冒泡阶段调用handler ele.addEventListener('eventName', handler, false); function handler(e){ var evt = window.event || e; //等价形式如下 //var evt = window.event || arguments[0]; }
9、函数防抖是什么,怎么实现。
详见笔者博文:JavaScript,冲鸭系列——函数防抖
2018-11-2
10、事件循环(event loop)机制。
JavaScript是单线程的,这个线程拥有唯一的一个事件循环,但是可以拥有多个异步任务队列,任务队列用来存放相应的回调函数或者事件处理方法。如下图任务队列分为:macro和micro两种,不同源类型的任务进入不同的任务队列。
事件循环的顺序决定了代码的执行顺序。从script开始,按照macro——micro的顺序交替执行,且无论是什么类型的任务,都需要借用函数调用栈来完成。