標籤:window 影響 方式 code 全域變數 class 不同的 new 串連
近來,學習了一下《JavaScript精粹》,讀到了函數這章,理清了JavaScript中this在不同調用模式下的指向。
1、Function調用模式:Function是JavaScript的一種參考型別,擁有四種調用模式:方法調用模式,函數調用模式,構造器調用模式,apply(call)調用模式
2、Function的不同調用模式對this產生不同的影響:
(1)方法調用模式:Function作為對象的方法被調用。此時,this指向調用Function的對象。
1 var obj = {2 name: "lucy", 3 printName: function( ) {4 console.log( this.name ); // 此時printName,作為obj的方法被調用,this指向調用printName的obj,this.name === "lucy"。5 } 6 };
(2)構造器調用模式:Function作為構造器被調用,亦即使用new操作符,建立新的對象執行個體,將新的對象串連到該函數的prototype上,並且將this指向新建立的對象執行個體;同時,執行構造器內的代碼為新的對象執行個體新增成員,最後返回這個新的對象執行個體。
1 // 建立構造器Demo,在Demo被new操作符調用時,this指向Demo的prototype。 2 var Demo = function( ){ 3 this.name = "jack"; 4 }; 5 6 // 在Demo的prototype中,添加方法printName。 7 Demo.prototype.printName = function( ){ 8 concole.log(this.name); 9 };10 11 // 建立Demo執行個體,此時this已經指向Demo的prototype 12 var d = new Demo( );13 console.log(d.name); // 在控制台輸出"jack"14 d.printName( ); // 在控制台輸出"jack"
PS:建構函式、構造器只是在英譯中的過程中的翻譯用詞差異,在英文都是constructor。《JavaScript精粹》譯為構造器,《JavaScript進階程式設計》第三版譯為建構函式。
(3)apply(call)調用模式:JavaScript中,函數也是對象而具有方法,其具有方法apply。apply接受兩個參數,第一個是要傳遞給this的值,第二個是參數數組。當函數調用apply方法時,將函數內部的this指向apply傳遞的第一個參數。
1 var people = { 2 this.name = "lily"; 3 } 4 5 var printName = function( ){ 6 console.log(this.name) 7 } 8 9 // 此時apply將this指向了people10 printName.apply(people) // 在控制台輸出 lily
PS:《JavaScript精粹》中只提及apply。apply和call在功能上是相同的,但是具體的使用方式上,有小差異。
(4)函數調用模式:既不是作為方法調用,也不是調用自己的apply(call),也不是作為構造器被new調用,這時候調用就是函數調用模式。此時函數內部的this指向全域變數,在瀏覽器中指的是window變數,在node.js中指的是global變數。
1 window.name = "bob";2 3 // 此時this指向window4 var printName = function( ) {5 console.log( this.name );6 };7 8 console.log(window.name) // 在控制台輸出bob9 printName() // 在控制台輸出bob
3、小結:
(1)方法調用模式:this指向調用方法的對象。
(2)構造器調用模式:this指向構造器的prototype。
(3)apply調用模式:this指向apply傳入的第一個對象。
(4)函數調用模式:this指向全域對象window。
JavaScript 再認識(一):Function調用模式對this的影響