JavaScript中创建对象的方法(中)

来源:互联网 发布:9wifi九维网络客服 编辑:程序博客网 时间:2024/05/22 14:12

  我们在上篇说到了工厂模式和构造函数模式,结尾说到解决构造函数模式的缺点的方法是引入了原型模式,本篇就来说说原型模式及其与构造函数模式的组合使用。

一、原型模式

    首先要理解:我们创建的每一个函数都有一个prototype(原型)属性,该属性是一个指针,指向一个对象,该对象的用途就是包含特定类型所有实例共享的属性和方法。
    举个例子: 我们定义一个构造函数Person;那么他的prototype属性所指的对象包含着所有Person的实例所共享的属性和方法;且该对象就是Person所有实例的原型对象
    使用原型的好处是:所有实例可以共享原型对象中的属性和方法;举例如下:
    function Person() {    }    Person.prototype.name = 'Jack';    Person.prototype.friends = ['Lily', 'John'];    var person1 = new Person();    var person2 = new Person();    console.log(person1.name);//Jack    console.log(person2.name);//Jack

   由于person1和person2都是Person的实例,所以都能访问他们共同的原型对象上的name属性。

   然而,原型模式也有缺点,继续上边的代码执行以下代码:

    person1.friends.push('Lucy');    console.log(person1.friends);//["Lily", "John", "Lucy"]    console.log(person2.friends);//["Lily", "John", "Lucy"]

   由于friends属性定义在原型对象上,所以一旦改变,所有实例都会改变,显然实际中这不是我们期望的,我们希望各自的friends属性互不影响;为解决这一问题,我们采用了原型模式和构造函数的组合使用;

二、组合使用原型模式和构造函数模式

    继续上边的例子,我们将实例需要独自拥有的属性或方法定义在构造函数里边,将共享的属性或者方法定义在原型对象中,举例如下:

    function Person(name) {        this.name=name;        this.friends=['Jack'];    }    Person.prototype.sayName=function(){        console.log(this.name);    };    var person1 = new Person('Alice');    var person2 = new Person('Bob');    person1.sayName();//Alice    person2.sayName();//Bob    person1.friends.push('Lucy');    console.log(person1.friends);//["Jack", "Lucy"]    console.log(person2.friends);//["Jack"]

    可以看到,构造函数里边的name和friends属性各实例分别拥有自己的一份,不会互相干扰,sayName方法所有实例共享。


0 0
原创粉丝点击