网络编程
位置:首页>> 网络编程>> JavaScript>> [翻译]JavaScript中对象的层次与继承(7)

[翻译]JavaScript中对象的层次与继承(7)

作者:chenzhe 来源:chenzhe 发布时间:2008-12-31 13:36:00 

标签:类,对象,继承,javascript,编程


又见属性继承

上一部分描述了在JavaScript中,构造器和原型是如何提供层次和继承的。就像在所有的语言中一样,在之前的讨论中有一些细微之处还没有能够充分地暴露(not necessarily apparent)。而这一部分就来讨论这些细微之处中的几个。

本地值和继承的值

我们再来概括地看看属性的继承。正如在之前讨论的,当你访问一个对象的属性,JavaScript进行如下几步:

    * 查看是否存在本地值。如果存在,返回那个值。
    * 如果不存在本地值,检查原型链(使用__proto__属性)。
    * 如果在原型链中的某一个对象有该属性值,则返回那个值。
    * 如果没有找到这个属性,说明这个对象没有这个属性值。

这一些列简单步骤的结果取决与你是如何在原型链上(along the way)定义对象的。在我们原来的例子中,我们有如下定义:

程序代码

function  Employee () {
  this.name = "";
  this.dept =  "general";
}

function  WorkerBee () {
  this.projects = [];
}
WorkerBee.prototype  = new Employee;

根据如上定义,假设你创建一个WorkerBee的实例amy,语句如下:

程序代码

amy = new  WorkerBee;

amy对象有一个本地的属性,projects。name和dept属性的值并不是amy本地的,是从amy对象的__proto__属性取得的。所以,amy拥有如下属性:

程序代码

amy.name ==  "";
amy.dept = "general";
amy.projects ==  [];

现在假设你改变了关联到Employee的原型的name属性的值:

程序代码

Employee.prototype.name  = "Unknown"

第一眼看来,你可能认为新的属性值会传递(propagate)到所有Employee的实例。然而,它却没有。

当你创建任何的Employee 对象的时候,那个实例就会为name属性取得一个本地的值(空字符串)。这意味着当你设置WorkerBee的原型为一个新建的Employee对象的时候,WorkerBee.prototype的name属性有一个本地的值。所以,当JavaScript查找amy对象(WorkerBee的一个实例)的name属性的时候,JavaScript在 WorkerBee.prototype中找到了name属性的值。所以它不会进一步顺着原型链访问Employee.prototype。

如果你想要在运行时改变改变对象的属性,并且让这个属性的新值被所有的该对象后代所继承,你就不能在对象的构造函数中定义这个属性。相反,你要将它添加在于构造函数向关联的原型上。例如,假设你将上面的代码修改如下:

程序代码

function  Employee () {
  this.dept =  "general";
}
Employee.prototype.name = "";

function  WorkerBee () {
  this.projects = [];
}
WorkerBee.prototype  = new Employee;
amy = new  WorkerBee;
Employee.prototype.name  = "Unknown";

在这种情况下,amy对象的name属性就变成了"Unknown"。

就像这些例子展示的,如果你想要让对象的属性有默认值,而且又希望可以在运行时改变这个默认值,你就应该在构造器的原型中设置这个属性,而不是在构造函数中。

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com