console.log(['a', 'b'].push.apply(['c', 'd']));
但它打印出来的是:
2
不应该打印出来吗?
['a', 'b', 'c', 'd']
如果不是这样,那我做错了什么?
console.log(['a', 'b'].push.apply(['c', 'd']));
2
['a', 'b', 'c', 'd']
试一下这个:
console.log(['a', 'b'].concat(['c', 'd']));
如果不行,我做错了什么?
首先,.push
方法返回数组的新长度:
var arr = [1, 1, 1];
console.log(arr.push(1)); // 4
console.log(arr); // [1, 1, 1, 1]
.apply
需要两个参数:你想要将函数应用到的对象和一个参数数组。但是你只传递了一个参数,因此你的代码基本上等价于:['c', 'd'].push()
也就是说,你没有向['c', 'd']
数组中添加任何内容。这也解释了为什么输出中看到了2
: ['c', 'd']
的长度是2
,而.push()
不会添加任何元素,所以它仍然是长度为2
的数组。
如果你想使用.push
来改变原始数组(而不是像.concat
一样创建一个新数组),那么它应该是这样的:
var arr = ['a', 'b'];
arr.push.apply(arr, ['c', 'd']); // equivalent to Array.prototype.push.apply(arr, [...])
// ^ ^--------^
// apply to arr arguments
console.log(arr); // ['a', 'b', 'c', 'd']
另请参阅
[].push.apply(arr, ['c', 'd']);
- maiomanvar arr1 = [1,2];
var arr2 = [3,4];
var arr3 = [...arr1, ...arr2];
console.log(arr3); // Logs [1,2,3,4]
spread element
。对于任何感兴趣的人,Spread Element 是 ES6 规范中使用的措辞。您可以在 Expressions section 中查看它。向下滚动一点到 _SpreadElement_。你知道的越多! - Jonathan Michalik如果您正在使用现代浏览器,那么可以使用扩展运算符...
,例如:
console.log([...['a', 'b'], ...['c', 'd']])
concat
是最佳选择。console.log(['a', 'b'].concat(['c', 'd']))
function appendArray(array,array1){ // adds the items in array1
// array1 can be any type
// to the end of array
var len,i;
array1 = [].concat(array1); // ensure array1 is an array
len = array1.length;
i = 0;
while(i < len){
array[array.length] = array1[i++]; // this is 2* quicker than invoking push
}
return array;
}
只需花60秒钟的时间编写代码,或者在您创建的通用库中添加此功能,就可以创建一个安全且可用于各种场景的数组追加函数。
log(appendArray([0, 1, 2, 3], 4)); // 0,1,2,3,4
log(appendArray([0, 1, 2, 3], [4, 5, 6])); // 0,1,2,3,4,5,6
var array1 = [1,2,3];
var array2 = [4,5,6];
array1 = array1.concat(array2); // 1,2,3,4,5,6
function doSomething(array){
... generate some info
array.concat(info);
}
var myArray = [...someData]; // the array
var myObject.setArray(myArray); // create a new referance to the array in myObject
myArray = doSomething(myArray); // adds info via concat to the array.
虽然不是显而易见,但您现在有两个数组:一个原始的数组在myObject
内部,以及在myObject
中连接版本的数组,它可能在闭包中存储数组引用,除非您取消关联所有相关上下文,否则您不能更改或删除它。也无法知道原始数组存在多少引用。
Function.apply()
有许多理由不使用此函数,但特别值得注意的是在Array.push
函数上使用它。如果您没有对数组进行类型检查,则会遭受不确定性。
var myArray = [1,2,3,4];
var data = getSomeData(); // may return array or array like data
myArray = doSomeWorkOn(myArray); // the spec says this may return undefined
myArray.push.apply(myArray,data); // what happen here is indeterminate and
// depends on the JS context, the JS mode
// and the JS version
如果没有对myArray进行undefined的审查,您无法预测apply的结果。它可能会引发错误,或者如果全局范围具有push函数并且未处于严格模式,则可能会默默失败。
不知道JS版本ES5还是ES6,apply可能已将一个对象data推送到myArray中,也可能将data中的所有项ES5不将类似数组的对象识别为Function.apply
数组,而ES6则可以。因此,必须审查myArray
或data
以使其成为当前JS版本的正确类型。
参数具有依赖于当前JS上下文的限制,JS上下文处理长参数列表时也存在不一致性。有些会引发错误,而另一些则仅简单截断参数。
var myPixelData = [];
myPixelData.push.apply(myPixelData,getSomePixelData()); // what will happen????
getPixelData
返回的数组长度进行比较。所有这些额外的复杂性只是为了使它更容易吗?Array.push
上使用Function.apply
,或者使用Array.concat
,当编写一个函数以执行所需操作并避免一长串问题、歧义和错误更容易呢?你应该这样使用变量
<script type="text/javascript">
var arr1=['a', 'b'];
var arr2=['c', 'd'];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);
</script>
Array.prototype.push
和[].push
是同一个函数。 - Felix Klingthis
值时才应使用 Apply。如果您不检查第一个参数是否为 null 或 undefined(如果您不使用严格模式),则只是在堆栈上添加了一个额外的调用,没有任何好处,并且还存在污染全局对象的风险。 - Blindman67
a= ['a', 'b'];
b= ['c', 'd'];
a.push.apply(a,b);
console.log(a);
Array.prototype.push.apply(ABArray, CDArray)
- Ram