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
型別也就是這個新的物件型別。
相關文章
- 建構函式建立物件函式物件
- 工廠模式建立物件和自定義建構函式建立物件的異同模式物件函式
- axios為什麼可以使用物件和函式兩種方式呼叫?是如何實現的?iOS物件函式
- 建構函式方式建立正規表示式函式
- 私有建構函式的物件建立例項函式物件
- JavaScript 建構函式JavaScript函式
- JavaScript建構函式,物件導向程式設計JavaScript函式物件程式設計
- JavaScript物件的建立方式有幾種?JavaScript物件
- 還在問什麼是JavaScript建構函式、例項、原型物件以及原型鏈?看完這篇你就懂JavaScript函式原型物件
- 《JavaScript物件導向精要》之四:建構函式和原型物件JavaScript物件函式原型
- JavaScript物件導向之二(建構函式繼承)JavaScript物件函式繼承
- JavaScript Date()建構函式JavaScript函式
- 建立派生類物件,建構函式的執行順序物件函式
- JavaScript 建立物件的方式JavaScript物件
- 回顧Javascript建構函式JavaScript函式
- JavaScript物件與建立物件的方式JavaScript物件
- JavaScript 函式引數解構物件JavaScript函式物件
- JS中建立函式的幾種方式JS函式
- 【譯】JavaScript 工廠函式 vs 建構函式JavaScript函式
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- 為什麼 Go 裡值為 nil 可以呼叫函式?Go函式
- 理清原型物件、 例項物件、建構函式原型物件函式
- 為什麼值型別不允許顯式定義無參建構函式型別函式
- 建立物件的幾種模式物件模式
- 預設建構函式、引數化建構函式、複製建構函式、解構函式函式
- javascript純函式是什麼JavaScript函式
- java建立物件的五種方式Java物件
- 建立Session物件的兩種方式Session物件
- 輕鬆理解建構函式和原型物件函式原型物件
- 前端筆記之JavaScript物件導向(一)Object&函式上下文&建構函式&原型鏈前端筆記JavaScript物件Object函式原型
- 你構建的程式碼為什麼這麼大
- Golang建立建構函式的方法詳解Golang函式
- JavaScript建立物件(三)——原型模式JavaScript物件原型模式
- JavaScript建立物件(一)——工廠模式JavaScript物件模式
- class和普通建構函式有什麼區別?函式
- JavaScript建立物件的多種方法JavaScript物件
- 【C/C++】為什麼需要複製建構函式的同時通常也需要過載複製運算子C++函式
- 為什麼不建議函式有太多引數?函式