浅谈 OOP JavaScript [3] -- 原型

上一章咱们谈了构造函数,他的惟一特色就是比较了地址不相同,由于你们知道引用类型是比较的引用。咱们来谈谈原型。数组

原型函数

咱们每建立一个函数都有一个原型(prototype)属性,这个属性是一个对象,他的特色是共享。也就是说不用在构造函数中定义对象实例,而是直接将这些添加到原型当中。this

function Create () {}    //声明一个构造函数
Create.prototype.a = 'abc';    //在原型中添加属性
Create.prototype.b = 10;
Create.prototype.c = function () {    //在原型中添加方法
    return this.a + this.b;
};
var create = new Create();    
alert(create.c());    //返回abc10

咱们此次再来比较一下原型中方法的地址是否一致:spa

var create = new Create();
var create1 = new Create();
alert(create.c == create1.c);    //true

是否是还没明白?咱们用一张图来告诉你们:
原型prototype

这个__proto__就至关于指针,指向了原型对象的constructor,而constructor就至关于将构造函数对象和原型对象相关联。
那么咱们要用构造函数对象去给重写属性或者方法会怎么样呢?指针

var create = new Create();
create.a = 'EFD';
alert(create.a);    //返回EFD

真的将原型对象里面的a给覆盖了么?并无:code

var create1 = new Create();
alert(create.a);    //返回abc

原型模式的执行过程:对象

1.先去查找构造函数里面的属性和方法 ,若是有就当即返回。

2.若是构造函数实例里面没有,就去原型里面查找,若是有就当即返回。blog

由于咱们在构造函数添加了属性,因此它会自动去查找,构造函数里面的属性也就当即返回了!字符串

原型的字面量

在原型中,咱们也可使用字面量的方式去建立,可让属性和方法体现出更好的封装效果。

function Create(a,b){};    //声明一个构造函数
Create.prototype = {    //字面量方式
    a:'abc',
    b:10,
    c:function () {
        return this.a + this.b;
    }
};

不知道你们有没有发现,咱们用字面量的方式是这样的:Create.prototype ={};
你们都知道,用一个{}就等同于new Create();这样,咱们就至关于新声明的一个对象,咱们原型对象里面的constructor还会指向Create么?

var create = new Create();
alert(create.constructor == Create);    //false
alert(create.constructor == Object);    //true

(咱们来解释一下为何用create.constructor,由于咱们打印constructor就会将整个构造函数打印出来,由于上面讲过它是将构造函数对象和原型对象相关联的属性。)
经过上面的例子能够看出,它已经指向了新的实例对象。

constructor的巧妙用法:

咱们可使用constructor来强制指回原来的实例对象:

function Create(a,b){};
Create.prototype = {
    constructor:Create,
    a:'abc',
    b:10,
    c:function () {
        return this.a + this.b;
    }
};

原型对象的重写问题:

你们都知道,构造函数的属性和方法重写是无伤大雅的,可是原型对象中能够重写么?

function Create(a,b){};
Create.prototype = {
    constructor:Create,
    a:'abc',
    b:10,
    c:function () {
        return this.a + this.b;
    }
};

Create.prototype = {
    a:'EFD',
};
var create = new Create();
alert(create.c());    //create.c is not a function

不难看出,咱们重写了原型会将以前的原型指向切断!!!

原型模式的缺点:

其实它的缺点也是它优势:共享
咱们在字面量里面给原型对象添加一个数组就很容易的看出来了:

function Create(a,b){};
Create.prototype = {
    constructor:Create,
    a:'abc',
    b:10,
    c:[第一个,第二个,第三个],
    d:function () {
        return this.a + this.b + this.c;
    }
};
var create = new Create();
create.c.push('第四个');
alert(create.run());    //返回abc10第一个第二个第三个第四个

咱们看得出这时候push添加已经生效了,在数组的末尾添加了“第四个”

咱们再来实例一个对象就能看得出他的共享问题了:

var create1 = new Create();
alert(create1.run());    //返回abc10第一个第二个第三个第四个

这就是共享问题。下面新实例化一个对象也会将上面添加的字符串给共享到这里来。
这一章就到这里。欢迎全部阅读文章的人指正错误!

Brian Lee

相关文章
相关标签/搜索