我看到这个response用于将一个数组扩展为另一个数组 所以我试过了:
console.log(['a', 'b'].push.apply(['c', 'd']));
但它打印出来:
2
不应该打印:
['a', 'b', 'c', 'd']
如果不是我做错了什么?
答案 0 :(得分:15)
如果不是我做错了什么?
首先,.push
返回数组的新长度:
BEGIN TRANSACTION;
INSERT INTO Clocks(time) VALUES (date('now'));
UPDATE Operations
SET finished = 1,
finishedOn = last_insert_rowid()
WHERE _id = '00000000-0000-0000-0000-000000000001';
COMMIT;
其次,.apply
需要两个参数:要将函数应用于的对象,以及参数数组。您只传递一个参数,因此您的代码基本上等同于:
var arr = [1, 1, 1];
console.log(arr.push(1)); // 4
console.log(arr); // [1, 1, 1, 1]
即。您没有向['c', 'd'].push()
数组添加任何内容。这也解释了为什么您在输出中看到['c', 'd']
:2
的长度为['c', 'd']
而2
未向其添加任何元素,因此其长度仍为.push()
}。
如果你想使用2
来改变原始数组(而不是创建像.concat
这样的新数组),它必须看起来像:
.push
另见
答案 1 :(得分:12)
试试这个:
console.log(['a', 'b'].concat(['c', 'd']));
答案 2 :(得分:7)
如果您的方案允许使用ES6语法,则可以使用spread element来连接数组:
var arr1 = [1,2];
var arr2 = [3,4];
var arr3 = [...arr1, ...arr2];
console.log(arr3); // Logs [1,2,3,4]
答案 3 :(得分:4)
如果您使用的是现代浏览器,那么您可以像这样使用点差运算符...
:
console.log([...['a', 'b'], ...['c', 'd']])
如果您使用的是较旧的浏览器/没有转录程序,则可以使用concat
:
console.log(['a', 'b'].concat(['c', 'd']))
答案 4 :(得分:2)
由于这里似乎存在对使用各种数组附加方法的一般误解,我将添加ES6引入扩展运算符的最安全的替代方法
功能语言
开发了功能语言以简化代码开发,允许程序员和系统工程师定义函数来替换常见的操作/算法。 JS是一种函数式语言,您编写函数以使生活更轻松,节省您的输入并使程序更容易测试和验证,所以为什么要用危险的替代品来对抗它。
答案中的错误(Jonathan Michalik回答除外)是他们都试图强迫语言做一些应该由函数(Function.apply
)完成的事情,或提供一个解决方案,但没有解释它正在做什么(Array.concat
)。
编写一个附加数组的函数,例如。
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
现在为什么其他答案不是好的解决方案。
Array.concat
是更安全的选项,如果您控制对数组的所有引用,则应该使用它。它受到以下事实的影响:它在使用时会创建一个新数组。
var array1 = [1,2,3];
var array2 = [4,5,6];
array1 = array1.concat(array2); // 1,2,3,4,5,6
许多人错误地认为concat(array2)被添加到array1,它不是,它被添加到array1的副本中。如果您对原始数组有其他引用,那么您最终会创建连接数组的副本,而原始数组仍保留在内存中。
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
中的连接版本可能会将数组referance存储在闭包中,除非你取消引用所有内容,否则不能更改或删除相关背景。你也不知道对原始数组有多少引用。
<强> 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,您无法预测应用的结果是什么。它可能会抛出错误,或者如果全局范围具有推送功能并且您没有处于严格模式,它可能会无声地失败。
在不知道JS版本ES5或ES6的情况下,apply可能已将一个对象data
推送到myArray,或者data
ES5中的所有项目都不会将类似对象的对象识别为{{1}的数组虽然ES6有。因此,您必须审核Function.apply
或myArray
以获得当前JS版本的正确类型。
参数具有依赖于当前JS上下文的限制,JS上下文对长参数列表的处理之间也存在不一致。有些人会抛出错误,有些人会简单地截断参数。
data
这可能会抛出,或者它可能会起作用,或者它可能只将65535个项目推送到阵列上,或更多或更少。您必须将它包装在try catch中,并根据var myPixelData = [];
myPixelData.push.apply(myPixelData,getSomePixelData()); // what will happen????
返回的数组的长度审核结果。所有增加的复杂性只是为了让它更容易???
那么为什么在getPixelData
上使用Function.apply
或使用Array.push
时更容易编写一个函数来执行您想要的操作并从一长串问题中拯救您,模糊不清和错误。
答案 5 :(得分:1)
你应该试试这个:
a= ['a', 'b'];
b= ['c', 'd'];
a.push.apply(a,b);
console.log(a);
答案 6 :(得分:1)
你应该使用像这样的变量
<script type="text/javascript">
var arr1=['a', 'b'];
var arr2=['c', 'd'];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);
</script>