Array.of和"[ ]"的区别是什么?何时应使用Array.of而不是"[ ]"?

28
我在阅读时发现了 Array.of。 根据MDN所述, Array.of() 方法可以创建一个带有可变数量参数的新数组实例,无论参数的数量或类型如何。
var a = Array.of(1,2,3,4,5);
console.log(a)
但如果我已经知道这些值,我也可以用[]将它们包装起来,以获得相同的输出。那么是否有特定情况下我们可以/应该使用Array.of?此外,使用它与[]相比有何好处呢? 编辑1: 这个问题的目标是区别Array.of[],而不是new ArrayArray.of

6
当您将一个构造函数作为参数传递,并且最终的调用者只能传递一个数字参数或多个参数时,您无法编写文字字面量。在这种情况下,如果传入 Array 的参数只有一个数字,它将无法正确执行。 - Frédéric Hamidi
@MedetTleukabiluly 我已经引用了 polyfill。问题是何时以及为什么需要使用 Array.of - Rajesh
1
这个线程可能会回答你的问题。请参考此链接:https://dev59.com/no3da4cB1Zd3GeqP04Gj - iamdeowanshi
2
我能想到的一个用途是:fn().map(Array.of)fn().map((...args) => [...args]) 的区别。 - azz
1
@Rajesh 这个重复项比较了所有三个。 - Bergi
显示剩余9条评论
3个回答

15
Array.of()Array()/[]构造函数之间有一个微妙的区别。通常,就像Array()一样,Array.of()中的this将是Array对象,并且它将使用Array.constructor(即function Array())来构造其结果。

然而,Array.of可以通过更改其绑定上下文而表现不同。如果绑定上下文可以用作构造函数(如果绑定对象是函数),则它将使用该函数进行构造。因此,让我们将Array.of()绑定到一个函数上并看看会发生什么。

function Test(n){console.log(n)}
Test.prototype.last = function(){return this[this.length-1]};

var what = Array.of.call(Test, [5,6,7], {a:0,b:1}, 42, null, "this is last");
console.log(JSON.stringify(what,null,2));
console.log(what.last());

因此,我们得到了一个类似于数组的东西,可以访问所有方法,包括我们构造函数原型上的方法。

最好记住它的定义

注意2:of函数是一种有意通用的工厂方法;它不要求其this值为Array构造函数。因此,它可以被传递或继承给其他可能使用单个数字参数调用的构造函数。

好的,这对于数组子类化非常方便。我知道通过涉及Object.setPrototypeOf()__proto__可以进行数组子类化,但它们有些不鼓励使用的操作,我们仍然可以通过Array.of()的帮助来完成类似的工作。所以.. 一旦被认为是无用的Array.of()在这里成为了一个英雄;也许是最有用的Array方法之一。怎么会这样..?让我们看看...

function SubArr(){}
SubArr.prototype = Object.create(Array.prototype); // make SubArr.prototype's prototype Array.prototype
SubArr.prototype.last = function(){return this[this.length-1]}; // add prototype methods to SubArr

var what = Array.of.call(SubArr, 1, 2, 3, 4, "this is last");
console.log(JSON.stringify(what,null,2));
console.log(what.last());
console.log(what.map(e => e));
console.log(what instanceof Array);
console.log(Array.isArray(what));
console.log(Object.prototype.toString.call(what));

我也尝试过创建SubArr.prototype.constructor = Array;,但是Array.isArray(what)的结果仍然是false


1
thingy with access to all function methods”是什么意思? - Bergi

3
尽管这种方法可能已经标准化,但似乎在许多浏览器中不受支持,因此使用它似乎很危险,并且正如您所指出的那样,毫无意义。
这个函数的实用性似乎是用于需要声明数组但不想将其组装成部分的情况。也就是说,您希望能够向某些函数传递多个参数,然后该函数返回一个数组。
如果您跟随链接来证明该方法,您将得到以下内容:
引用: 当您无法编写文字时,使用情况通常是因为将构造函数作为funarg传递,并且最终的调用者可能只传递一个数字参数或多个参数。在这种情况下,如果只有一个数字参数,Array将无法完成正确的操作。
这基本上是一种说“这个函数可以接收可变长度的参数列表,并将始终返回用正确值填充的数组”的方式,但实际上,它将一个数组转换为...一个数组,我并不完全相信这个东西需要存在,显然许多浏览器实现者持有类似的观点。
对于Array.of的推动主要是针对new Array()行为不一致的事实的回应。
new Array(2);
// [ , ] 2-element array that's unpopulated

new Array(1,2);
// [1,2] 2-element array populated with the provided values
Array.of将始终像后者版本一样运行。

我知道new Array(2)的情况。但我想问的是Array.of(2)[2]之间的区别。两者都会返回相同的输出。另外,关于当您必须发送函数以获取值的情况,我们不能像这样做吗:JSFiddle - Rajesh
区别在于Array.of在某些浏览器中没有实现,因此除非您感到有义务并使用polyfill,否则在不支持它的情况下使用它没有任何意义。该方法是对使用方括号表示法不太方便或不切实际的情况的响应,因此比较Array.of(2)[2]实际上是错过了重点。 - tadman
4
我知道IE不支持它。关键不是使用它。关键是,为什么这个存在。有什么情况下你会使用Array.of而不是[]呢? - Rajesh
"在实践中,将一个数组转换为...另一个数组" - 参数列表不是数组。" - Bergi
@Bergi 确实如此,但是要在动态环境中使用 apply 需要涉及到数组。而在静态环境下使用它,比如直接使用 Array.of(1,2,3) 并没有比 [1,2,3] 更好的优势。 - tadman

0
迭代 Redu 的回答,您可以使用 ArraySubclass.of 创建数组子类的实例。例如,您可以创建一个 Array-子类包装器,围绕 lodash 的 Array 方法。
例如:
_.Array = class extends Array {
  uniq() {
    return _.Array.from(_.uniq(this));
  }
  last() {
    return _.last(this);
  }
  flatten() {
    return _.Array.from(_.flatten(this));
  }
  // ... more methods
}

_.Array.of([1,2,3], [3,4,5]) // <_.Array> [[1,2,3],[3,4,5]]
  .flatten()                 // <_.Array> [1,2,3,3,4,5]
  .uniq()                    // <_.Array> [1,2,3,4,5]
  .last()                    // <number> 5

JSFiddle


编辑

最终我扩展了这个示例,使用了 ES 代理。

_.Array = class extends Array { }
_.Array.prototype = new Proxy(Array.prototype, {
  get(proto, name) {
    if (name in _) return function (...args) {
        const ret = _[name](this, ...args);
        return Array.isArray(ret) ? _.Array.from(ret) : ret;
    }
    return proto[name];
  }
});

现在每个lodash函数都可用,返回数组的函数被包装在_.Array类中,类似于_(array)的隐式链接。


1
抱歉回复晚了,但这篇文章的目的是了解array.of和[]之间的区别。不需要介绍任何库。 - Rajesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接