小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

  1. Object構造函數方法

var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ console.log(this.name); }

2.對象字面量方法

var person = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function(){ console.log(this.name); } };

如果在html環境下,為了便於輸出,可以將 console.log() 替換成 alert() ,以下代碼同理。

和傳統的面嚮對象語言相比較,上述的對象創建方式存在明顯的問題。第一個問題,對象的創建代碼並不能實現很好的複用,第二個問題,使用同一個接口創建很多對象,會產生大量的重複代碼。

以下提出了幾種創建對象的模式,針對每種模式,本文中會針對上述兩個問題以及其他問題進行優缺點分析。

小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

一、工廠模式

工廠模式用函數封裝了以特定接口創建對象的細節

function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ console.log(this.name); }; return o; } var person1 = createPerson("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg" console.log(person1.sayName == person2.sayName); //false

工廠模式雖然解決了創建多個相似對象的問題,但是沒有解決對象識別的問題,即通過這種方式創建的對象通過instanceof確定的對象類型只能是Object。可以看出,每創建一個對象, sayName() 方法都會被重複定義一次,造成了冗餘。

二、構造函數模式

使用構造函數模式重寫前面的例子,如下:

function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ console.log(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg" console.log(person1 instanceof Object); //true console.log(person1 instanceof Person); //true console.log(person2 instanceof Object); //true console.log(person2 instanceof Person); //true console.log(person1.sayName == person2.sayName); //false

小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

從代碼可以看出,創建自定義的構造函數意味著將來可以將它的實例標識為一種特定的類型,而這正是構造函數模式勝過工廠模式的地方。但是和工廠模式一樣, sayName() 方法被重複定義的問題並沒有得到解決,為什麼在傳統的面嚮對象語言比如Java,C++中這麼寫不會產生這個問題呢?因為ECAMScript中的函數是對象,所以每定義一個函數,也就是實例化了一個對象,本質上就造成了對象的重複創建,所以說會造成冗餘,而在Java,C++中,函數僅僅是函數而已。

好了,既然這樣,那我們就嘗試把函數定義轉移到構造函數的外部:

function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ console.log(this.name); } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor");14 15 person1.sayName(); //"Nicholas"16 person2.sayName(); //"Greg"17 18 console.log(person1.sayName == person2.sayName); //true

看起來問題好像解決了,兩個實例共享了全局的 sayName() ,但是這麼寫,卻帶來新的問題,如果某個類型需要相當多的自定義函數,而這些函數全都被定義為了全局函數,那麼這個類型還有什麼封裝性可言。

小熊吐槽JavaScript基礎教程,Are you OK?

小熊吐槽JavaScript基礎教程,Are you OK?

歡迎大家在下方積極吐槽,小編會一一進行查看並回復,期待你的答案哦……

如果喜歡請轉發,小小支持一下。


分享到:


相關文章: