JS的构造函数模式

原型模式

在JS中,每一个函数被定义之后,就会为这个函数创建一个prototype属性,该属性指向了这个函数的原型对象。

那原型对象能在对象的构造中发挥多大的作用呢?先看一个例子

function Person(){
    this.name = 'Tom';
    this.age = 22;
    this.sayHi = function(){
        console.log('Hello');
    }
}

let personA = new Person();
let personB = new Person();

console.log(personA.sayHi === personB.sayHi);   //false

可以看到创建的两个person对象的sayHi方法是不一样的,这就意味着每一次Person类的实例被创建都要重新创建一遍sayHi方法,这十分浪费时间跟空间。

而引入原型对象之后,就可以比较好的解决这个问题。

function Person(){
    this.name = 'Tom';
    this.age = 22;
}

Person.prototype.sayHi = function(){
    console.log('Hello');
};

let personA = new Person();
let personB = new Person();

console.log(personA.sayHi === personB.sayHi);   //true

通过原型对象可以在多个实例之间共享一些属性而不必重复创建。

然而使用原型对象也会存在问题,如下面的例子

function Person(){
    this.name = 'Tom';
    this.age = 22;
}

Person.prototype={
    constructor: Person,
    friends: []
};

let personA = new Person();
let personB = new Person();

personA.friends.push('Paul');
console.log(personB.friends);   //['Paul']

在原型中定义了一个friends数组,我用personA来访问friends数组并往里添加了一个’Paul’。然而,在访问personB的friends数组的时候,发现也有’Paul’。

这是因为原型对象解决的就是一个共享的问题,然而成也共享,败也共享。原型对象可能会让一些不需要实例间共享的属性被共享。

解决方法也很简单,只要我们不把不想被共享的属性放进原型对象里就可以了。

动态原型模式

把构造方法和原型对象分开写可能不够优雅,那么动态原型模式就是一种较为优雅的解决方案。

function Person(name, age){
    this.name = name;
    this.age = age;
    
    if(typeof this.saiHi != 'Function'){
        Person.prototype.sayHi = function(){
            console.log('Hello');
        }
    }
}

这个构造函数仅会在第一次调用的时候设置原型对象,因为第一次设置完了之后原型对象上就有了sayHi这个方法。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值