Is there a way to cross-reference an instance of a class or an instance variable from different namespaces, taking into account that it does matter in which order are the script files defined in the main html application. Actually I want to know if there is any possibility to cross reference two different class instances, one pointing to a reference defined in a different namespace, and another variable defined in the second class pointing back to the first one.

Suppose i have a main.js file where i define a class which uses some instance variables defined in another namespace, let's say in particle.js, where at the same time i define a variable pointing back to Main class public variable.

var Main = (function() {
    var p = new Particle();

    this.draw = true;
    this.width = 800;
    this.height = 600;

    function print() {
        console.log(p.width, ':', p.height);
    }

    return {
        draw : this.draw,
        width : this.width,
        height : this.height,
        print : print
    }
})();

function Particle() {

    this.width = Main.width;
    this.height = Main.height;
    this.print = function() {
        console.log(this.width, ':', this.height);
    }    
}


var p = new Particle();
p.print();
Main.print();

...and in the *.html the javascript files order would be:

<script src = 'main.js'></script>
<script src = 'particle.js'></script>

Actually this code is working as expected if you try it on firebug for example, but on the same logic on my real application, which is much complex, i got Main is undefined error in console. I know it's possible to simulate real class modules using AMD with Require.js for example, but i don't want to relay on AMD right now.

有帮助吗?

解决方案

I did not manage to get your code work on Chrome or Firefox, i always get an error on Main.width.

The matter is that you refer to Main inside particle when you Main has not been fully constructed yet.

There is no straightforward solution, the best I can think is delaying part of the initialisation of your Main singleton after you defined the Particle class. Alternately you can also reorder your code to respect dependencies.

You have to remember that in javascript your code is evaluated when you call it.

Here are my two proposals:

Solution 1: Delay Main initialisation partly

// Main.js --> loaded first
var Main = new (function () {
    this.draw = true;
    this.width = 800;
    this.height = 600;

    // delayed initialization method
    this.init = function ()
    {
        var p = new Particle();
        this.print = function () {
            console.log(p.width, ':', p.height);
        }
    }
})();

//Particle.js --> loaded second
function Particle() {
    this.width = Main.width;
    this.height = Main.height;
    this.print = function() {
        console.log(this.width, ':', this.height);
    }    
}

// call the delayed init method
Main.init()

var p = new Particle();
p.print();
Main.print();

Solution 2: Split in 3 files to respect dependencies

//Particle.js --> loaded first
function Particle() {
    this.width = Main.width;
    this.height = Main.height;
    this.print = function() {
        console.log(this.width, ':', this.height);
    }    
}

// Main.js --> loaded in second position
var Main = (function() {
    var p = new Particle();
    this.draw = true;
    this.width = 800;
    this.height = 600;
    function print() {
        console.log(p.width, ':', p.height);
    }
    return {
        draw : this.draw,
        width : this.width,
        height : this.height,
        print : print
    }
})();

// Init.js --> loaded third
var p = new Particle();
p.print();
Main.print();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top