函数定义中参数周围的方括号

Square brackets surrounding parameter in function definition

我在 the Ember CLI website 中遇到了以下代码:

export default Ember.Helper.helper(function([value]) {
  return value.toUpperCase();
});

令我困惑的是 value 参数周围的方括号。我可以在函数调用中理解它,但为什么在函数定义中?

这一切让我很惊讶,但它似乎是有效的javascript,根据 ECMAScript 2017 语言规范,函数声明中的形参可以是任意的"binding element",包括数组绑定。

https://tc39.github.io/ecma262/#prod-BindingElement

此功能的实际行为似乎意味着函数的参数应该是一个数组,value 将采用数组中第一个元素的值。

这是一个destructuring assignment。 @recursive 描述的行为是正确的,但了解它不限于第一个元素可能会有所帮助。如果写成三个元素:

function xyz([a, b, c]){...}

然后 a、b 和 c 将全部声明为函数范围内可用的变量,在这种情况下,将等于数组的前 三个 元素。此外 - 如果作为参数传递的数组没有至少三个元素,则参数(a、b 和 c)中指定的其余元素 将存在 声明时,但将具有 undefined:

的值
// Example
function destructureThis([a, b, c]){
  console.log(a, b, c);
}

var shortArray = [1, 25];
destructureThis(shortArray);

// Prints to console:
// 1 25 undefined

同样,如果参数数组较大,则将忽略其他元素,如前所述。

var longerArray = [1, 5, 9, 50, 60];
destructureThis(longerArray);

// Prints to console:
// 1 5 9

此外...这是对 ECMAScript 规范的最新补充,如果不使用 Babel 或等效的转换它以实现向后兼容性,它应该在所有目标环境(看着你的 IE)中进行测试。

LavaWings 上面的答案是正确的,并且对数组析构函数的工作原理进行了很好的分析,这就是用括号声明函数参数时得到的结果。

请注意,这也适用于反向。 Javascript 将允许您从任何对象“构造”一个​​数组,方法是传递带有括号的对象,并将其视为函数中的数组。在这种情况下,函数定义将不会在参数周围包含方括号。

这两种行为是同一事物的两面,展示了编译器如何在幕后处理对象和数组。

例如:

var a, b;

a = {first:"Orion", middle:"Miki", last:"Kenyon"}
b = objToUpperCase([a]); // a is a single object, but is passed as an array

console.log(a);
console.log(b[0]);

function objToUpperCase(inputs) {
  var outputs = [];
  for (var i = 0; i <= inputs.length - 1; i++) {
    var input = inputs[i];
    output = {
        first: input.first.toUpperCase(),
        middle: input.middle.toUpperCase(),
        last: input.last.toUpperCase()
        };
    outputs.push(output);
  }
  return outputs;
}

输出:

Object {first: "Orion", last: "Kenyon", middle: "Miki"}
Object {first: "ORION", last: "KENYON", middle: "MIKI"}