Câu hỏi Chức năng gọi với mảng đối số [trùng lặp]


Câu hỏi này đã có câu trả lời ở đây:

Tôi có thể gọi một hàm với một mảng các đối số theo một cách thuận tiện trong JavaScript không?

Thí dụ:

var fn = function() {
    console.log(arguments);
}

var args = [1,2,3];

fn(args);

tôi cần arguments được [1,2,3], giống như mảng của tôi.


17
2017-12-10 15:49


gốc




Các câu trả lời:


Bạn nên sử dụng apply:

var fn = function() {
    console.log(arguments);
};

var args = [1,2,3];

fn.apply(null, args);

Áp dụng sẽ thực hiện cuộc gọi hàm tương đương:

fn(1,2,3);

Lưu ý rằng tôi đã sử dụng null là đối số đầu tiên của apply, điều đó sẽ đặt this từ khóa cho đối tượng chung (window) phía trong fn.

Bạn cũng nên biết rằng arguments đối tượng không thực sự là một mảng, nó là một đối tượng giống như mảng, chứa các chỉ mục số tương ứng với các đối số được sử dụng để gọi hàm của bạn, length thuộc tính cung cấp cho bạn số đối số được sử dụng và arguments.callee thuộc tính là tham chiếu đến hàm thi hành (hữu ích cho đệ quy trên các hàm ẩn danh).

Nếu bạn muốn tạo một mảng từ arguments đối tượng, bạn có thể sử dụng Array.prototype.slice phương pháp:

var fn = function() {
  var args = Array.prototype.slice.call(arguments);
  console.log(args);
};

Chỉnh sửa: Để trả lời nhận xét của bạn, có, bạn có thể sử dụng shift và đặt giá trị trả về của nó làm ngữ cảnh ( this từ khóa) về chức năng của bạn:

fn.apply(args.shift(), args);

Nhưng hãy nhớ rằng shift sẽ loại bỏ phần tử đầu tiên khỏi mảng ban đầu và hàm của bạn sẽ được gọi mà không có đối số đầu tiên đó.

Nếu bạn vẫn cần gọi hàm của bạn với tất cả các đối số khác, bạn có thể:

fn.apply(args[0], args);

Và nếu bạn không muốn thay đổi ngữ cảnh, bạn có thể chỉ cần trích xuất đối số đầu tiên bên trong hàm của bạn:

var fn = function() {
  var args = Array.prototype.slice.call(arguments),
      firstArg = args.shift();

  console.log(args, firstArg);
};

28
2017-12-10 15:51



Điều gì sẽ xảy ra nếu tôi muốn phạm vi là phần tử đầu tiên của Mảng? Tôi có cần giả mạo nó bằng cách sử dụng shift ()? - David
@ David: Bạn có ý nghĩa gì bởi phạm vi? Các this từ khóa? - CMS
Có, sử dụng hàm apply (), đối số đầu tiên sẽ trở thành phạm vi (this) cho hàm này, đúng không? Phạm vi trong trường hợp này cần phải là phần tử mảng đầu tiên. - David
"fn.apply (args.shift (), args);" - javascript có đảm bảo thứ tự đánh giá đối số từ trái sang phải không? Là args thông qua tham chiếu? Biểu thức dạng "f (sửa đổi (đối tượng), đối tượng))" kích hoạt các giác quan nhện của tôi ... - Jonas Kölker
@CMS Câu hỏi này chỉ là về việc gọi một hàm với một mảng các đối số. Tôi nghĩ rằng nói về arguments không phải là một mảng thực sự là ít chủ đề ở đây (nó sẽ giúp OP, nhưng không phải là khách truy cập trong tương lai). Thêm liên kết vào Làm thế nào tôi có thể chuyển đổi đối tượng "đối số" thành một mảng trong JavaScript? sẽ là đủ. - Michał Perłakowski


Trong ECMAScript 6, bạn có thể sử dụng cú pháp mở rộng (...) vì mục đích đó. Đó là cách đơn giản và dễ hiểu hơn Function.prototype.apply().

Ví dụ về mã:

const fn = function() {
  console.log(arguments);
}

const args = [1,2,3];

fn(...args);

7
2018-01-24 16:42