之前總結了this的一些罕見綁定狀況(【前端工程師手冊】JavaScript之this的筆記),然則另有一些沒有說到,本日繼承進修一下。
es6箭頭函數
先說結論:箭頭函數沒有本身的this,它是依據外層(函數或許全局,背面會說到箭頭函數作為某個對象的要領時的狀況)作用域來決議this,箭頭函數能夠像 bind(..) 一樣確保函數的 this 被綁定到指定對象,也就是說它在運轉中不會喪失this,它的this是在聲明箭頭函數時就決議了。
一個例子
var name = 'out'
function test(){
this.name = 'in';
setTimeout(function(){
console.log(this.name)
},1000)
}
new test() // 1秒后打印'out'
上面這個是es5中罕見的this題目,計時器1s后運轉匿名函數,this已喪失了,因而默許綁定到了window上。
之前的典範處置懲罰要領是:
var name = 'out'
function test(){
this.name = 'in';
var self = this;
setTimeout(function(){
console.log(self.name)
},1000)
}
new test() // 1秒后打印'in'
顯式的運用self來保留住準確的this,防備this喪失。
實在這些都能夠運用箭頭函數來完成:
var name = 'out'
function test(){
this.name = 'in';
setTimeout(() => {
console.log(this.name)
},1000)
}
new test() // 1秒后打印'in'
在上面的代碼片斷中,箭頭函數內部的this在聲明時期就綁定為外層函數的this,且在運轉過程當中不會被修正。
不能當作組織函數
var Agumon = () => { this.name = 'agumon' }
var agumon = new Agumon() // Uncaught TypeError: Agumon is not a constructor
運用箭頭函數去當作組織函數來new對象會直接報錯,不過這個也好明白,由於箭頭函數並沒有本身的this,new操縱中有用到this的步驟它搞不定。
call或apply挪用無效
function foo() {
// 返回一個箭頭函數
return (a) => {
console.log( this.a );
};
}
var obj1 = {
a:2
};
var obj2 = { a:3};
var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 不是3
上面的代碼片斷顯式的運用call來想把foodethis綁定到obj1,但是並不見效,由於箭頭函數的this並不會在運轉時再被轉變。
沒有prototype
var Foo = () => {};
console.log(Foo.prototype); // undefined
箭頭函數是沒有原型的
不適用於作為對象的要領
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log( this.i, this)
}
}
obj.b();
// undefined
obj.c();
// 10, Object {...}
方才說了依據外層作用域來決議this,上面代碼片斷中的對象obj還不足以天生作用域,再往上就是全局作用域了,所以this被綁定為window。
參考資料:
MDN-箭頭函數
《你不知道的JavaScript-上卷》