摘要:發生這種情況的條件是當引用類型值的對象恰好為活躍對象。總結本文介紹中的使用,更重要的是幫助我們能更好地理解值在全局函數構造函數以及一些特例的情況中值的變化。然而,由于對于來說沒有任何意義,因此會隱式轉換為全局對象。
接上一篇Javascript this 的一些學習總結02【轉自cnblogs的JKhuang】
引用類型以及this的null值
對于前面提及的情形,還有例外的情況,當調用表達式左側是引用類型的值,但是this的值卻是null,最終變為全局對象(global object)。 發生這種情況的條件是當引用類型值的base對象恰好為活躍對象(activation object)。
當內部子函數在父函數中被調用的時候就會發生這種情況,通過下面的示意代碼介紹活躍對象:
// Declares foo function. function foo() { function bar() { alert(this); // global } // The same as AO.bar(). bar(); }
由于活躍對象(activation object)總是會返回this值為——null(用偽代碼來表示AO.bar()就相當于null.bar()),然后,this的值最終會由null轉變為全局對象。
當函數調用包含在with語句的代碼塊中,并且with對象包含一個函數屬性的時候,就會出現例外的情況。with語句會將該對象添加到作用域鏈的最前面,在活躍對象的之前。 相應地,在引用類型的值(標識符或者屬性訪問)的情況下,base對象就不再是活躍對象了,而是with語句的對象。另外,值得一提的是,它不僅僅只針對內部函數,全局函數也是如此, 原因就是with對象掩蓋了作用域鏈中更高層的對象(全局對象或者活躍對象):
函數作為構造器被調用時this的值
函數作為構造函數時,我們通過new操作符創建實例對象是,它會調用Foo()函數的內部[[Construct]]方法;在對象創建之后,會調用內部的[[Call]]方法,然后所有Foo()函數中this的值會設置為新創建的對象。
// Declares constructor function Foo() { // The new object. alert(this); this.x = 10; } var foo = new Foo(); foo.x = 23; alert(foo.x); // 23
手動設置函數調用時this的值
Function.prototype原型上定義了兩個方法,允許手動指定函數調用時this的值。這兩個方法分別是:.apply()和.call()。這兩個方法都接受第一個參數作為調用上下文中this的值,而這兩個方法的區別是傳遞的參數,對于.apply()方法來說,第二個參數接受數組類型(或者是類數組的對象,比如arguments), 而.call()方法接受任意多的參數(通過逗號分隔);這兩個方法只有第一個參數是必要的——this的值。
通過示例代碼介紹call()方法和apply()方法的使用:
var myObject = {}; var myFunction = function(param1, param2) { //setviacall()"this"points to my Object when function is invoked this.foo = param1; this.bar = param2; //logs Object{foo = "foo", bar = "bar"} console.log(this); }; // invokes function, set this value to myObject myFunction.call(myObject, "foo", "bar"); // logs Object {foo = "foo", bar = "bar"} console.log(myObject);
call()方法第一個參數是必要的this值,接著我們可以傳遞任意多個參數,接著介紹apply()方法的使用。
var myObject = {}; var myFunction = function(param1, param2) { //set via apply(), this points to my Object when function is invoked this.foo=param1; this.bar=param2; // logs Object{foo="foo", bar="bar"} console.log(this); }; // invoke function, set this value myFunction.apply(myObject, ["foo", "bar"]); // logs Object {foo = "foo", bar = "bar"} console.log(myObject);
通過與call()方法對比,我們發現apply()方法和call()方法沒有太大的區別,只是方法簽名不一樣。
總結
本文介紹Javascript中this的使用,更重要的是幫助我們能更好地理解this值在全局、函數、構造函數以及一些特例的情況中值的變化。
對于在函數上下文中this的值是函數調用者提供并且由當前調用表達式的形式而定的。如果在調用括號()的左邊有引用類型的值,那么this的值就會設置為該引用類型值的base對象。 所有其他情況下(非引用類型),this的值總是null。然而,由于null對于this來說沒有任何意義,因此會隱式轉換為全局對象。
對于特例情況,我們要記住賦值符、逗號操作符以及||邏輯表達式,會使this丟失原先的引用類型值,變成了函數類型,this的值就變成了全局對象了
參考
http://dmitrysoshnikov.com/ec...英文版
http://blog.goddyzhao.me/post... 譯文
https://net.tutsplus.com/tuto...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88108.html
摘要:總結本博文通過介紹執行上下文和作用域的異同的使用以及變量對象,讓我們加深對語言特性的理解。首先,我們介紹了執行上下文和的的關系,并且執行上下文是具有對象的然后,介紹了作用域使變量在作用域范圍內可見,并且作用域是基于函數的。 接上一篇Javascript Context和Scope的學習總結01【轉自cnblogs的JKhuang】(可能是segmentfault對單篇文章發布字數有限制...
摘要:函數上下文中的值是函數調用者提供并且由當前調用表達式的形式而定的。然而,由于對于來說沒有任何意義,因此會隱式轉換為全局對象。這里注意到四個表達式中,只有第一個表達式是指向對象的,而其他三個表達式則執行。 摘要 相信有C++、C#或Java等編程經驗的各位,對于this關鍵字再熟悉不過了。由于Javascript是一種面向對象的編程語言,它和C++、C#或Java一樣都包含this關鍵字...
摘要:正文執行環境也稱為環境是中最為重要的一個概念。執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自的行為。簡而言之,執行環境是基于對象的,而作用域是基于函數的。 前述 在我們學習Javascript過程中,常常會遇到作用域(Scope)和執行上下文(Context)等概念。其中,執行上下文與this關鍵字的關系密切。 有面向對象編程經驗的各位,對于this關鍵字再熟悉不過了,因此...
摘要:獲取字符串中出現次數最多的字符。去掉字符串中的所有空格中對象數組按對象屬性排序 VUE 1、vue——解決You may use special comments to disable some warnings. Use // eslint-disable-next-line to ignore the next line. Use / eslint-disable / to ign...
摘要:獲取字符串中出現次數最多的字符。去掉字符串中的所有空格中對象數組按對象屬性排序 VUE 1、vue——解決You may use special comments to disable some warnings. Use // eslint-disable-next-line to ignore the next line. Use / eslint-disable / to ign...
閱讀 2621·2021-11-25 09:43
閱讀 2725·2021-11-04 16:09
閱讀 1634·2021-10-12 10:13
閱讀 881·2021-09-29 09:35
閱讀 880·2021-08-03 14:03
閱讀 1777·2019-08-30 15:55
閱讀 2989·2019-08-28 18:14
閱讀 3489·2019-08-26 13:43