this提供了一種更優雅的方式來“隱式”傳遞一個對象的引用,
eg:
function identify() {
return this.name.toUpperCase();
}
function speak() {
var greeting = "Hello, I'm " + identify.call( this );
console.log( greeting );
}
var me = {
name: "Kyle"
};
var you = {
name: "Reader"
};
identify.call( me ); // KYLE
identify.call( you ); // READER
speak.call( me ); // Hello, 我是 KYLE
speak.call( you ); // Hello, 我是 READER
如果不用this,則需要顯示傳遞一個上下文對象
綁定規則
this是在運行時進行綁定的,它的上下文取決于函數調用時的各種條件。this的綁定和函數聲明的位置沒有任何關系。
1.默認綁定
直接使用不帶任何修飾符的函數引用進行調用使用默認綁定,this
被綁定到全局對象。
NOTE:在嚴格模式中,全局對象將無法使用默認綁定,this
會等于undefined
2.隱式綁定
調用時使用object上下文來引用函數,隱式綁定將函數中的this綁定到這個object
NOTE:丟失綁定對象的情況
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 函數別名!
var a = "oops, global"; // a 是全局對象的屬性
bar(); // "oops, global"
雖然bar
是obj.foo
的一個引用,但它引用的是foo
函數本身,因此此時bar()
是一個不帶任何修飾符的調用,采用默認綁定
3.顯式綁定
call()和apply()
foo.call(foo,i);
使用call()
可以確保this指向函數對象foo本身
硬綁定
Function.prototype.bind會返回一個硬編碼的新函數,它會把參數設置為this的上下文并調用原始函數,除了new時
軟綁定
保留隱式綁定或顯式綁定修改this的能力
4.new綁定
使用new來調用函數會放生:
- 創建(或者說構造)一個全新的對象。
- 這個新對象會被執行 [[ 原型 ]] 連接。
- 這個新對象會綁定到函數調用的 this。
- 如果函數沒有返回其他對象,那么 new 表達式中的函數調用會自動返回這個新對象。
NOTE:
1如果把null或undefined作為this的綁定對象傳入call,apply或者bind,這些值在調用時會被忽略,實際應用的是默認綁定規則
2.箭頭函數的this是外層作用域。