之前我们已经学过了原型如何使用,那么现在我们介绍一种简单原型的使用方式:即直接通过对象字面量来重写整个原型对象(这种方法会改变原型对象的构造器)
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(); //正常使用