之前我们已经学过了原型如何使用,那么现在我们介绍一种简单原型的使用方式:即直接通过对象字面量来重写整个原型对象(这种方法会改变原型对象的构造器)
function Person(){
}
Person.prototype = {
name : "z3",
age : 20,
job : "程序员",
say : function(){
console.info("我是原型的函数!");
}
};
var p1 = new Person();
p1.say();
console.info(p1.constructor); //Object
console.info(p1.constructor === Person); //false 此处的构造方法已经不是Person()了
可以在简单原型对象中使用constructor属性重新设置指向原来的构造函数
function Person(){
}
Person.prototype = {
constructor: Person,
name : "z3",
age : 20,
job : "程序员",
say : function(){
console.info("我是原型的函数!");
}
};
var p1 = new Person();
p1.say();
console.info(p1.constructor); //Person
console.info(p1.constructor === Person); //true
以上代码虽然可以使用原型的constructor属性重新指回Person()构造函数,但是存在一个新的问题,constructor属性可以被枚举了
//通过在简单原型对象中添加constructor属性指向Person的方式会导致constructor会被枚举出来。如果严格来说是不允许枚举出来的
for(var attr in p1){
console.info(attr);
}
在ECMAScript5中新增了Object.defineProperty()方法,通过此方法能够将属性添加到对象或修改现有属性的特性。
function Person(){
}
Person.prototype = {
name : "z3",
age : 20,
job : "程序员",
say : function(){
console.info("我是原型的函数!");
}
};
//使用ECMAScript5中的新方法为Person的原型对象增加constructor属性
//三个参数
// 参数一:要设置属性或方法的对象
// 参数二:要设置的属性或方法名称
// 参数三:属性或方法的值及相关属性
Object.defineProperty(Person.prototype, "constructor", {
enumerable: false,
value: Person
});
var p1 = new Person();
p1.say();
console.info(p1.constructor); //Person
console.info(p1.constructor === Person); //false
//constructor不会被枚举出来
for(var attr in p1){
console.info(attr);
}
原型的动态性
不使用简单原型的方式:
function Person(){
}
var p = new Person();
//使用这种方式不会引起Person的构造方法变为Object
Person.prototype.say = function(){
console.info("我是原型的方法!");
}
p.say(); //正常使用
使用简单原型的方式:
function Person(){
}
var p = new Person();
Person.prototype = {
constructor: Person,
say: function(){
console.info("我是原型的方法!");
}
};
//p.say(); //错误 Uncaught TypeError: undefined is not a function
以上这段代码使用了简单原型后会产生错误,具体分析如下:
1、执行到var p = new Person()时实例对象p中指向Person的原型对象
2、通过简单原型重写Person的原型对象后,实例对象p中指向的还是原来的Person的原型对象
3、当执行到p.say()语句时p所指向的原型对象中并没有say()方法
注意在使用时的顺序:通过简单原型的方式设置原型对象时,实例对象的定义要在设置完原型对象之后
function Person(){
}
Person.prototype = {
constructor: Person,
say: function(){
console.info("我是原型的方法!");
}
};
var p = new Person();
p.say(); //正常使用