简体   繁体   中英

Trying to understand this code in Javascript

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

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

In the above, I don't understand why the author used this statement

EarthApp.prototype = new Sim.App();

He could have used

EarthApp = new Sim.App();

Please help me understand the use of 'prototype' within that statement .

The line

EarthApp.prototype = new Sim.App();

...creates a Sim.App object and assigns it to the prototype property of the EarthApp function. That means that when we do this:

var e = new EarthApp();

...the e object will get the object from EarthApp.prototype as its prototype, giving it access to the properties and methods of that object.


FWIW, the inheritance implemented by that code isn't really ideal, because it's calling the Sim.App constructor to create the EarthApp.prototype object, then calling it again to initialize instances. If you want to chain constructors together in that way, here's the more correct way to do it:

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

You might want to check out my Lineage helper script, which does the above and handles all the plumbing required to handle "supercalls" correctly and such.

It's also worth noting that this is just one way to use JavaScript's prototypical inheritance, which is tremendously flexible.

Prototypes are a fundamental piece in Javascript's inheritance model. I recommend you read about it, because without understading it you'll not "get" JS fully.

Having that said, assinging an object as a function's prototype makes this object be in a prototype chain of every instance of this function created afterwards.

The way prototype chain works is (more or less) (see example below):

  1. You try to access "foo" variable in an object
  2. If this object have "foo", return it's value.
  3. If this object does not have "foo", look at it's prototype ('Sim.App' instance in your case) - does it have "foo"? If so, return it's value.
  4. If object's prototype does not have a "foo", look at prototype's prototype - and so on, up through the chain.

If you want to read more on that, have a look at this article .

Example - consider:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM