22_面向对象程序设计(原型【五】简单原型的使用

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

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(); //正常使用

你可能感兴趣的:(原型的动态性,简单原型)