在平常的學習中,常常會遇到this的用法,本篇將會對其進行詳解。
你可能遇到過這樣的 JS 面試題:
var obj = { foo: function(){ console.log(this) } }var bar = obj.foo obj.foo() // 打印出的 this 是 objbar() // 打印出的 this 是 window
請解釋最後兩行函數的值為什麼不一樣。
——-
初學者對 this 的理解一直很模糊。今天這篇文章就要一次講清楚了。
而且這個解釋,你在別的地方看不到。看懂這篇文章,所有關於 this 的面試題,都是小菜。
函數呼叫
首先需要從函數的呼叫開始講起。
JS(ES5)裡面有三種函數呼叫形式:
func(p1, p2) obj.child.method(p1, p2) func.call(context, p1, p2) // 先不讲 apply
一般,初學者都知道前兩種形式,而且認為前兩種形式「優於」第三種形式。
從看到這篇文章起,你一定要記住,第三種呼叫形式,才是正常呼叫形式:
func.call(context, p1, p2)
其他兩種都是語法糖,可以等價地變成call 形式:
func(p1, p2) 等價於func.call(undefined, p1, p2)obj .child.method(p1, p2) 等價於obj.child.method.call(obj.child, p1, p2)
function func(){ console.log(this)}func() 等价于 function func(){ console.log(this)}func.call(undefined) // 可以简写为 func.call()按理說列印出來的this 應該就是undefined 了吧,但是瀏覽器裡有一條規則:如果你傳的context 就null 或者undefined,那麼window 物件就是預設的context(嚴格模式下預設context 是undefined)
因此上面的列印結果是window。
var obj = { foo: function(){ console.log(this) } } obj.foo()依照「轉換程式碼」,我們將obj.foo() 轉換為
obj.foo.call(obj)
var obj = { foo: function(){ console.log(this) } }var bar = obj.fooobj.foo() // 轉換成obj.foo.call(obj),this 就是objbar()// 轉換成bar.call()/ / 由於沒有傳context// 所以this 就是undefined// 最後瀏覽器給你一個預設的this —— window 物件
function fn (){ console.log(this) } var arr = [fn, fn2] arr0 // 这里面的 this 又是什么呢?我們可以把arr0 想像為arr.0( ),雖然後者的語法錯了,但是形式與轉換程式碼裡的obj.child.method(p1, p2) 對應上了,於是就可以愉快的轉換了:# arr0
假想為 arr.0()
然後轉換成arr.0.call(arr)
那麼裡面的this 就是arr 了:)
如果你的函數呼叫形式不是 call 形式,請依照「轉換程式碼」將其轉換為 call 形式。
以上是Javascript關於this的用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!