试图用Javascript理解此代码

试图用Javascript理解此代码,javascript,inheritance,Javascript,Inheritance,============================================= 在上面,我不明白作者为什么要用这句话 // Sim.App - application class (singleton) Sim.App = function() { this.renderer = null; this.scene = null; this.camera = null; this.objects =

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

在上面,我不明白作者为什么要用这句话

// 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();
…创建一个
Sim.App
对象,并将其分配给
EarthApp
函数的
prototype
属性。这意味着当我们这样做时:

EarthApp.prototype = new Sim.App();
e
对象将从
EarthApp.prototype
获取对象作为其原型,从而访问该对象的属性和方法


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

var e = new EarthApp();
您可能想查看my helper脚本,它执行上述操作,并处理正确处理“超级调用”等所需的所有管道

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

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

EarthApp.prototype = new Sim.App();
e
对象将从
EarthApp.prototype
获取对象作为其原型,从而访问该对象的属性和方法


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

var e = new EarthApp();
您可能想查看my helper脚本,它执行上述操作,并处理正确处理“超级调用”等所需的所有管道


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

原型是JavaScript继承模型的一个基本部分。我建议你读一读,因为如果不理解它,你就不会完全“理解”JS

话虽如此,将一个对象作为函数的原型进行分配会使该对象位于随后创建的该函数的每个实例的原型链中

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

  • 您尝试访问对象中的“foo”变量
  • 如果此对象有“foo”,则返回其值
  • 如果这个对象没有“foo”,那么看看它的原型(在你的例子中是“Sim.App”实例)——它有“foo”吗?如果是,返回它的值
  • 如果对象的原型没有“foo”,请查看原型的原型,以此类推,直到链的上游
  • 如果你想读更多关于这方面的内容,请看一看

    示例-考虑:

    // 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);
    

    原型是Javascript继承模型中的一个基本部分。我建议你读一读,因为如果不理解它,你就不会完全“理解”JS

    话虽如此,将一个对象作为函数的原型进行分配会使该对象位于随后创建的该函数的每个实例的原型链中

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

  • 您尝试访问对象中的“foo”变量
  • 如果此对象有“foo”,则返回其值
  • 如果这个对象没有“foo”,那么看看它的原型(在你的例子中是“Sim.App”实例)——它有“foo”吗?如果是,返回它的值
  • 如果对象的原型没有“foo”,请查看原型的原型,以此类推,直到链的上游
  • 如果你想读更多关于这方面的内容,请看一看

    示例-考虑:

    // 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);
    

    为什么
    console.log(earth.var)不应该是
    console.log(earth.prototype.var)?或者我遗漏了什么。@Nunners-不,
    earth.var
    是有效的-因为原型链的工作方式-查看我的更新答案。刚刚看到了,感谢额外的细节和澄清:)为什么
    console.log(earth.var)不应该是
    console.log(earth.prototype.var)?或者我遗漏了什么。@Nunners-不,
    earth.var
    是有效的-因为原型链的工作方式-查看我的更新答案。刚刚看到,感谢您提供的额外细节和说明:)