javascript:建構函式模式(為什麼這種方式也可以建立物件)
ECMAScript
中建構函式可以用來建立特定型別的物件。像Object
和Array
這樣的原生建構函式,在執行時會自動出現在執行環境中。此外,也可以建立自定義的建構函式,從而定義自定義物件型別的屬性和方法。例如,可以使用建構函式模式將前面的例子重寫。如下:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
return this.name;
};
}
var p1 = new Person("Ann" , 23 , "actress");
var p2 = new Person("Rose" , 23 , "writer");
當我看到上面的內容的時候,我震驚了。javascript
中呼叫函式可以建立一個新的物件?使用new
操作符,然後呼叫函式就可以了?
雖然這種方式很奇怪(相對於java
,c#
而言),但是,的確可以。
因為根據以往的經驗,函式中的this
是當前的執行環境變數。一般來說,如果是在網頁上的全域性環境裡面呼叫函式,則函式內部的this
物件就是window
物件。但是,這裡的this
好像是一個新的型別(Person
?)的物件。為什麼?
下面是我的小測驗,檢視一下通過這種方式呼叫函式,是不是真的改變了this
物件。
1 使用
new
呼叫建構函式的程式碼:
console.log("<>>>before this是 Window 型別嗎? " + (this instanceof Window));
function Person(name, age, job) {
console.log("inner this是 Window 型別嗎? " + (this instanceof Window));
console.log("inner this是 Person 型別嗎? " + (this instanceof Person));
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
return this.name;
};
}
var p1 = new Person("Ann", 23, "actress");
// todo: 使用了 new 操作符
console.log("outer this是 Window 型別嗎? " + (this instanceof Window));
console.log("outer this是 Person 型別嗎? " + (this instanceof Person));
// 在瀏覽器執行的輸出結果如下
/**
<pre>
// todo: 在瀏覽器執行的輸出結果如下 :
<>>>before this是 Window 型別嗎? true
inner this是 Window 型別嗎? false
inner this是 Person 型別嗎? true
outer this是 Window 型別嗎? true
outer this是 Person 型別嗎? false
</pre>
*/
2 不使用
new
,直接呼叫建構函式的程式碼:
console.log("<>>>before this是 Window 型別嗎? " + (this instanceof Window));
function Person(name, age, job) {
console.log("inner this是 Window 型別嗎? " + (this instanceof Window));
console.log("inner this是 Person 型別嗎? " + (this instanceof Person));
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
return this.name;
};
}
var p1 = Person("Ann", 23, "actress"); // 注意:這裡沒有 new
console.log("outer this是 Window 型別嗎? " + (this instanceof Window));
console.log("outer this是 Person 型別嗎? " + (this instanceof Person));
/*
<pre>
// todo: 在瀏覽器執行的輸出結果如下 :
<>>>before this是 Window 型別嗎? true
inner this是 Window 型別嗎? true
inner this是 Person 型別嗎? false
outer this是 Window 型別嗎? true
outer this是 Person 型別嗎? false
</pre>
*/
同樣的程式碼,只是在呼叫的時候,一次使用了new
操作符來呼叫Person()
函式,一次沒有。然後輸出的效果並不相同。
從log
可以看到:
- 在函式外部,
this
一直是Window
型別的物件。(在全域性環境中呼叫的)[即使函式內部的this
不是Window
型別。] - 在函式內部:
- 如果當前函式被
new funcName(args);
的方式呼叫,this
為當funcName
型別的物件; - 如果當前函式沒有使用
new
操作符呼叫,只是普通呼叫(var result = funcName(args);
),則this
是Window
型別的物件。
- 如果當前函式被
所以,通過建構函式模式確實建立了一個新的物件,而且,這個物件有自己的型別,可以被型別識別到了。
總結:
- 任何函式,不使用
new
去呼叫,就是普通的函式呼叫,函式中的this
是當前函式呼叫的執行環境變數。(誰呼叫我,我的this
就是誰。)。 - 任何函式,使用
new
去呼叫,就成了建構函式,函式會建立一個新的物件型別,新的物件型別名就是當前函式名,函式中的this
型別也就是這個新的物件型別。
相關文章
- 建構函式建立物件函式物件
- javascript基礎(this,工廠方法來建立物件,建構函式建立物件)(十六)JavaScript物件函式
- 工廠模式建立物件和自定義建構函式建立物件的異同模式物件函式
- javascript建立安全的建構函式JavaScript函式
- JavaScript進階系列03,通過硬編碼、工廠模式、建構函式建立JavaScript物件JavaScript模式函式物件
- 建構函式方式建立正規表示式函式
- javascript建立物件的三種方式JavaScript物件
- JavaScript 建立物件的七種方式JavaScript物件
- javascript建立物件的幾種方式JavaScript物件
- 私有建構函式的物件建立例項函式物件
- JavaScript 建立類/物件的幾種方式JavaScript物件
- js Date()建構函式建立時間日期物件JS函式物件
- JavaScript 建構函式JavaScript函式
- 還在問什麼是JavaScript建構函式、例項、原型物件以及原型鏈?看完這篇你就懂JavaScript函式原型物件
- Javascript 物件導向中的建構函式和原型物件JavaScript物件函式原型
- JavaScript建構函式,物件導向程式設計JavaScript函式物件程式設計
- JavaScript物件的建立方式有幾種?JavaScript物件
- [轉載]javascript建立物件的幾種方式JavaScript物件
- 《JavaScript物件導向精要》之四:建構函式和原型物件JavaScript物件函式原型
- JavaScript Date()建構函式JavaScript函式
- javascript Function()建構函式JavaScriptFunction函式
- java中寫建構函式的另外一種方式Java函式
- JavaScript物件導向之二(建構函式繼承)JavaScript物件函式繼承
- 為什麼 Go 裡值為 nil 可以呼叫函式?Go函式
- 建立派生類物件,建構函式的執行順序物件函式
- JavaScript 函式的兩種宣告方式JavaScript函式
- 回顧Javascript建構函式JavaScript函式
- JavaScript 建立物件的方式JavaScript物件
- JS中建立函式的幾種方式JS函式
- JavaScript物件與建立物件的方式JavaScript物件
- 【譯】JavaScript 工廠函式 vs 建構函式JavaScript函式
- 理解建構函式與原型物件函式原型物件
- JavaScript 函式引數解構物件JavaScript函式物件
- 你構建的程式碼為什麼這麼大
- 建構函式與解構函式是否可以丟擲異常函式
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- 為什麼值型別不允許顯式定義無參建構函式型別函式
- JavaScript建構函式和普通函式的區別JavaScript函式