这是我对requirejs的第一次修补,我认为我有一个很好的处理,除了:为什么模块中定义的函数无法访问require()内的局部变量,我怎么能实现这个目标?
如果我们能够专注于这个问题并且 NOT 我使用eval(),更好或替代方法来定义test()或者可能存在的错字,我们将非常感激。下面的代码。
在全局命名空间中给出以下代码:
require(["test"], function(testModule) {
var test1 = testModule.test1;// same as local test()
var test2 = testModule.test2; // modified to work as module
//local function same as testModule.test1
function test (name, test){
return test+'='+eval(name+test);
}
//define class & instance for testing
var MyClass1 = function (name) {
this.name = name;
};
var mc1 = new MyClass1('instance 1');
var objName = 'mc1'
test(objName, '.name'); // works as expected
test1(objName, '.name'); // error: mc1 is not defined
test1.call(this, objName, '.name'); // error: mc1 is not defined
test2(mc1, objName+'.name'); // works as expected
})
和测试模块定义:
define({
test1: function (name, test){
return test+'='+eval(name+test);
},
test2: function (obj, test){
var parts = test.split('.');
parts[0] = 'obj';
test = parts.join('.');
return test+'='+eval(test);
}
});
问题:
part a)当我调用test1(objName,'。name')时,为什么它没有看到定义为var mc1 = new MyClass1('instance 1')的局部变量?
我知道这是出于好的原因而要保持全局命名空间的清洁,我只是不明白它怎么看不到它。 define()这指向与require()相同的命名空间。
b)如果我想让测试模块访问var mc1,我该怎么办呢?
答案 0 :(得分:1)
当我调用test1(objName,'。name')时,为什么它没有看到定义为var mc1 = new MyClass1('instance 1')的局部变量?
它们在不同的功能中定义。这也是为什么不起作用的原因:
function a() {
var hello = 'world'
b()
}
function b() {
alert(hello)
}
如果我想让测试模块访问var mc1,我该怎么办呢?
将定义更改为:
test1: function (name, test, mc1){ ... }
明确传递mc1变量:
test1(objName, '.name', mc1)
这与require.js无关,这是javascript的工作方式。
答案 1 :(得分:1)
如果我们忽略以下代码污染全局namesapce的事实,那么你在做什么在功能上等同于:
// This is the callback you passed to `require`. I've added a
// name to it.
function foo(testModule) {
var test1 = testModule.test1;// same as local test()
var test2 = testModule.test2; // modified to work as module
// ... etc... its all the same as your original code.
var mc1 = new MyClass1('instance 1');
// ... etc ...
}
// This is the module `test` that your `require` call was loading.
var test = {
test1: function (name, test){
return test+'='+eval(name+test);
},
test2: function (obj, test){
var parts = test.split('.');
parts[0] = 'obj';
test = parts.join('.');
return test+'='+eval(test);
}
};
// This is what happens when RequireJS executes your module.
foo(test);
我在上面对其进行重组的方式应该明确为什么你不能 访问函数闭包内的任何内容。
至于如何做你想做的事,你可以只将对象引用传递给你的函数。或者,如果您需要一次提供对多个对象的访问,或者想要更改符号所指的内容,则可以传递命名空间:
var ns = {
mc1: new MyClass1('instance 1'),
mc2: new MyClass1('instance 2'),
// ...
};
test(ns, "mc1", ...);
这样做,test
可以根据需要为mc1
分配新值:
function test(ns, name, ...) {
ns[name] = new MyClass1(...);
}