如何在Javascript中交叉引用类

时间:2012-07-09 08:32:55

标签: javascript module design-patterns cross-reference

是否有一种方法可以从不同的命名空间交叉引用类或实例变量的实例,同时考虑到主html应用程序中定义的脚本文件的顺序很重要。实际上我想知道是否有可能交叉引用两个不同的类实例,一个指向在不同命名空间中定义的引用,另一个在第二个类中定义的另一个指向第一个类。

假设我有一个 main.js 文件,我在其中定义一个类,该类使用在另一个名称空间中定义的一些实例变量,让我们说 particle.js ,同时我定义一个指向Main类公共变量的变量。     

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

...并在*.html javascript文件顺序为:

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

实际上,如果您在firebug上尝试使用此代码,则该代码正常工作,但在我的实际应用程序上使用相同的逻辑,这非常复杂,我在控制台中出现Main is undefined错误。我知道使用带有Require.js的AMD模拟真实类模块是可能的,但我现在不想在AMD上转发。

1 个答案:

答案 0 :(得分:2)

我无法让您的代码在Chrome或Firefox上运行,我总是在Main.width上收到错误。

问题是当你的Main尚未完全构建时,你会引用Main inside particle。

没有直接的解决方案,我可以认为最好的是在定义Particle类之后推迟部分主要单例的初始化。 或者,您也可以重新排序代码以尊重依赖关系。

你必须记住,在javascript中,你的代码在你调用它时会被评估。

以下是我的两个提案:

解决方案1 ​​:部分延迟主要初始化

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

解决方案2 :拆分为3个文件以尊重依赖关系

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