javascript之prototype学习笔记


首先,Javascript中每个对象都有prototype属性,他是用来返回对象类 型原型的引用的。我们使用prototype属性提供对象的类的一组基本功能。并且对象的新实例会"继承"赋予该对象原型的操作。但是这个 prototype到底是怎么实现和被管理的呢?
对于对象的prototype属性的说明,Javascript手册上如是说:所有 Javascript内部对象都有只读的 prototype 属性。可以向其原型中动态添加功能(属性和方法),但该对象不能被赋予不同的原型。然而,用户定义的对象可以被赋给新的原型。
下面我们看三个经典的prototype属性的使用示例。

  1. 为脚本环境内建对象添加方法
    Array.prototype.max = function()
    {
    var i,max = this[0];
    for(i=0; i<this.length; i++)
    {
    if (max<this[i])
    max = this[i];
    }
    return max;
    }

  2. 为用户自定义类添加方法
    function SkyObject(name)
    {
    this._name=name;
    }
    SkyObject.prototype.ShowName=function()
    {
    alert(this._name);
    }

  3. 更新自定义类的prototype
    function SkyTestA()
    {
    this.MethodA = function()
    {
    alert("SkyTestA.MethodA()");
    }
    }
    function SkyTestB()
    {
    this.MethodB = function()
    {
    alert("SkyTestB.MethodB()");
    }
    }
    SkyTestB.prototype = new SkyTestA();


第三个使用了继承(原型继承,另外还有构造继承,调用继承等),SkyTestB继承了SkyTestA的方法。
prototype 还有一个默认的属性:constructor,是用来表示创建对象的函数的(即我们OOP里说的构造函数)。constructor属性是所有具有 prototype属性的对象的成员。它们包括除Global和Math对象以外的所有Javascript内部对象。constructor属性保存了 对构造特定对象实例的函数的引用。
弄清楚了Javascript中prototype属性怎么使用后,下面我们再来深入的研究它。
Javascript实际上是使用了我们设计模式中prototype pattern的一种衍生形式。下面我先简单的说一下prototype pattern,然后再来看到底JScript中的prototype是怎么回事?!
What's prototype pattern?
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
下面我们继续说Javascript里的prototype,为什么我们说它和prototype pattern里的prototype不一样呢?! 继续看示例:
function RP()
{
RP.PropertyA = 1;
RP.MethodA = function()
{
alert("RP.MethodA()");
}
this.PropertyA = 100;
this.MethodA = function()
{
alert("this.MethodA()");
}
}
RP.prototype.PropertyA = 10;
RP.prototype.MethodA = function()
{
alert("RP.prototype.MethodA()");
}
RP是ResearchPrototype,看示例及结果分析:
程序代码:
<script type="text/javascript">
var rp = new RP();
alert(RP.PropertyA);
RP.MethodA();
alert(rp.PropertyA);
rp.MethodA();
</script>
运行结果:
1
RP.MethodA
100
this.MethodA
继续
程序代码:
<script type="text/javascript">
var rp=new RP();
delete RP.prototype.PropertyA;
alert(RP.prototype.PropertyA);
delete RP.prototype.MethodA;
RP.prototype.MethodA();
delete rp.PropertyA;
alert(rp.PropertyA);
delete rp.MethodA;
rp.MethodA();
</script>
运行结果:
undefined
对象不支持此属性或方法
RP.prototype.MethodA();
再来
程序代码:
<script type="text/javascript">
var rp=new RP();
delete rp.PropertyA;
alert(rp.PropertyA);
delete rp.MethodA;
rp.MethodA();
</script>
运行结果:
10
RP.Prototype.MethodA()
这里的RP.PropertyA和RP.MethodA只是用来做参照的,可是怎么把this.PropertyA和this.MethodA都delete了,还能出来结果,而且还是prototype导入的属性和方法呢?
这 就是Javascript的prototype和prototype pattern中prototype最大的不同了,Javascript中的这个所谓的prototype属性其实是个语言本身支持的特性,这里没有发生 任何的copy,不管shallow还是deep的。对于Javascript的解释引擎,它在处理"."或"[keyName]"引用的对象的属性和方 法时,先在对象本身的实例(this)中查找,如果找到就返回或执行。如果没有查找到,就查找对象的 prototype(this.constructor.prototype)里是否定义了被查找的对象和方法,如果找到就返回或执行,如果没有查找到, 就返回undefined(对于属性)或runtime error(对于方法)。
正因为prototype导入类实例的属性或方法是动态查找的,所以我们才能对系统内部对象添加prototype属性和方法,比如给String对象添加trim方法:
程序代码:
String.prototype.trim()
{
return this.replace(/(^s+)|(s+$)/g, "");
}
显然Javascript中的这种用法也是prototype pattern中的prototype不能解释和支持的。

Need a translation service?

Please enter your personal details and we will contact you shortly

Words translated by CCJK

146,096,379

We are Certified

Our Client Satisfaction

rating for previous quarte

4.00

Over 95% of our clients recommend our language services to others

Copyright © CCJK Technologies Co., Ltd. 2000-2017. All rights reserved.
TOP