我正在研究一个超级简单的流星应用程序,并发现一些代码几乎完全符合我的要求,但依赖于underscorejs。我从来没有使用过underscorejs并且不喜欢那种依赖(我当然听说下划线很棒,但我现在不想处理任何不必要的包)。这是唯一使用underscorejs的行:
this.channels[name].args = _.toArray(arguments);
重写toArray功能是否是微不足道的,或者引擎盖下是否有一些繁重的工作?
代码来自此博客条目:http://www.manuel-schoebel.com/blog/meteorjs-package-only-app-structure-with-mediator-pattern,位于Mediator对象示例中。
谢谢!
答案 0 :(得分:1)
如果这是本地arguments对象,您可以迭代并创建一个数组
var arr = [];
for (var i=0; i<arguments.length; i++) {
arr[i] = arguments[i]
}
或者您可以使用缩写为Array.prototype.slice.call
[].slice.call
var arr = [].slice.call(arguments);
请注意,MDN专门说
你不应该对参数进行切片,因为它会阻止优化 JavaScript引擎(例如V8)。相反,尝试构建一个新的 数组通过遍历参数对象。
答案 1 :(得分:1)
arguments
是一个可迭代的对象,尽管它不是明确的Array
。如果您不关心JS引擎的含义,您可以简单地将其转换为真实数组。这允许您像处理数组一样处理arguments
并执行数组方法。你可以这样做:
this.channels[name].args = Array.prototype.slice.call(arguments);
另一种方式是:
this.channels[name].args = Array.apply(null, arguments);
如果您想要替换_.toArray()
而不依赖于下划线库,您可以执行以下操作:
_.toArray = function () { return Array.prototype.slice.call(arguments)[0]; };
ES6将spread operator能够优雅地完成您的工作:
function someFunction(...args) {
this.channels[name].args = args;
}
答案 2 :(得分:0)
如果你对下划线进行评级并相信它正在做什么,你可以使用它在这里找到的toArray方法:http://underscorejs.org/docs/underscore.html#section-46
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};
不幸的是,下划线使用下划线!因此,您必须实施isArray
和isArrayLike
:P
也许来源可以为您提供一些关于如何使您的实施工作的想法?
另外,请查看lodash源代码。这也可能提供一些灵感:https://github.com/lodash/lodash/blob/master/lodash.js#L8983