(轉(zhuǎn)載微信上看到的很棒的一篇關(guān)于this的寫法阴挣,分享給大家
http://mp.weixin.qq.com/s/ksqtCd8ouxU-cVc_HnA4Aw)
也可以看阮一峰的這篇:
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
還有51博客上看到的很詳細(xì)的解釋:
http://weizhan.51cto.com/article/view/58eb2924f2dd872e48200541
相信這幾篇大家看看應(yīng)該會有更深入的理解局待。
你可能遇到過這樣的 JS 面試題:
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
請解釋最后兩行函數(shù)的值為什么不一樣孵淘。
——-
初學(xué)者關(guān)于 this 的理解一直很模糊憨降。今天這篇文章就要一次講清楚了与殃。
而且這個解釋立帖,你在別的地方看不到眼溶。看懂這篇文章晓勇,所有關(guān)于 this 的面試題堂飞,都是小菜。
函數(shù)調(diào)用
首先需要從函數(shù)的調(diào)用開始講起绑咱。
JS(ES5)里面有三種函數(shù)調(diào)用形式:
func(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2) // 先不講 apply
一般绰筛,初學(xué)者都知道前兩種形式,而且認(rèn)為前兩種形式「優(yōu)于」第三種形式描融。
從看到這篇文章起铝噩,你一定要記住,第三種調(diào)用形式稼稿,才是正常調(diào)用形式:
func.call(context, p1, p2)
其他兩種都是語法糖薄榛,可以等價地變?yōu)?call 形式:
func(p1, p2) 等價于
func.call(undefined, p1, p2)
obj.child.method(p1, p2) 等價于
obj.child.method.call(obj.child, p1, p2)
請記下來。(我們稱此代碼為「轉(zhuǎn)換代碼」让歼,方便下文引用)
至此我們的函數(shù)調(diào)用只有一種形式:
func.call(context, p1, p2)
這樣敞恋,this 就好解釋了
this,就是上面代碼中的 context谋右。就這么簡單硬猫。
this 是你 call 一個函數(shù)時傳的 context,由于你從來不用 call 形式的函數(shù)調(diào)用改执,所以你一直不知道啸蜜。
先看 func(p1, p2) 中的 this 如何確定:
當(dāng)你寫下面代碼時
function func(){
console.log(this)
}
func()
等價于
function func(){
console.log(this)
}
func.call(undefined) // 可以簡寫為 func.call()
按理說打印出來的 this 應(yīng)該就是 undefined 了吧,但是瀏覽器里有一條規(guī)則:
如果你傳的 context 就 null 或者 undefined辈挂,那么 window 對象就是默認(rèn)的 context(嚴(yán)格模式下默認(rèn) context 是 undefined)
因此上面的打印結(jié)果是 window衬横。
如果你希望這里的 this 不是 window,很簡單:
func.call(obj) // 那么里面的 this 就是 obj 對象了
再看 obj.child.method(p1, p2) 的 this 如何確定
var obj = {
foo: function(){
console.log(this)
}
}
obj.foo()
按照「轉(zhuǎn)換代碼」终蒂,我們將 obj.foo() 轉(zhuǎn)換為
obj.foo.call(obj)
好了蜂林,this 就是 obj。搞定拇泣。
回到題目:
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 轉(zhuǎn)換為 obj.foo.call(obj)噪叙,this 就是 obj
bar()
// 轉(zhuǎn)換為 bar.call()
// 由于沒有傳 context
// 所以 this 就是 undefined
// 最后瀏覽器給你一個默認(rèn)的 this —— window 對象
[ ] 語法
function fn (){ console.log(this) }
var arr = [fn, fn2]
arr0 // 這里面的 this 又是什么呢?
我們可以把 arr0 想象為arr.0( )霉翔,雖然后者的語法錯了睁蕾,但是形式與轉(zhuǎn)換代碼里的 obj.child.method(p1, p2) 對應(yīng)上了,于是就可以愉快的轉(zhuǎn)換了:
arr0
假想為 arr.0()
然后轉(zhuǎn)換為 arr.0.call(arr)
那么里面的 this 就是 arr 了 :)
總結(jié)
this 就是你 call 一個函數(shù)時,傳入的 context子眶。
如果你的函數(shù)調(diào)用形式不是 call 形式瀑凝,請按照「轉(zhuǎn)換代碼」將其轉(zhuǎn)換為 call 形式。
以后你遇到所有跟 this 有關(guān)的筆試題壹店,都不會有疑問了猜丹。
完。