var label = 2
var obj={
label:1
a:function(){
console.log(this.label);
}
}
obj.a(); //1
var b = obj.a
b(); //2
為什麼b會失去原始物件this,後面的原理是什麼?
================補充:巢狀函數的this指向window怎麼理解? =========================
##如果說函數的this,由它執行時的執行環境來決定,例如這裡的obj.a(),function的執行環境是obj所以this指向obj,而b()的執行環境是window,所以this指向window;那麼巢狀函數的this指向window,這個除了說“這是JS的語法規範規定的”,怎麼從JS的實現原理上理解? ###
var label = "windowC"
function showThis(){
var label = "innerC"
function innerFun(){
console.log(this.label)
}
innerFun()
}
showThis(); //windowC
對this的理解得了解執行上下文環境
建議閱讀 http://www.jianshu.com/p/d647...
var b=obj.a;就等價於var b=function(){console.log(this.label)};這裡相當於聲明了一個函數,this指向window
你聲明的b,其實就相當於window.b,所以印2沒有錯。理解this很重要
obj.a執行過程中a中的this指向的是obj,
而b(),相當於window.b(),this指向的是window
最近在翻高程3的書,應該可以幫到樓主。
首先,需要明確作用域的概念。
obj.1()//1,這塊,a中的functon中的this的作用域被限定在了obj這個對象當中,所以this的label的值則為你在obj對像中定義的屬性label的值,這個值為1。
接下來一行,你var了一個變數b,注意,很重要的一點,你的這個變數b是在全域作用域(window)中定義的,然後,你講obj.a方法賦值給b。接下來,(敲黑板,重點來了),你在全域作用域環境下(window)執行了b,而this的指向是需要根據執行環境來確定的,所以在全域作用域環境下label的值變為了你第一行寫的2。
如果還不懂得繼續討論哈,這個是基於我個人的理解
this是根據函數執行環境變化的 如果你後面想拿到當前的this可以先把this保存在一個變數中或使用apply/call/bind來綁定this
obj.a的值,不過是存放了它代表方法的地址,當
var b = obj.a
時,b變量存放的也是該方法的地址;而另一方面,全局聲明的變量,是
window
的屬性,故window.b == b
是成立的;調用
b()
時,就相當於window.b()
一樣。再跟obj.a()
對比,明白了吧;當然,就指向了window這個全局物件。給個讚也行哇
看了各位的答案,加上自己得到的理解,自問自答一下:
我是在結合obj在記憶體的儲存狀況來理解的,一開始也是在這裡遇到了困惑:
obj中,label和1都儲存在obj中,a作為一個變數存在obj中,a對應的function的實體儲存在obj之外,obj只是儲存一個指標。 因此obj.a()的this指向a並不是因為實體function存在裡面,而是孤立的實體function在被調用時,處於obj這個執行環境中;同理,b()的this指向window,也是因為孤立的實體function在被呼叫時,處於window這個執行環境中
只看結論的話就是,函數內部的this指向,由其調用方式決定:函數被物件所擁有則this指向該物件;函數獨立調用,則this指向undefined,非嚴格模式指向全域物件。