đẩy nhiều yếu tố vào mảng


284

Tôi đang cố gắng đẩy nhiều phần tử thành một mảng, nhưng gặp lỗi

> a = []
[]
> a.push.apply(null, [1,2])
TypeError: Array.prototype.push called on null or undefined

Tôi đang cố gắng làm những thứ tương tự mà tôi làm trong ruby, tôi đã nghĩ đó applylà một cái gì đó giống như *.

>> a = []
=> []
>> a.push(*[1,2])
=> [1, 2]

Câu trả lời:


240

Khi sử dụng hầu hết các chức năng của các đối tượng có applyhoặc call, contexttham số PHẢI là đối tượng bạn đang làm việc.

Trong trường hợp này, bạn cần a.push.apply(a, [1,2])(hoặc chính xác hơn Array.prototype.push.apply(a, [1,2]))


616

Bạn có thể đẩy nhiều phần tử vào một mảng theo cách sau

var a = [];
    
a.push(1, 2, 3);

console.log(a);


1
Câu trả lời này và câu trả lời được chọn tạo ra kết quả khác nhau, và có lẽ bất ngờ. a.push (1) so với a.push ([1])
oevna

1
Bất cứ ai có thể giải thích, tại sao điều này có nhiều phiếu hơn so với câu trả lời được chấp nhận? Nó có thể dễ dàng hơn, nhưng kém linh hoạt. Nếu bạn muốn hợp nhất 2 mảng, điều này sẽ không hoạt động.
BluE

@BluE nếu bạn muốn hợp nhất hai mảng, chỉ cần sử dụng mảng.concat ()
Florent Arlandis

@FlorentArlandis mảng.concat không hoạt động để thêm mảng thứ 2 vào mảng đầu tiên. Nó sẽ tạo ra một cái mới. Tôi biết nó là tương tự. Toán tử lây lan là những gì tôi đang tìm kiếm. Chỉ cần nhìn vào các câu trả lời và ý kiến ​​khác để biết chi tiết.
BluE

435

Bây giờ trong ECMAScript2015 (còn gọi là ES6), bạn có thể sử dụng toán tử trải rộng để chắp thêm nhiều mục cùng một lúc:

var arr = [1];
var newItems = [2, 3];
arr.push(...newItems);
console.log(arr);

Xem bảng tương thích ES6 của Kangax để xem trình duyệt nào tương thích


41
whaaaaaaat điều này thật tuyệt vời, cộng với, nếu bạn làm nó trong bản in, nó sẽ biên dịch thành Push.apply để bạn có khả năng tương thích ngược
Chris

72

Bạn có thể sử dụng Array.concat:

var result = a.concat(b);

16
Array.prototype.concat trả về mảng mới.
xương rồng

12
Anh ta muốn đẩy vào mảng hiện có để có Array.prototype.push.apply(arr1, arr2)câu trả lời chính xác, bởi vì sử dụng arr1.concat(arr2)bạn đang tạo ra một mảng mới.
suricactus

3
@suricactus arr1 = arr1.concat(arr2)không phải là vấn đề lớn và có vẻ sạch sẽ hơn nhiều. Đẩy sang mảng cũ hoặc thay thế mảng cũ bằng mảng mới phụ thuộc vào nhu cầu của bạn. Nếu bạn xử lý các phần tử 10m + đẩy vào mảng cũ sẽ hoạt động nhanh hơn, nếu bạn quản lý các khối nhỏ, bạn hầu như không tìm thấy bất kỳ sự khác biệt nào về tốc độ. Cả hai lựa chọn hoàn toàn hợp pháp.
VisioN

5
@YuvalA. prototype.push.applychỉ gọi pushmột lần. Và sự khác biệt ở trên không cần thiết về tốc độ mà là thao tác tại chỗ so với việc tạo ra một mảng mới. Điều gì xảy ra nếu tôi có một phương thức lấy một mảng và có nghĩa vụ phải sửa đổi nó tại chỗ? Các concatphương pháp không thể nào làm việc, thậm chí với mã VisionN như nó sẽ không thay đổi biến cho người gọi của hàm.
coderforlife

1
a = a.concat(b)vẫn là một cú pháp ngắn hơnArray.prototype.push.apply(arr1, arr2)
Aizzat Suhardi

22

Nếu bạn muốn một giải pháp thay thế Array.concattrong ECMAScript 2015 (còn gọi là ES6, ES2015), giống như nó, không sửa đổi mảng nhưng trả về một mảng mới, bạn có thể sử dụng toán tử trải rộng như vậy:

var arr = [1];
var newItems = [2, 3];
var newerItems = [4, 5];
var newArr = [...arr, ...newItems, ...newerItems];
console.log(newArr);

Lưu ý điều này khác với pushphương thức vì pushphương thức biến đổi / sửa đổi mảng.

Nếu bạn muốn xem các tính năng ES2015 nhất định có hoạt động trong trình duyệt của mình không, hãy kiểm tra bảng tương thích của Kangax .

Bạn cũng có thể sử dụng Babel hoặc bộ chuyển đổi tương tự nếu bạn không muốn chờ hỗ trợ trình duyệt và muốn sử dụng ES2015 trong sản xuất.


4

Có nhiều câu trả lời khuyên bạn nên sử dụng : Array.prototype.push(a, b). Đó là cách tốt đẹp, NHƯNG nếu bạn sẽ có b thực sự lớn, bạn sẽ có lỗi tràn ngăn xếp (vì có quá nhiều đối số). Hãy cẩn thận ở đây.

Xem cách hiệu quả nhất để nối các mảng N là gì? để biết thêm chi tiết.


3
Điều này không cung cấp một câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ một tác giả, hãy để lại nhận xét bên dưới bài đăng của họ. [Làm thế nào để tôi viết một câu trả lời tốt? ] ( stackoverflow.com/help/how-to-answer )
bắt đầu từ

1
Xin lỗi, tôi không thể để lại nhận xét dưới câu trả lời (ngoại trừ của riêng tôi) vì không đủ danh tiếng :). Nhưng dường như điều này nên được đề cập ở đây để có cái nhìn tổng quan hoàn chỉnh. Bạn có thể vui lòng làm điều đó cho tôi? Sau đó tôi sẽ xóa câu trả lời của tôi.
12kb

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.