javascript中组合使用构造函数模式和原型模式创建对象

首先来讲一下构造函数创建对象。ECMAScript中的构造函数可用来创建特定类型的对象。请看下面示例了解一下构造函数模式:

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}

function sayName(){
    alert(this.name);
}

var person1 = new Person("Dawang", 22, "Softwaare Engineer");
var person2 = new Person("King", 23, "Doctor");

person1.sayName();//Dawang
alert(person1.constructor == Person);//true
alert(person2.constructor == Person);//true

从代码中可以看出,person1和person2的constructor都指向Person,这两个实例既是Person的实例,也是Object的实例。但是,使用构造函数的缺点是,每个方法都要在每个实例上重新创建一遍。在上面的示例中,person1和person2都有一个sayName()方法,但是这两个方法不是同一个Function的实例。因为ECMAScript中的函数是对象,因此每定义一个函数,也就是实例化了一个对象。创建两个完成同样任务的Function实例没有必要,所以,采用的方法就是像上述代码那样,将函数定义转移到构造函数外部来解决。这样,sayName包含了一个指向函数的指针,person1和person2对象就共享了在全局作用域中定义的同一个sayName()函数。
在全局作用域中定义的函数实际上只能被某个函数调用,如果对象需要定义很多方法,那就要定义很多个全局函数,我们自定义的引用类型就没有封装性可言了。这一点可以通过原型模式来解决,我的上一篇文章已经介绍过,原型模式也有缺点。因此,实际上创建自定义类型的最常见方式,就是组合使用构造函数模式和原型模式。
构造函数模式用于定义实力属性,而原型模式用于定义方法和共享的属性。这样,每个实例都会有自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度的节省了内存。这种混合模式还支持向构造函数传递参数,集合了两种模式之长。请看示例:

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Hongtao","Xiaosheng"];
}

Person.protytype = {
    constructor: Person,
    sayName: function(){
        alert(this.name);
    }
}

var person1 = new Person("Dawang", 22, "Softwaare Engineer");
var person2 = new Person("King", 23, "Doctor");

person1.friends.push("Huazi");
alert(person1.friends);//"Hongtao,Xiaosheng,Huazi"
alert(person2.friends);//"Hongtao,Xiaosheng"
alert(person1.friends === person2.friends);//false
alert(person1.sayName === person2.sayName);//true

从示例中可以看出,修改person1.friends并不会影响person2.friends,因为它们分别引用了不同的数组。
这种构造函数和原型模式混合的模式,是ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值