简体   繁体   English

指示函数使用'arguments'对象的最明确方法是什么?

[英]What's the clearest way to indicate a function uses the 'arguments' object?

What's the best way to indicate a function uses the 'arguments' object? 指示函数使用'arguments'对象的最佳方法是什么?
This is obviously opinion based but are there any conventions? 这显然是基于意见的,但有没有任何约定? When would it be better to use an array of arguments? 何时使用参数数组会更好?

Some examples: 一些例子:

// Function takes n arguments and makes them pretty.
function manyArgs() {
    for (var i = 0; i < arguments.length; i++)
    console.log(arguments[i]);
}

function manyArgs( /* n1 , n2, ... */ )

function manyArgs(n1 /*, n2, ... */ )

function manyArgs(argArray)

I never use variadic arguments in JavaScript. 我从不在JavaScript中使用可变参数。 There are many better ways of structuring your code. 有许多更好的方法来构建代码。 For example, I would rewrite your code as follows: 例如,我会按如下方式重写您的代码:

[1,2,3,4,5].forEach(log); // instead of manyArgs(1,2,3,4,5);

function log(a) {
    console.log(a);
}

It's clear and concise. 它简洁明了。

Another example, if you want to find the sum of a list of numbers in JavaScript: 另一个例子,如果你想在JavaScript中找到一个数字列表的总和:

[1,2,3,4,5].reduce(add, 0); // instead of add(1,2,3,4,5);

function add(a, b) {
    return a + b;
}

There are so many useful abstractions available to structure your code that I don't see the benefit of using variadic arguments at all. 有很多有用的抽象可用于构造代码,我没有看到使用可变参数的好处。

I do however use the arguments object for default values: 但是我使用arguments对象作为默认值:

function foo(a,b,c) {
    switch (arguments.length) {
    case 0: a = "default argument for a";
    case 1: b = "default argument for b";
    case 2: c = "default argument for c";
    }

    // do something with a, b & c
}

Hence my advise to you would be to not use variadic arguments at all. 因此,我建议你不要使用可变参数。 Find a better abstraction for your code. 为代码找到更好的抽象。 I've never encountered the need to use variadic arguments in the 8 years that I have been programming in JavaScript. 在我用JavaScript编程的8年里,我从未遇到过使用可变参数的必要性。


Edit: I would advocate using a more functional approach to writing code. 编辑:我主张使用更实用的方法来编写代码。 We can use currying to make code more succinct: 我们可以使用currying使代码更简洁:

function curry(func, length, args) {
    switch (arguments.length) {
    case 1: length = func.length;
    case 2: args = [];
    }

    var slice = args.slice;

    return function () {
        var len = arguments.length;
        var a = args.concat(slice.call(arguments));
        if (len >= length) return func.apply(this, a);
        return curry(func, length - len, a);
    };
}

Using curry we can rewrite the sum example as follows: 使用curry我们可以重写sum示例,如下所示:

var reduce = curry(function (func, acc, a) {
    var index = 0, length = a.length;
    while (index < length) acc = func(acc, a[index++]);
    return acc;
});

var sum = reduce(add, 0);

sum([1,2,3,4,5]); // instead of add(1,2,3,4,5);

function add(a, b) {
    return a + b;
}

Similarly for Math.max and Array.prototype.concat : 类似于Math.maxArray.prototype.concat

var reduce1 = curry(function (func, a) {
    if (a.length === 0)
        throw new Error("Reducing empty array.");
    return reduce(func, a[0], a.slice(1));
});

var maximum = reduce1(max);

maximum([1,2,3,4,5]); // instead of Math.max(1,2,3,4,5);

function max(a, b) {
    return a > b ? a : b;
}

var concat = reduce(function (a, b) {
    return a.concat(b);
}, []);

concat([[1,2],[3,4],[5,6]]) // instead of [1,2].concat([3,4],[5,6])

As for Array.prototype.push , because it mutates the input array instead of creating a new one, I prefer using array.concat([element]) instead of array.push(element) : 至于Array.prototype.push ,因为它改变输入数组而不是创建一个新数组,我更喜欢使用array.concat([element])而不是array.push(element)

var push = reduce(function (a, e) {
    return a.concat([e]);
});

push([1,2,3], [4,5]); // instead of [1,2,3].push(4, 5)

So what are the advantages of writing code this way: 那么以这种方式编写代码有什么好处:

  1. Currying is awesome. Currying很棒。 It allows you to create new functions from old ones. 它允许您从旧的功能创建新功能。
  2. Instead of using variadic arguments you are passing arrays to functions. 您可以将数组传递给函数,而不是使用可变参数。 So you don't need any special way to indicate that the function uses arguments . 因此,您不需要任何特殊方式来指示该函数使用arguments
  3. Suppose you have to find the sum of an array named array . 假设您必须找到名为array的数组的总和。 Using this method you just do sum(array) . 使用此方法,您只需执行sum(array) If you use variadic arguments then you would need to do add.apply(null, array) . 如果使用可变参数,则需要执行add.apply(null, array)
  4. Suppose you want to find the sum of a , b & c . 假设您要查找abc的总和。 All you need to do is sum([a,b,c]) , as compared to add(a, b, c) . add(a, b, c)相比,您需要做的就是sum([a,b,c]) add(a, b, c) You need to put in the extra [] brackets. 你需要加上额外的[]括号。 However doing so makes your code more understandable. 但这样做会使您的代码更容易理解。 According to the zen of python “explicit is better than implicit” . 根据蟒蛇禅宗 “明显比隐含更好”

So these are some of the reasons I never use variadic arguments in my programs. 所以这些是我从未在程序中使用可变参数的一些原因。

// Using ES6 syntax ...
var foo = function(/*...args*/){
    // shim Array.from, then
    var args = Array.from(arguments);
    // or
    var args = [].slice.call(arguments);
};

The clearest way is to use the spread operator available in ES6 , CoffeeScript (where they are called "splats" and the three dots come after the identifer), and TypeScript (where they are called "rest parameters"). 最明确的方法是使用ES6中提供的扩展运算符, CoffeeScript (它们被称为“splats”,三个点位于标识符之后)和TypeScript (它们被称为“rest参数”)。

// Function takes n arguments and makes them pretty.
function manyArgs(...args) {
    for (var i = 0; i < args.length; i++)
        console.log(args[i]);
}

If you're in an environment where you can use them, of course. 当然,如果你在一个可以使用它们的环境中。 It is both better self-documenting, and avoids having to muck around with arguments . 这是更好的自我记录,并避免不得不捣乱arguments

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM