在JavaScript建立對象(三)——原型模式中,咱們闡述了原型模式存在的兩個問題:一是沒辦法經過構造函數初始化對象屬性,二是共享引用類型的數據致使數據錯亂。因而咱們提出組合使用兩種模式,摒棄它們的缺點,保留它們的優勢。javascript
爲了解決構造函數模式相同功能的函數定義屢次的問題,咱們提出了原型模式。可是不要忘記,構造函數模式也具有原型模式所缺少的優勢,好比能夠經過構造函數初始化對象的屬性,同時也沒有共享引用類型的數據錯亂問題。既然咱們提出原型模式是爲了解決構造函數模式的函數問題,那爲何咱們不僅把函數定義在原型中,屬性依然保留在構造函數中呢?順着這個思路,咱們來看下面的代碼:java
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ['小明', '小剛']; } Person.prototype = { constructor: Person, sayName: function(){ console.log(this.name); } } var p1 = new Person('張三', 18, 'JavaScript'); var p2 = new Person('李四', 20, 'Java'); p1.friends.push('小紅'); console.log(p1.friends);//["小明", "小剛", "小紅"] console.log(p2.friends);//["小明", "小剛"] console.log(p1.friends === p2.friends);//false console.log(p1.sayName === p2.sayName);//true
仍是原來的例子,只不過把一些不須要共享的屬性保留在構造函數中,須要共享的屬性定義在原型中,這就是組合使用構造函數和原型模式。咱們能夠看到,首先能夠經過構造函數初始化對象屬性了。其次,由於屬性是定義在構造函數中,每次經過new
關鍵字建立對象都會執行一次構造函數,因此對於每一個對象來講就都有了屬於本身的屬性了。好比這裏,p1
的friends
新增了一個小紅,p2
的friends
並不會受到影響,由於它們是兩個數組。再者,一些須要共享的屬性依然定義在原型中,避免了重複定義,可謂是集兩種模式之長。數組
這種構造函數與原型集成的模式,是目前在JavaScript中使用最普遍、認同度最高的一種建立自定義類型的方法。能夠說,這是用來定義引用類型的一種默認模式。函數
本文參考《JavaScript高級程序設計(第3版)》this