0

我有一个名为functionalUtilities 的模块,其中包含许多实用功能。缩写版本如下所示:

MYAPP.functionalUtilities = (function() {
function map(func, array) {
  var len = array.length;
  var result = new Array(len);
  for (var i = 0; i < len; i++)
    result[i] = func(array[i]);
  return result;
}
return {
    map:map,
};
})();

然后我有第二个模块,其中包含核心代码:

MYAPP.main = (function() {

//Dependencies
var f = MYAPP.functiionalUtilities;

//Do stuff using dependencies
f.map(...)

})()

f.map每次我想使用map. 当然,在依赖项中,我可以查看我的每个功能实用程序类型:

var map = f.map,
forEach = f.forEach,

等等

但我想知道是否有更好的方法来做到这一点?我读过的很多关于命名空间的文章都提到了别名,但没有建议一种“将对象的所有内容导入范围”的方法。

非常感谢您的帮助,

罗宾

[编辑] 澄清一下,我想在其中使用我的功能实用程序(map等),MYAPP.main而不必每次都在它们前面加上f.

这可以通过遍历每个函数MYAPP.functionalUtilities并分配给MYAPP.main. 但是这需要的代码量并不能证明好处是合理的,它也不是一个通用的解决方案。

4

2 回答 2

1

正如我在评论中所说。没有真正的方法可以从对象属性中自动定义局部变量。我唯一想到的是使用 eval:

for (var i in MYAPP.functiionalUtilities) {
    eval("var " + i + " = MYAPP.functiionalUtilities[i];");
}

但我不会使用这种方法,因为您可以使用字符串作为键的对象属性,如下所示:

var obj = {
    "my prop": 1
};

“我的道具”可能是对象属性的有效键,但它不是有效的标识符。所以我建议用;f.prop手动编写或定义你的局部变量。var prop = f.prop

编辑

正如 Felix Kling 在评论部分中提到的那样,实际上还有另一种方法可以实现这一点,使用 with 语句,除了它已被弃用之外,我真的不太了解。

于 2013-06-29T16:35:27.520 回答
1

这是一个迟到的答案 - 我想添加到 basilikum 的答案。

1)with关键字在这里可能很有用!

with(MYAPP.functiionalUtilities) {

    map(console.log, [ 'this', 'sorta', 'works', 'quite', 'nicely!' ]);

    // Directly reference any properties within MYAPP.functiionalUtilities here!!

};

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with

with某些方面,关键字正是针对这种情况而设计的。当然,应该注意的是 Mozilla 开发者链接不鼓励使用with,并且with在严格模式下也是禁止的。另一个问题是该with语句导致其参数成为范围链的头部,这意味着它将始终首先检查with块中所有语句的所有标识符。这可能会影响性能。

2)改进 basilikum 的答案

虽然函数调用无法将项目添加到其父框架的范围,但有一种方法可以避免每次您希望将项目列表添加到命名空间时都输入一个 for 循环。

// First, define a multi-use function we can use each time
// This function returns a string that can be eval'd to import all properties.
var import = function(module) {
    var statements = [];
    for (var k in module) statements.push('var ' + i + ' = module["' + i + '"]');
    return statements.join(';');
};

// Now, each time a module needs to be imported, just eval the result of import
eval(import(MYAPP.functiionalUtilities));
map(console.log, [ 'this', 'works!' ]);

这里的想法是用类似eval(import(MYAPP.functiionalUtilities));.

正如 basilikum 所说,这里的危险在于模块属性必须是有效的标识符名称。

于 2016-07-11T17:45:46.503 回答