Truyền số lượng đối số chưa biết vào hàm javascript


84

Có cách nào để truyền một số lượng đối số không xác định như:

var print_names = function(names) {
    foreach(name in names) console.log(name); // something like this
}

print_names('foo', 'bar', 'baz');

Ngoài ra, làm cách nào để lấy số lượng đối số được truyền vào?



Cho đến nay câu trả lời của public override là câu trả lời duy nhất mô tả cách chuyển một số lượng đối số chưa biết (vào một lệnh gọi hàm) (sử dụng .apply). Những người khác chỉ ra cách đọc một số lượng đối số chưa biết (từ bên trong hàm) (sử dụng arguments).
Ben J

Câu trả lời:


146

ES3 (hoặc ES5 hoặc Javascript cũ)

Bạn có thể truy cập các đối số được truyền cho bất kỳ hàm javascript nào thông qua argumentsđối tượng ma thuật , đối tượng này hoạt động tương tự như một mảng. Sử dụng argumentschức năng của bạn sẽ trông như thế nào

var print_names = function() {
     for (var i=0; i<arguments.length; i++) console.log(arguments[i]);
}

Điều quan trọng cần lưu ý là rằng argumentskhông một mảng. MDC có một số tài liệu tốt về nó: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#Using_the_arguments_object

Nếu bạn muốn chuyển argumentsthành một mảng để bạn có thể làm những việc như .slice(), .push()v.v., hãy sử dụng một cái gì đó như sau:

var args = Array.prototype.slice.call(arguments);

ES6 / Bảng chữ cái

Có một cách tốt hơn! Tính năng thông số nghỉ ngơi mới đã hỗ trợ bạn:

var print_names = function(...names) {
    for (let i=0; i<names.length; i++) console.log(names[i]);
}

3
Cảm ơn vì một câu trả lời chi tiết và đồng thời ngắn gọn + đơn giản :)
Mese

1
Tham chiếu đến ES6 spread syntaxkhá không chính xác ở đây. Đó là một rest parameterví dụ bạn đã đưa ra. Câu trả lời tốt, nhưng khó hiểu rằng nó được tham chiếu nhưspread
Drenai

Cảm ơn câu trả lời của bạn! Tôi thấy đây là một bài viết hữu ích giải thích những gì đang xảy ra với Array.prototype.slice.call(arguments): medium.com/@andrewsburke/…
AnnieP.

22

ES6 / ES2015

Tận dụng cú pháp tham số còn lại .

function printNames(...names) {
  console.log(`number of arguments: ${names.length}`);
  for (var name of names) {
    console.log(name);
  }
}

printNames('foo', 'bar', 'baz');

Có ba điểm khác biệt chính giữa tham số phần còn lại và đối tượng đối số:

  • các tham số còn lại chỉ là những tham số chưa được đặt tên riêng, trong khi đối tượng đối số chứa tất cả các đối số được truyền cho hàm;
  • đối tượng đối số không phải là một mảng thực, trong khi các tham số còn lại là các cá thể Mảng, nghĩa là các phương thức như sắp xếp, ánh xạ, forEach hoặc pop có thể được áp dụng trực tiếp trên nó;
  • đối tượng đối số có chức năng bổ sung cụ thể cho chính nó (như thuộc tính callee).

Điều này có ý nghĩa hoàn hảo cho việc phát triển web thường sử dụng cú pháp PHP phổ biến.
Dadan


7
function print_args() {
    for(var i=0; i<arguments.length; i++)
        console.log(arguments[i])
}

6

Có một đối tượng ẩn được truyền cho mọi hàm trong JavaScript được gọi arguments.

Bạn sẽ chỉ sử dụng arguments.lengthđể lấy số lượng đối số được truyền vào hàm.

Để lặp lại các đối số, bạn sẽ sử dụng một vòng lặp:

for(var i = arguments.length; i--) {
   var arg = arguments[i];
}

Lưu ý rằng đó argumentskhông phải là một mảng thực, vì vậy nếu bạn cần nó như một mảng, bạn sẽ chuyển đổi nó như thế này:

var args = Array.prototype.slice.call(arguments);

3
Chỉ cần lưu ý rằng nó không phải là một mảng "thật", nó là một "mảng giống như" đối tượng (với một số đặc điểm đặc biệt), nhưng để sử dụng "phương pháp Array" vào nó, bạn sẽ cần phải chuyển đổi nó, ví dụ như var args = Array.prototype.slice.call(arguments);, var args = Array.apply(null, arguments);, vv , có rất nhiều cách ...
Christian C. Salvadó

4

arguments.length. bạn có thể sử dụng vòng lặp for trên đó.

(function () {
    for (var a = [], i = arguments.length; i--;) {
        a.push(arguments[i]);
    };
    return a;
})(1, 2, 3, 4, 5, 6, 7, 8)

@meder, tôi thích sử dụng các chức năng ẩn danh như vậy. Ví dụ đẹp! Ngoài ra, bạn có thiếu một vài dấu chấm phẩy ở đó không?
Jacob Relkin

dường như chạy tốt như hiện tại.
meder omuraliev

@meder, chèn Dấu chấm phẩy trong #ftf Javascript
Jacob Relkin

@meder, thực sự, chỉ cần dấu chấm phẩy sau forkhối là không thực sự cần thiết, tuy nhiên tôi sẽ thêm một dấu chấm phẩy ở cuối dòng cuối cùng.
Christian C. Salvadó

1
@weng, nó về FunctionExpressionvs FunctionDeclaration, xem bài này .
Christian C. Salvadó

2

Tốt hơn nhiều bây giờ cho ES6

function Example() {
    return {
        arguments: (...args) =>{
            args.map(a => console.log());
        }
    }
}

var exmpl = new Example();
exmpl.arguments(1, 2, 3, 'a', 'b', 'c');

Tôi hi vọng cái này giúp được


0

Các thông số còn lại trong ES6

const example = (...args) => {
  for (arg in args) {
    console.log(arg);
  }
}

Lưu ý: bạn có thể chuyển các tham số thông thường vào trước các tham số còn lại

const example = (arg1, ...args) => {
  console.log(arg1);
  for (arg in args) {
    console.log(arg);
  }
}

0

Bạn có thể sử dụng toán tử spread / rest để thu thập các tham số của bạn vào một mảng và sau đó length, mảng của mảng sẽ là số tham số bạn đã truyền:

function foo(...names) {
    console.log(names);
    return names;
}

console.log(foo(1, 2, 3, 4).length);

Sử dụng BabelJS, tôi đã chuyển đổi hàm thành JS cũ:

"use strict";

function foo() {
  for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
    names[_key] = arguments[_key];
  }

  console.log(names);
  return names;
}

0

Bạn có thể tạo một hàm bằng cách sử dụng toán tử spread / rest và từ đó, bạn đã đạt được mục tiêu của mình. Hãy xem đoạn dưới đây.

const print_names = (...args) => args.forEach(x => console.log(x));


-4

Tôi thích làm điều này:

Điều này sẽ không hữu ích nếu bạn không biết số lượng đối số, nhưng nó sẽ hữu ích nếu bạn không muốn nhớ thứ tự của chúng.

/**
 *  @param  params.one        A test parameter
 *  @param  params.two        Another one  
 **/
function test(params) {

    var one = params.one;
    if(typeof(one) == 'undefined') {
        throw new Error('params.one is undefined');
    }

    var two = params.two;
    if(typeof(two) == 'undefined') {
        throw new Error('params.two is undefined');
    }
}

1
Câu hỏi là về số lượng đối số không xác định.
Thiết kế bởi Adrian
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.