js面向對象4--原型模式的不足以及頂級模式的出現

<%@ page language="java" contentType="text/html;
charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<script type="text/javascript">

/*
JavaScript原型模式已經帶來的弊端以及這個弊端的解決辦法:
一句話概述弊端: 原型對象中的引用類型因爲共享,修改了就修改了全部實例。
而又的時候我們僅僅是想每個實例有每個實例的引用類型,所以就出現了問題。

原型模式也並不是沒有缺點的,首先,它省略了爲構造函數傳遞參數的這一環節,
結果所有實例在默認情況下將取得所有相同的屬性值,雖然這會在某種程度上
帶來一些不方便,但還不是原型的最大的問題,原型模式的最大問題是由其共享
的本性所導致的。
原型中所有屬性是被實例共享的,這種共享對於函數非常適合,對於那些包含基本值的屬性
倒也說得過去,畢竟,通過在實例上添加一個同名屬性,可以隱蔽原型中的對應屬性。然而
,對於包含引用類型值得屬性來說,問題就比較突出了,來看如下例子:
*/
function Person(){}
Person.prototype = {
constructor:Person, //應該知道這種寫法帶來的問題,已經過,不在贅述
name : "chenchaoyang",
age:12,
job : "Software enginner",
friends :["何勝男","何凱"],
sayName : function(){
console.log(this.name);
}
}

function onloadFunction(){
var person1 = new Person();
var person2 = new Person();

person1.friends.push("張三");

person1.friends = ["3333","34444"];

alert(person1.friends); //何勝男,何凱,張三
alert(person2.friends); //何勝男,何凱,張三
alert(person1.friends == person2.friends); //true
}

/*
因爲friends屬性存在於Person的prototype對象中,所以修改了person1
的friends屬性,person2的friends同樣就行了修改,因爲他們是共享了一個
friends屬性,假如我們的初衷就是像這樣在所有實例中共享一個數組,那麼
對這個結果我沒有話可說,可是,實例一般都是要有屬於自己的全部屬性的,而這個
問題正是我們很少看到有人單獨使用原型模式的原因所在。
於是一個我們比較常見的,最實用的使用的模式出現了,這個模式也是我們的頂級模式:
*/

/*
創建自定義類型的最常見方式,就是組合模式 = 構造模式 + 原型模式。
構造模式用來: 定義實例屬性
原型模式用來:定義共享的屬性
這樣,每個實例都會有自己的一份實例屬性的副本,但同時又共享着對象的引用,最大限度
的節省了內存。另外,這種混合模式還支持向構造函數傳遞參數,可謂是集兩種模式之長。
下面代碼重寫了前面的例子,是JavaScript創建對象的頂級模式,一定要牢記:
*/
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["何勝男","何凱"];
}

Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}

function onloadFunction(){
var person1 = new Person("chenchaoyang",27,"Software Enginner");
var person2 = new Person("heshengnan",23,"Software Enginner");

person1.friends.push("zhagnsan");

console.log(person1.friends); // ["何勝男", "何凱", "zhagnsan"]
console.log(person2.friends); // ["何勝男", "何凱"]

console.log(person1.friends == person2.friends); //false
console.log(person1.sayName == person2.sayName); //true

console.log(person1.constructor); // Person(name, age, job)
console.log(person2.constructor); //Person(name, age, job)

console.log(person1 instanceof Object); //true
console.log(person1 instanceof Person); //true

console.log(person2 instanceof Object); //true
console.log(person2 instanceof Person); //true
}

</script>

</head>

<body οnlοad="onloadFunction();">
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章