Javascript 处理Array.prototype.slice.call(参数)的更干净方法

Javascript 处理Array.prototype.slice.call(参数)的更干净方法,javascript,node.js,Javascript,Node.js,我正在编写几个函数,它们采用不同类型的参数。因此,只需执行以下操作就简单得多: var myFunc = function() { var args = Array.prototype.slice.call(arguments) } …而不是尝试直接在函数声明的参数字段中处理所有不同的可能性,例如: var myFunc = function(param1, param2, param3) { if (param3) { // etc. } } Arr

我正在编写几个函数,它们采用不同类型的参数。因此,只需执行以下操作就简单得多:

var myFunc = function() {
    var args = Array.prototype.slice.call(arguments)
}
…而不是尝试直接在函数声明的参数字段中处理所有不同的可能性,例如:

var myFunc = function(param1, param2, param3) {
    if (param3) {
        // etc.
    }
}
Array.prototype.slice.call(参数)
增加了大量代码,降低了可读性。我试图找出是否有一种方法可以编写一个助手函数,该函数可以完成与
Array.prototype.slice.call()
相同的任务,但更简洁、更易于阅读。我试着说:

var parseArgs = function() {
    return Array.prototype.slice.call(arguments)
}

var foo = function() {
    console.log(parseArgs(arguments))
}

foo('one', 'two', 'three')
// [Arguments, ['one', 'two', 'three']]

但是很明显,这是行不通的。

您需要传递
foo
的arguments对象,并仅对其进行切片,如下所示

function parseArgs(args) {
    return Array.prototype.slice.call(args);
}
function foo() {
    console.log(Array.from(arguments));
}
function parseArgs() {
    return Array.prototype.slice.call(arguments);
}

function foo() {
    console.log(parseArgs(...arguments));
}
当您在
parseArgs
中使用
arguments
时,它将仅引用该函数接收的参数,而不是
foo
接收的参数


在ECMA脚本2015中,您可以直接在
参数
对象上使用,如下所示

function parseArgs(args) {
    return Array.prototype.slice.call(args);
}
function foo() {
    console.log(Array.from(arguments));
}
function parseArgs() {
    return Array.prototype.slice.call(arguments);
}

function foo() {
    console.log(parseArgs(...arguments));
}

或者,您可以保持
parseArgs
不变,并在ECMA脚本2015中将
参数
分散到
parseArgs
上,如下所示

function parseArgs(args) {
    return Array.prototype.slice.call(args);
}
function foo() {
    console.log(Array.from(arguments));
}
function parseArgs() {
    return Array.prototype.slice.call(arguments);
}

function foo() {
    console.log(parseArgs(...arguments));
}
这基本上意味着您正在传播由
foo
接收的
参数
,并将它们传递给
parseArgs
,以便它也将接收相同的参数。

那么:

var parseArgs = function(args) {
    return Array.prototype.slice.call(args)
}

var foo = function() {
    console.log(parseArgs(arguments))
}

foo('one', 'two', 'three')

通过这种方式,您可以解析实际参数
array

在JS中将类似于数组的对象转换为实际数组的一些缩写:

别名
Array.prototype.slice

(function (slice) {
  ...your code...
  function someFunction() {
    var args = slice.call(arguments);
    ...
  }
  ...
}(Array.prototype.slice));
function someFunction() {
  var args = [].slice.call(arguments);
}
function someFunction() {
  var args = [...arguments];
}
使用
[]切片

(function (slice) {
  ...your code...
  function someFunction() {
    var args = slice.call(arguments);
    ...
  }
  ...
}(Array.prototype.slice));
function someFunction() {
  var args = [].slice.call(arguments);
}
function someFunction() {
  var args = [...arguments];
}
创建自己的切片(您尝试了此操作,但参数中出现错误):

使用modern(确保polyfill向后兼容):

如果您处于可以安全使用的环境中,则无需调用
切片

(function (slice) {
  ...your code...
  function someFunction() {
    var args = slice.call(arguments);
    ...
  }
  ...
}(Array.prototype.slice));
function someFunction() {
  var args = [].slice.call(arguments);
}
function someFunction() {
  var args = [...arguments];
}

如果您不想每次都编写
Array.prototype.slice.call(args)

var slice = Function.call.bind(Array.prototype.slice);
然后您可以在任何地方使用它,如:

function fn(){
    var arr = slice(arguments);
}

有许多方法可以使用
参数
,使函数无法优化。使用
参数时必须非常小心

从对象上的参数:

重要提示:您不应该对参数进行切片,因为它会阻止JavaScript引擎(例如V8)中的优化。相反,尝试通过遍历arguments对象来构造新数组

由于Node.js使用V8,您可能希望执行以下操作:

函数parseArgs(){
var args=新数组(arguments.length);
对于(变量i=0;i[1,2,3]
}

myFunc(1,2,3)不确定您的具体用例,但可能选项对象模式是一个更好的选择,例如:
函数foo(o){log(o.name)}foo({name:“Bar”})
@lleaff这需要比这更灵活,但不幸的是,我使用的是Node.js,所以虽然这可以在单个脚本中工作,但我看不到它可以与module.exports()一起工作?它也应该在节点上工作。除非你对他们的全局函数做了一些奇怪的事情。我想这取决于我在哪里加载了实现它的模块。如果我在加载依赖它的任何其他模块之前这样做,它可能会工作。@remus这也会工作,因为它不使用任何浏览器/节点特定的功能:-)哦,是的,我意识到它不是节点特定的。或者,
var args=[…arguments]
。是的,我知道所有这些-因此我使用Array.prototype.slice.call()的MDN推荐的方法@remus,出于性能优化的原因,MDN建议不要使用
Array.prototype.slice.call
。当然,
Array.prototype.slice.call(arguments)
是一个瓶颈的可能性很小,所以我不会太担心这个问题;听起来更像是他们说你不应该直接使用
arguments.slice()
。我想我误解了它。@brandonscript没有
参数。slice
,所以不能直接调用它
slice
是一种数组方法,而参数不是,这就是您首先将
参数
转换为数组的全部原因。所以这一点都不含糊。只需在控制台中尝试以下操作:
(函数(){return arguments.slice();})(1,2,3)
或者,您可以缓存
slice
,以避免每次调用时间接寻址的性能影响:
var slice=Array.prototype.slice。或者直接绑定所有内容一次:
var parseArgs=Function.call.bind(Array.prototype.slice)