试图在Javascript中理解这段代码

时间:2013-10-15 07:33:12

标签: javascript inheritance

// Sim.App - application class (singleton)

    Sim.App = function()
    {   
        this.renderer = null;
        this.scene = null;
        this.camera = null;
        this.objects = [];
    }

    // Constructor
    EarthApp = function()
    {
        Sim.App.call(this);
    }

// Subclass Sim.App
EarthApp.prototype = new Sim.App();

=============================================

在上面,我不明白为什么作者使用了这个陈述

EarthApp.prototype = new Sim.App();

他本可以使用

EarthApp = new Sim.App();

请帮助我理解在该声明中使用'原型'。

2 个答案:

答案 0 :(得分:4)

该行

EarthApp.prototype = new Sim.App();

...创建一个Sim.App对象,并将其分配给prototype函数的EarthApp属性。这意味着当我们这样做时:

var e = new EarthApp();

... e对象将从EarthApp.prototype获取对象作为其原型,使其可以访问该对象的属性和方法。


FWIW,该代码实现的继承并不是很理想,因为它调用Sim.App构造函数来创建EarthApp.prototype对象,然后再次调用 来初始化实例。如果你想以这种方式将构造函数链接在一起,这是更正确的方法:

// Reusable `derive` function
// Set up `child`'s `prototype` property to be based on `parent`'s `prototype` property
function derive(child, parent)
{
    function ctor()
    {
    }

    ctor.prototype = parent.prototype;
    child.prototype = new ctor();
    child.prototype.constructor = parent;
}

// Sim.App - application class (singleton)
Sim.App = function()
{   
    this.renderer = null;
    this.scene = null;
    this.camera = null;
    this.objects = [];
};

// Constructor
EarthApp = function()
{
    Sim.App.call(this);
};

// Subclass Sim.App
derive(EarthApp, Sim.App);

您可能需要查看我的Lineage帮助程序脚本,它执行上述操作并处理正确处理“超级调用”所需的所有管道,等等。

值得注意的是,这只是使用JavaScript原型继承的一种方式,非常灵活。

答案 1 :(得分:4)

原型是Javascript继承模型的基础部分。我建议你阅读它,因为如果没有强调它,你就不会“完全”得到JS。

有了这个说法,将一个对象作为一个函数的原型,将这个对象放在后来创建的这个函数的每个实例的原型链中。

原型链的工作方式(或多或少)(见下面的例子):

  1. 您尝试访问对象中的“foo”变量
  2. 如果此对象具有“foo”,则返回其值。
  3. 如果此对象没有“foo”,请查看它的原型(在您的情况下为'Sim.App'实例) - 它是否有“foo”?如果是这样,请返回它的值。
  4. 如果对象的原型没有“f​​oo”,请查看原型的原型 - 依此类推,直到链。
  5. 如果您想了解更多信息,请查看at this article

    示例 - 考虑:

    var Sim = {};
    Sim.App = function () {
        this.foo = 'sim';
    }
    
    EarthApp = function () {
    }
    
    EarthApp.prototype = new Sim.App();
    
    var earth = new EarthApp();
    
    // I can access earth.foo even though 'earth' is an instance of 'EarthApp' 
    // and not 'Sim.App'. That's because instance of 'Sim.App' is in 
    // earth's prototype chain.
    console.log(earth.foo);