如何使用requireJS访问模块变量?

10

我使用Javascript已经有一段时间了,刚刚尝试使用模块和requireJS,但是新的设计模式让我很难理解!

这是我的第一次尝试:

require([
    "jquery",
    "testModule"
], function ($, testModule) {
    $(function () {
        var testInstance1 = testModule;
        testInstance1.setID(11);
        alert(testInstance1.id);
    });
});

和testModule.js

define([
  'jquery'
], function ($) {

    var id = 0;

    var setID = function (newID) {
        id = newID;
        return id;
    };
    return {
        setID: setID,
        id:id
    };
});

这返回了0,我期望的是11。我错过了什么吗?

当然,这也是一个简化示例。我想创建多个对象,每个对象都应保持其自身变量的状态。例如,如果我想要创建一个模块来将列表附加到容器DIV中,但还包含添加、清除或查询该列表数据的函数,我应该如何构建模块函数以使每个实现保持其自己的状态。

谢谢

2个回答

6
你在这里实际上并没有遗漏任何与 requireJS 相关的内容。问题在于,只有对象(也许还有数组,现在记不太清了)是以引用方式传递的,而数字则不是。因此,当你返回 {setID: setID, id: id} 时,'id' 被设置为 'id' 的值,再也不会被更新。你需要做的是使用一个名为 'getID' 的函数,它将引用原始变量而非原始变量的值:
return {
    setID: setID,
    getID: function () {return id;}
};

and then...

testInstance1.setID(11);
alert(testInstance1.getID());

1
感谢您的帮助。这个代码在创建一个实例时是有效的。但是当我尝试创建两个实例时,就会出现问题。以下是代码:'var testInstance1 = testModule; testInstance1.setID(11);var testInstance2 = testModule; testInstance2.setID(99); alert(testInstance2.getID()); alert(testInstance1.getID());'两个弹窗都会显示 99。 - user759885
1
嗯,你正在更改同一变量.. 你可能需要比你现有的更复杂的结构,例如拥有一个“testModule.createInstance()”。 - Stephen
Stephen,你的回答真的帮我很好地理解了RequireJS模块。我无法感谢你的足够之道。 - zacharydl

3
如果您想要有两个 testModule 实例,您需要将 testModule 返回为函数。然后当您 require 它时,可以使用 new 实例化多个实例。

示例1

testModule.js

define([
  'jquery'
], function ($) {

    function TestModule() {
        var self = this;
        // anything attached to self or this will be public
        self.id = 0;
        self.setID = function (newID) {
            self.id = newID;
            return self.id;
        };
    }

    return TestModule;
});

main.js

require([
    "jquery",
    "testModule"
], function ($, TestModule) {
    $(function () {
        var testInstance1 = new TestModule();
        var testInstance2 = new TestModule();
        testInstance1.setID(11);
        testInstance2.setID(99);
        alert(testInstance1.id); // Should return 11
        alert(testInstance2.id); // Should return 99
    });
});

如果你想要更加高级,你可以保护testModule内的某些属性或函数。

示例2

testModule.js

define([
  'jquery'
], function ($) {

    function TestModule() {
        var self = this;
        var privateID = 0;
        function privateToString() {
            return 'Your id is ' + privateID;
        }
        // anything attached to self or this will be public
        self.setID = function (newID) {
            privateID = newID;
        };
        self.getID = function () {
            return privateID;
        };
        self.toString = function () {
            return privateToString();
        };
    }

    return TestModule;
});

main.js

    require([
        "jquery",
        "testModule"
    ], function ($, TestModule) {
        $(function () {
            var testInstance1 = new TestModule();
            var testInstance2 = new TestModule();
            testInstance1.setID(11);
            testInstance2.setID(99);
            alert(testInstance1.getID()); // Should return 11
            alert(testInstance2.getID()); // Should return 99
            alert(testInstance1.privateID); // Undefined
            alert(testInstance1.toString()); // Should return "Your id is 11"
        });
    });

如果您只需要单个实例,比如一个单例,您可以使用new关键字返回TestModule。

示例3

testModule.js

define([
  'jquery'
], function ($) {

    function TestModule() {
        var self = this;
        // anything attached to self or this will be public
        self.id = 0;
        self.setID = function (newID) {
            self.id = newID;
            return self.id;
        };
    }

    return new TestModule();
});

main.js

require([
    "jquery",
    "testModule"
], function ($, testModule) {
    $(function () {
        var testInstance1 = testModule;
        var testInstance2 = testModule;
        testInstance1.setID(11);
        testInstance2.setID(99);
        alert(testInstance1.id); // Should return 99
        alert(testInstance2.id); // Should return 99
    });
});

太棒了,这真的让我对RequireJS有了更深入的了解。我对NodeJS模块是面向对象的感到舒适,但我需要在RequireJS中看到这一点。谢谢。 - Dr.YSG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接