【转】prototype定义(的位置)写在构造函数内或外的区别 ?

第一种写法:

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
}
Person.prototype = {
    constructor: Person,
    getName: function(){
        return this.name;
    }
}

第二种写法:

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
    Person.prototype.getName = function(){
        return this.name;
    }
}

第二种写法每次创建实例都会执行一遍对prototype的操作!关键是这个操作很没意义,这个方法对每个实例都是相同的。
第一种方法中, 当prototype在构造函数外面书写时,可以从形式上和内存分配中解决重复定义或分配内存的问题。
对应在内存中,第一种写法,无论你创建了多少实例,每个实例占据空间只是name, age,job和lessons。getName在内存中只有一份,所有实例共用; 第二种写法,每个新创建的实例会分配一块额外的空间(栈)来执行prototype的定义。
prototype在第一种方法中赋值的方式和第二种方法有何区别?
区别很大的,一个function类定义好,它默认的 constructor属性就是自己, 它的实例在访问constructor属性时会返回这个值。

function Person() {};
console.log(Person.prototype.constructor);  // Person

var p = new Person();
console.log(p.constructor);   // Person    表示p的构造函数是Person类

方法1中为什么要定义constructor? 因为它给prototype重新赋值了,如果你不定义

constructor(Person.prototype = {getName: function() {}})

,那么上例中p.constructor返回值将是 Object, 即p的构造函数是Object,显然与事实不符。

方法1更明智的做法是不要重新给prototype赋值,只为prototype添加我们需要的属性getName, 改为

Person.prototype.getName = function() {return this.name;}

也就是第二种方法里的定义方法,这么写就不会覆盖prototype的默认属性。

来源:
关于js中组合使用构造函数模式和原型模式的写法

此条目发表在JavaScript分类目录。将固定链接加入收藏夹。

发表评论

邮箱地址不会被公开。 必填项已用*标注