js面向對象3--更簡單的原型模式已經帶來的問題以及解決辦法

<%@ page language="java" contentType="text/html;
charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<script type="text/javascript">
/*
更簡單的原型模式以及由此帶來的問題:
在本人博客“ js面向對象2--js中工廠模式的演化(重要,詳細)”中的原型模式
是最基本也最正確的原型模式的用法,但是每次都用Person.prototype.屬性名稱
來個原型模式添加方法和屬性未免太過繁瑣。
爲了減少不必要的輸入,也爲了從視覺上更好的封裝原型的功能,更常見的做法是用一個
包含所有屬性和方法的對象資源面來重寫這個原型對象,如下:
*/
//正常的原型寫法:
function Person(){}
Person.prototype.name = "chenchaoyang";
Person.prototype.age = 12;
Person.prototype.job = "Software enginner";
Person.prototype.sayName = function (){
alert(this.name);
}

var person1 = new Person();

//簡單的原型寫法
function Person(){}
Person.prototype = {
name:"chenchaoyang",
age:"12",
job:"Software enginner",
sayName:function(){
console.log(this.name);
}
}
var person2 = new Person();

function onloadFunction()
{
console.log(person1.constructor); //Person()
console.log(person2.constructor); //Object()
}

/*
在上面代碼,我們將Person.prototype 設置爲等於一個以對象字面量形式創建的
新對象,最終結果相同,但有一個例外,constructor屬性不再指向Person了。
原因:
每創建一個函數,就會同事創建它的prototype對象,這個對象也會自動獲得constructor
屬性。而我們在這裏使用的語法,本質上完全重寫了默認的prototype對象,因此constructor
屬性也就變成了新對象的constructor屬性(指向Object構造函數),不再指向Person函數,
此時儘管instanceof操作符還能返回正確的結果,但通過constructor已經無法確定對象
的類型了。

如果在編程過程中,一個對象的constructor值很重要,可以像下面這樣的方法去改寫:
*/
function Person(){}
Person.prototype = {
constructor : Person, //人爲的制定原型對象的構造函數指向
name : "chenchaoyang",
age :13,
sayName : function(){
alert(this.name);
}

}

/*
注意:以上面的方式重設constructor屬性會導致它[[Enumerable]]特性被設置爲true。默認
情況下,原聲constructor屬性是不可枚舉的,因此如果你使用兼容EcmAScript5的JavaScript
引擎,可以試一試Object.defineProperty().如下:
function Person(){}
Person.prototype = {
name : "chenchaoyang",
age : 12,
job : "Soft Enginner",
sayName : function(){
console.log(this.name);
}
//重寫原型對象的構造函數,只適用於ECMAScript5兼容的瀏覽器
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
})
}

此種模式堪稱完美。。。。。。。。。Over
*/
</script>

</head>

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