4 回答
TA貢獻1842條經驗 獲得超22個贊
var b=25;
var a={
b:20,
func: function(){
return this.b;
}
}
console.log(( a. func)())//20 A
console.log(( a. func, a.func)())//25我覺得應該都是25啊。。 B
這里涉及到2個運算符的問題,分組運算符,逗號運算符
分組運算符對于其中的表達式運算結果為reference類型的-引用類型的,不會執行取值操作
逗號運算符對其中的每一個表達式的都會執行取值操作,并且返回最有一個表達式的值作為最終的計算結果
那么對于 A 語句
(a.func)();
的左邊括號就是個分組運算符,a.func屬性訪問表達式返回一個reference,分組運算符不對拿到的引用執行解引用操作,也就不取出實際指向的函數對象,還在a對象的環境下,接下來就對拿到的reference執行調用,此時的this還是a對象。這個和
var p=a.func;
p();
不同的,賦值運算符會對a.func求值。獲取函數對象,進而賦值給p。p調用,this為為全局對象
對于 A 語句
(a.func, a.func)();
逗號運算符,對a.func都會取出實際指向的函數對象,返回這個函數對象。右邊的括號為一個函數調用操作符,此時的this為全局對象。
代碼改成如下也是同樣的結果
(1, a.func)();
對于引用和解應用,另一個操作符delete會給出更好的理解
delete a.func;
delete操作符下,a.func的運算結果是返回一個reference而不是函數對象。也就是delete的不是指向的函數對象而是a.func本身
TA貢獻1831條經驗 獲得超4個贊
除了this指向還有一個逗號操作符的小知識
逗號操作符依次執行返回最后一個 相當于賦給匿名值后再操作
(a.func)(); //-> a.func() a調用this為a
//逗號操作符相當于賦給匿名值后再操作
(a.func, a.func)(); //-> var c = a.func; c(); c()->window.c() window調用this為window
TA貢獻1909條經驗 獲得超7個贊
抽象下代碼,這樣好分析
var a = {
func: function() {
console.log(this);
}
};
a.func();//1、a
(a.func)(); //2、 a
(a.func, a.func)(); //3、 window;
(a.func = a.func)(); // 4、window;
這里其實就是 this 的指向問題;
1、在方法調用(如果某個對象的屬性是函數,這個屬性就叫方法,調用這個屬性,就叫方法調用)中,執行函數體的時候,作為屬性訪問主體的對象和數組便是其調用方法內 this 的指向。通俗的說,調用誰的方法 this 就指向誰;)
2、雖然加上括號之后,就好像只是在引用一個函數,但 this 的值得到了維持,因為 a.func() 和 (a.func()) 的定義時相同的,按照 kikong 所說,就是 ()不對拿到的引用執行解引用操作,也就不取出實際指向的函數對象,還在a對象的環境下,接下來就對拿到的reference執行調用,此時的this還是a對象。
3、4、其實一樣,逗號運算符、賦值運算符都返回一個值,也就是保存在內存中的函數本身,所以 this 的值不能得到維持,這是因為
this 對象是在運行時基于函數的執行環境綁定的:在全局函數中,this 等于window(瀏覽器非嚴格模式,嚴格模式是 undefined)
上面四個明白了,上面的題目就解開了;this 更多了解 戳這
這里有個引申,按照上面的邏輯,所有返回值操作的,都有可能去改變上面代碼中的 this 值,都需要謹慎,譬如
var a = {
func: function() {
return this;
}
};
function f(fn) {
console.log(fn());
}
f(a.func);//window
因為函數中的參數也是按照值傳遞的,在向參數傳遞引用類型的值時,會把這個值在內存中的地址復制給一個局部變量。
添加回答
舉報
