前言
this是函數中的隱形參數,它綁定的值取決於函數的調用位置。
this的定義
《你不知道的js》中是這樣說的:是函數體內的隱式參數,this就是記錄函數調用上下文的一個屬性。可以在函數體中使用this引用函數的調用上下文。this的綁定關注的是函數的調用位置。
調用位置:是函數在調用時的位置,區別於函數聲明時的位置。
this的綁定規則
this綁定方式取決於函數的調用位置,根據不同的場景,有四中綁定方式(默認、隱式、顯示、構造調用中的綁定)。多種情況同時存在時,依靠的是這四中規則的優先級別采用相應的綁定。
默認綁定
當函數不使用任何修飾時直接調用。無論在哪里調用,它指向的都是全局對象(瀏覽器環境下指向的是window)。注:嚴格模式下this會綁定到undefined。
function run(){ console.log(this); //window
console.log("running"); function speak(){ console.log("speak"); console.log(this); // window
} return speak; } run()();
隱形綁定
當函數擁有上下文對象的時候,隱式綁定規則會把函數調用中的this綁定到這個上下文對象。
// 對象的屬性不管以任何形式擁有函數的引用時,通過對象屬性調用這個函數時,這個函數當前調用上下文就是這個對象。
function foo(){ console.log(this.a); } var obj = { a:1, foo:foo } obj.foo(); // 1
// 直接上下文:只有最后一層調用影響this的綁定
function foo(){
console.log(this.a);
}
var obj1 = {
a:1,
foo:foo
}
var obj2 = {
a:2,
obj1:obj1
}
obj2.obj1.foo(); // 1
顯示綁定
直接指定this的綁定對象就叫做顯示綁定。js中所有函數都從Function.prototype上繼承了call和apply這兩個方法。他們都是用來顯示指定函數執行時其中的this的。
call和apply的異同:
目的相同:都用來指定函數執行時其中的this。
參數個數和類型不同:apply接收兩個參數,第一個是本次執行要綁定在函數this上的值,第二個是一個數組。call接收的是一個參數列表,參數需要一個一個的傳,他會把第一個參數綁定到本次執行函數的this上去。
參數的處理:apply會把第二個參數(Array類型)展開后依次傳到本次執行的函數中去。call是取第一綁定到this,再把后面的參數依次傳入本次執行函數。
注:argument是函數體中的另一個隱式參數。可以在函數體內拿到函數運行時,接收到的實參。它是一個偽數組,其中的元素和實參一 一對應
// 以下輸出結果出自chrome
function test(){ console.log(test.arguments); } // apply 數組[1,2,3]被展開分成三個參數 依次傳入 test。
test.apply({},[1,2,3]); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] // call 數組[1,2,3] 作為一個參數傳進了test中
test.call({},[1,2,3]); // Arguments [Array(3), callee: ƒ, Symbol(Symbol.iterator): ƒ]
常用操作
// 使用call調用數組map方法。
var arr = [1,2,3,4];
Array.prototype.map.call(arr,function(item){ console.log(item); // 分別輸出 1 2 3 4
})
new綁定
使用new 操作符調用函數叫做構造調用。函數做構造調用時,其中this的綁定。函數做構造調用時其中有四個默認操作。
1,創建一個新的對象。
2,這個對象會被執行原型鏈接(添加到構造函數的原型鏈的末尾)。
3,把當前正在做構造調用的函數中的this綁定到新創建的對象。
3,如果函數沒有顯式的返回其他對象,那么默認返回這個新建的對象。
// 對foo進行構造調用創建一個新的對象
function foo(a){ this.a = a; } var bar = new foo(2); console.log(bar.a);
js中的構造函數
1,只是使用new操作符調用的普通函數。
2,不屬於某個類,也不會實例化某個類。
3,所有函數使用new 進行調用時都被稱作構造調用。
4,js中不存在面向類語言意義上的構造函數,只有基於new操作符號的構造調用。