这道题在前端面试中出现的概率应该可以排在前几位了, 就算是入门前端都能回答上来一二, 但是回答的是否有逻辑有条理有深度呢?
本文从以下几个问题进行讲述
- 说一下js中的this
- 说一下new做了什么事
- 说一下apply,call方法做了什么事
- 说一下箭头函数和普通函数的区别
js中的this
面试中遇到这个问题时, 最好不要想一点说一点, 要做出自己的总结
js中的this主要是指在函数中this的指向问题
- 如果函数是作为构造函数,使用new方法生成的对象, 那么这个构造函数中的this被绑定到了实例对象上
- 如果函数调用时被apply,call, bind方法强绑定了this, this就指向强绑定的对象(apply等函数的第一个参数)
- 普通函数的this指向该函数的调用对象
- 箭头函数没有自己的this, 只能从作用域链的上一层获取this; 所以箭头函数的this是可变的
上面总结了四种this的指向问题, 他们也是有优先级的.
new -> apply等方法 -> 普通函数 -> 箭头函数
所以在被问到这个问题时, 可以依次判断
那么有了上面这四种分类, 就可以引申出下面几个问题了
说一下new做了什么事
function Func(){
}
let func= new Func();
如上, new 操作符做了什么?
new 构造函数的时候主要做了四件事
1 创建一个空对象
let obj = new Object();
2 链接到构造函数的原型
obj.__proto__ = Func.prototype;
3 绑定this值(让Func中的this指向obj,并执行Func的函数体。
let result = Func.call(obj)
4 返回新对象
if (typeof(result) == "object"){
func=result;
}
else{
func=obj;
}
所以实现代码是
function _new(fn, ...arg) {
const obj = {};
obj.__proto__ = fn.prototype;
fn.apply(obj, arg)
return Object.prototype.toString.call(obj) == '[object Object]'? obj : {}
}
说一下apply,call方法做了什么事
apply和call是调用函数, 将函数中的this强绑定到apply,call的第一个参数对象上
手动实现一个myApply
Function.prototype.myApply = function (context = window, args) {
context.fn = this
let result = context.fn(...args)
delete context.fn
return result
}
说一下箭头函数和普通函数的区别
箭头函数和普通函数的区别不只上面说的this指向不同这一个区别哦, 下面总结一下
- 箭头函数this的来自上一层作用域的this, 和调用位置无关
- 箭头函数不能使用apply,call进行强绑定this
- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的arguments,可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表
- 箭头函数没有原型prototype
|