在理解javascript的this之前,首先先了解一下作用域。
作用域分為兩種:
詞法作用域和動態作用域的區別是:詞法作用域是在寫代碼或定義時確定的;動態作用域是在運行時確定的。
this的綁定規則
this是在調用時被綁定,取決于函數的調用位置。由此可以知道,一般情況下(非嚴格模式下),this都會根據函數調用(調用棧)的上下文來綁定對象。
一、默認綁定
默認綁定:默認綁定是指在非嚴格模式下,且沒有使用別的綁定規則時,this根據函數調用(調用棧)的上下文來綁定對象(全局對象)。(嚴格模式下則綁定undefined)
舉個栗子:
function foo() { console.log(this.a);};function bar() { var a = 3; foo();}var a = 2;bar(); //調用棧在全局作用域,this綁定全局對象運行結果為: 2
//加上"use strict"運行結果則會變成this is undefined
這里的函數調用時,使用了默認綁定,函數調用(調用棧)的上下文是全局作用域,因此this綁定了全局對象(global)。
eg2:
function foo() { console.log(this.a)};var a = 2;(function() { "use strict" foo();})();運行結果為: 2
這里需要注意:對于默認綁定,決定this綁定對象的不是調用位置是否處于嚴格模式,而是函數體是否處于嚴格模式(函數體處于嚴格模式則this綁定undefined;否則this綁定全局對象)。另外:嚴格模式和非嚴格模式雖然有可能可以綁定,但是最好不混用。
間接引用一般也是會應用默認綁定規則。
function foo() { console.log(this.a);};var a = 2;var o = { a: 3, foo: foo };var p = { a: 4 };o.foo(); //3(p.foo = o.foo)(); //2賦值表達式 p.foo = o.foo的返回值是直接引用目標函數foo。
二、隱式綁定
隱式綁定:由上下文對象調用,綁定到上下文對象。
舉個栗子:
function foo() { console.log(this.a);};var obj = { a: 2, foo: foo};obj.foo(); //2foo(); //undefined這段代碼中,foo()被當做引用屬性添加到obj對象中,obj調用這個引用屬性函數時,會使用該引用屬性上下文,this會被綁定到obj對象。(這個函數嚴格來說不屬于obj對象,只是作為引用屬性)。屬于隱式綁定。
而下面foo()函數的直接執行,并不是obj對象引用,所以上下文對象是全局對象。故this綁定了undefined。屬于默認綁定。
新聞熱點
疑難解答
圖片精選