替换为下划线的toArray

时间:2015-04-26 22:10:20

标签: javascript meteor underscore.js

我正在研究一个超级简单的流星应用程序,并发现一些代码几乎完全符合我的要求,但依赖于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对象示例中。

谢谢!

3 个答案:

答案 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);
};

不幸的是,下划线使用下划线!因此,您必须实施isArrayisArrayLike:P

也许来源可以为您提供一些关于如何使您的实施工作的想法?

另外,请查看lodash源代码。这也可能提供一些灵感:https://github.com/lodash/lodash/blob/master/lodash.js#L8983