本文已参与「新人创作礼」活动,一起开启掘金创作之路
// 问:下面的console.log输出什么?
let arrowFunction = () => {};
console.log(new arrowFunction());
几年前当我第一次被问到这个问题的时候,我意思到哪里不对劲,但是时间紧迫,面试官追问我输出什么,是输出对象吗?很犹豫。。。那就是吧。一个小时以后当面试一结束。。思考片刻我突然意识我翻车了。。。
从头来想这个问题。首先 new一个对象做什么?
- 创建一个全新的对象
- 这个新对象会被执行原型连接
- 这个新对象会绑定到函数调用的
this - 如果函数没有返回其它对象,那么
new表达式种的函数调用会自动返回这个新对象
我们可以看到 new 的操作中就有 this 的绑定,我们在来看看代码。
这里在实现一个new 方法,更好的理解
function myNew(consturctor,...argas){
//创建一个全新的对象,这个新对象会被执行原型连接,及继承 constructor 的原型
const obj = object.create(constructor.protype);
//这个新对象会绑定到函数调用的 `this`,及将 obj 作为 this ,执行 constructor ,传入参数
constructor.apply(obj.args);
//返回 obj
return obj
}
那么在来说下 this,通常情况下this 要在执行时确认,定义时无法确认.
- 作为构造函数执行
- 作为对象属性执行
- 作为普通函数执行
- call apply bind 可以改变
this指向
let a = {
name:'A',
fn: function () {
console.log(this)
}
}
console.log(a.fn())
console.log(a.fn.call({name:'B'}))
let fn1= a.fn;
console.log(fn1())
总结:通常情况下,函数的this 要在执行时确认,定义时无法确认,也就是谁引用它,this就指向谁
但是当我们将函数变成箭头函数的时候情况发生了变化。
let a = {
name:'A',
fn: () => {
console.log(this)
}
}
console.log(a.fn())
console.log(a.fn.call({name:'B'}))
let fn1= a.fn;
console.log(fn1())
对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,call apply bind 不可以改变 this指向。相比之下,普通函数的this指向是可变的。同时箭头函数不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
总结:
箭头函数存在着许多不适用的场景
- 不适合当作构造函数,也就是说,不可以对箭头函数使用
new命令,否则会抛出一个错误。 - 不适合作为对象的方法
- 不适合作为扩展对象原型
- 不适合动态上下文中的回调函数
- 因Vue组件是一个对象,所以不适合作为Vue生命周期和方法
PS:
Object.create 可以指定原型,创建一个空对象。
{} 就相当于 Object.create(Object.prototype) ,即根据 Object 原型的空对象。