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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章