es6里面的箭头函数很好用,不过也有些坑,如果你觉得它完全取代了function关键字,那就是大错特错了。
构造函数
箭头函数无法跟function一样使用new:
var Foo = ()=>{
console.log(this)
}
var Foo2 = function(){
console.log(this)
}
console.log(Foo.prototype)//undefined
console.log(Foo.constructor)//[Function: Function]
console.log(Foo2.prototype)//Foo2{}
console.log(Foo2.constructor)//[Function: Function]
var f2 = new Foo2()
console.log(f2.__proto__)//Foo2 {}
var f = new Foo()//报错,因为没有prototype
我们再来回顾下new的执行过程:
1、创建一个空对象
2、将该对象的__proto__指向到构造函数(比如Fn)的原型prototype
3、修改构造函数Fn的上下文到空对象
4、返回空对象(其实就是this)
//new的执行过程
function myNew(Fn){
let mythis = {} //定义一个空的object
mythis.__proto__ = Fn.prototype
let args = [].slice.call(arguments,1)
Fn.apply(mythis,args)
return mythis //其实这个就是this
}
function Person(name){
this.name = name
}
let o = myNew(Person,'jack')
console.log(o)
箭头函数不满足第二步,也就是没有原型prototype,因此无法使用new关键字。
this
虽然箭头函数可以帮我们绑定this上下文作用域,但如果不清楚内部原理滥用的话,仍然会遇到大坑。
window.color = 'blue'
let color = 'green'
let obj = {
color: 'yellow',
getColor: () => {
console.log(this)//指向了window
console.log(this.color)
}
}
obj.getColor()//blue
这段代码相当具有迷惑性,getColor的this居然指向了window!为啥呢?
这是因为:箭头函数绑定的上下文是定义时的this,而不是执行时的this。
箭头函数无法使用new,当然也就无法返回this,因此对象内部的箭头函数若有this,那它只能指向对象的外面作用域window。
call和apply
正常的function是可以使用call或apply改变执行作用域的,箭头函数行吗?
window.color = 'blue'
let color = 'green'
let obj = {
color: 'yellow',
}
let getColor = () => {
console.log(this)//指向了window
console.log(this.color)
}
getColor.call(obj)//blue
这个就不需解释了吧~~
网友评论