• 本地值和继承值。在访问一个对象的属性时,JavaScript 将执行下面的步骤:

    (1)检查本地值是否存在。如果存在,返回该值。
    (2)如果本地值不存在,检查原型链(通过 Proto属性)。
    (3)如果原型链中的某个对象具有指定属性的值,则返回该值。
    (4)如果这样的属性不存在,则对象没有该属性。

    • 判断实例的关系。JavaScript 的属性查找机制首先在对象自身的属性中查找,如果指定的属性名称没有找到,将在对象的特殊属性 proto 中查找。这个过程是递归的;被称为“在原型链中查找”。

    特殊的 proto 属性是在构建对象时设置的;设置为构造器的 prototype 属性的值。所以表达式 new Foo() 将创建一个对象,其 proto == Foo.prototype。因而,修改 Foo.prototype 的属性,将改变所有通过 new Foo() 创建的对象的属性的查找。
    每个对象都有一个 proto 对象属性(除了 Object);每个函数都有一个 prototype对象属性。因此,通过“原型继承”,对象与其它对象之间形成关系。通过比较对象的 proto 属性和函数的 prototype 属性可以检测对象的继承关系。JavaScript 提供了便捷方法:instanceof 操作符可以用来将一个对象和一个函数做检测,如果对象继承自函数的原型,则该操作符返回真。

    • JS不支持多重继承。某些面向对象语言支持多重继承。也就是说,对象可以从无关的多个父对象中继承属性和属性值。JavaScript 不支持多重继承。

    JavaScript 属性值的继承是在运行时通过检索对象的原型链来实现的。因为对象只有一个原型与之关联,所以 JavaScript 无法动态地从多个原型链中继承。
    在 JavaScript 中,可以在构造器函数中调用多个其它的构造器函数。这一点造成了多重继承的假象。例如,考虑如下语句:

    1. function Hobbyist (hobby) {
    2. this.hobby = hobby || "scuba";
    3. }
    4. function Engineer (name, projs, mach, hobby) {
    5. this.base1 = WorkerBee;
    6. this.base1(name, "engineering", projs);
    7. this.base2 = Hobbyist;
    8. this.base2(hobby);
    9. this.machine = mach || "";
    10. }
    11. Engineer.prototype = new WorkerBee;
    12. var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")

    进一步假设使用本章前面所属的 WorkerBee 的定义。此时 dennis 对象具有如下属性:

    1. dennis.name == "Doe, Dennis"
    2. dennis.dept == "engineering"
    3. dennis.projects == ["collabra"]
    4. dennis.machine == "hugo"
    5. dennis.hobby == "scuba"

    dennis 确实从 Hobbyist 构造器中获得了 hobby 属性。但是,假设添加了一个属性到 Hobbyist 构造器的原型:

    1. Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]

    dennis 对象不会继承这个新属性。