首页 > JavaScript > JavaScript prototype原型对象
2009六月29

JavaScript prototype原型对象

在之前的《javascript 构造函数和方法》一文中,我们知道,用构造函数把方法赋予其实例化的对象这样的效率实在让人不敢恭维。如果那样的话,构造函数创建的每一个每一个对象都会有相同的方法属性的副本。

在JavaScript中,有一种更为有效的声明方法、常量及其他能被类所有对象共享的属性的方式,那就是prototype原型


一个对象的原型,是由创建并初始化该对象的构造函数定义的。在JavaScript中,所有的函数都具有prototype属性,它引用了一个对象。虽然原型对象在初始化时是空的,但是你在其中定义的任何属性都会被该构造函数创建的所有对象所继承。这也是JavaScript继承的实现原理。

在学习prototype(原型)的时候,我们首先要搞明白这样两个规则:
1. 使用原型可以大量减少每个对象对内存的需求量,因为对象可以继承许多属性。
2. 即使属性在对象被创建之后才被添加至原型中,对象也能够继承这些属性。

我们需要了解一下,原型里定义的属性,不是简单的被实例化的对象复制过去的,只是看起来好像是这些对象的属性了,这是很重要的概念。

看一个实例来理解一下:

                //创建一个构造函数 “用户”
        function User(name)
        {
            this.name = name;
        }
       
        //实例化一个用户——>老张
        var 老张 = new User('老张');
       
        //弹窗显示老张的名字
        alert(老张.name);
       
        //定义原型,注意这里对象“老张”已经被实例化了
        User.prototype.favchannel = 'CCAV';
       
        //弹窗显示老张最喜欢的电视台
        alert(老张.favchannel);

虽然“老张”这个对象已经被实例化出来了,不过其仍然会继承原型定义的“最喜欢的频道”这个属性

注意,只有读属性的时候才会使用prototype,写属性的时候是不会用到prototype的。

首先我们来详细了解一下,什么时候会用到prototype。当读一个对象的属性时,其寻找这个属性的顺序是怎样的呢?例如:读取老张的favchannel属性:

第一步:去问老张,你有没有啥喜欢的频道啊? 老张如果有的话就是:嗯呐,我喜欢CCAV,如果没有就说我不知道啊,问我老大吧,他说我喜欢啥,俺就喜欢啥。

第二步:问老张的构造函数的原型,如果原型内定义了,就会告诉你,我的小弟都喜欢CCAV,除非有的非常有个性可能喜欢某岛国的小电影频道。如果原型内也没定义,就会告诉你,去找我们经理,经理知道。

第三步:去问经理,即Object的prototype,如果经理说他们一般都喜欢CCAV,那么就是CCAV,如果经理也不知道,那就返回undefined。

所以顺序是 老张——>User prototype——>Object prototype

那么为啥写属性的时候不用prototype呢?举个例子你就清楚了

        //老李是一个新的用户
        var 老李 = new User('老李');
       
        //老李喜欢小电影
        老李.favchannel = 'JAPANTV';
       
        //弹窗显示JAPANTV
        alert(老李.favchannel);

        //弹窗显示老张还是中意CCAV
        alert(老张.favchannel);

如果,写属性也去改prototype的时候,那改变其中任何一个对象的属性,比如老李现在得意JAPANTV,如果也去改原型的话,老张也只能得意JAPANTV了。。

上面我们已经了解了,属性的继承(从原型处继承)只发生在读属性时。另外,原型对象的属性被一个类的所有对象共享,所以通常只用它们来定义类中所有对象相同的属性。例如我们可以定义“圆”这个类的PI值为1.34。

文章作者:simaopig
本文地址:http://www.xiaoxiaozi.com/2009/06/29/995/
版权所有 © 转载时必须以链接形式注明作者和原始出处!

9 Responses to “JavaScript prototype原型对象”

  1. #1 bolo 回复 | 引用 Post:2009-06-29 15:52

    你翻书真快,怎么他们不去得意JAPANAV呢?

    [回复]

  2. #2 simaopig 回复 | 引用 Post:2009-06-29 15:54

    @bolo
    呃。。因为CCAV强大,不会被河蟹吃掉。嗯。

    [回复]

  3. #3 Estoremap 回复 | 引用 Post:2009-06-29 16:24

    我来了,哈哈,技术派

    [回复]

  4. #4 simaopig 回复 | 引用 Post:2009-06-29 16:28

    @Estoremap
    哈,欢迎。。有空常来玩。呵。

    [回复]

  5. #5 tomheng 回复 | 引用 Post:2010-11-04 21:51

    这次是Google来的,呵呵

    [回复]

  6. #6 simaopig 回复 | 引用 Post:2010-11-05 15:44

    @tomheng
    呵呵,谢谢。原来Google还是能搜到我这里啊?呵。

    [回复]

  7. #7 andy 回复 | 引用 Post:2011-09-17 16:39

    Thank you.
    关于JS的原型讲的很形象。不过对于所说的读属性和写属性还不是非常明白。。。

    [回复]

  8. #8 kevin 回复 | 引用 Post:2011-11-25 12:11

    nice 2 :lol:

    [回复]

  9. #9 世纪之光 回复 | 引用 Post:2011-12-06 09:54

    原型应该叫做“类的原型”或者“构造函数的原型”更合理,而不是对象的原型。
    个人觉得写操作完全是给实例化的对象自身添加了一个属性,如果对象本身就存在这个属性,那原型中同名属性也被覆盖了,所以写操作跟原型没啥关系了。

    [回复]

发表评论

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)