Điều gì xảy ra nếu tôi không truyền một tham số trong một hàm Javascript?


88

Tôi mới làm quen với thế giới của Javascript và đang mày mò viết các hàm rất cơ bản và tình cờ nhìn thấy ví dụ bên dưới và không hiểu tại sao nó hoạt động khi tôi không truyền một tham số khi hàm yêu cầu nó.

Chức năng mẫu

function myfunction(x) {
    alert("This is a sample alert");
}

Bây giờ nếu tôi gọi hàm, myfunction();tôi sẽ thấy cảnh báo. Tại sao tôi có thể gọi hàm mà không có bất kỳ lỗi hoặc cảnh báo nào khi tôi chưa chuyển một tham số?

BIÊN TẬP

Tôi không mong đợi nhiều câu trả lời tuyệt vời như vậy và tôi không có khả năng nói câu trả lời nào là tốt nhất, vì vậy tôi có thể yêu cầu mọi người đề xuất câu trả lời tốt nhất và tôi sẽ trao sự chấp nhận cho người đó.



1
Không có quá tải dựa trên chữ ký hàm trong JS vì vậy nó thực sự không quan tâm đến số lượng tham số mà hàm "mong đợi". Bạn thậm chí có thể chuyển vào các tham số mà hàm không được xác định để sử dụng và chỉ cần sử dụng các đối số từ khóa để truy xuất chúng.
scrappedcola

@scrappedcola - Ý bạn là gì khi nạp chồng cũng như chuyển vào các tham số mà hàm không được xác định để thực hiện? Bạn có thể cho ví dụ?
PeanutsMonkey

2
@PeanutsMonkey. Ý của ông ấy là, bạn không thể có hai chức năng: function foo(x){...}function foo(x,y,z){...}bạn chỉ có thể có một chức năng cho mỗi tên.
gdoron đang hỗ trợ Monica

2
@PeanutsMonkey. Vâng, bạn không thể có function overloadingtrong js, mặc dù bạn có những cách khác để chế nhạo nó.
gdoron đang hỗ trợ Monica

Câu trả lời:


111

Sẽ không có gì xảy ra - nghĩa là bạn sẽ không gặp lỗi hoặc cảnh báo vì việc chuyển các tham số trong javascript là tùy chọn.
Tất cả các tham số không được "cung cấp" sẽ có undefinedgiá trị .

function foo(x, y, z){
    //...
}

foo(1);

Bên trong foohàm bây giờ:

function foo(x, y, z){
    x === 1
    y === undefined
    z === undefined
}

Bạn thậm chí có thể chuyển nhiều đối số hơn, như:

foo(1,2,3,4,5,7); // Valid!

Bạn có thể biết số lượng các tham số được cung cấp bởi arguments.lengthbên trong hàm.

function foo(x, y, z) {
    console.log('x value: ' + x);
    console.log('y value: ' + y);
    console.log('z value: ' + z);
    console.log('Arguments length: ' + arguments.length);
}
console.log('Zero parameters');
foo();
console.log('Four parameters');
foo(1, 2, 3, 4);

Ví dụ về hàm hữu ích xử lý bất kỳ lượng tham số nào:

function max() {
    var maxValue = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        if (maxValue < arguments[i]) {
            maxValue = arguments[i];
        }
    }
    return maxValue;
}

alert(max(1, 5, 7, 2, 88, 32, 44));


Cảm ơn vì bản demo trực tiếp. Không mong đợi nhiều câu trả lời tốt như vậy. Vì vậy, nếu tôi có một hàm chẳng hạn như function myfunction (a,b){}và đã truyền các giá trị của hàm my function (1,2,3,4,5), tôi coi rằng nó vẫn còn hợp lệ? Có phải kỳ vọng rằng sẽ có một số cảnh báo hoặc lỗi?
PeanutsMonkey

Xin lỗi, bạn có vui lòng giải thích thêm chức năng của lệnh console.logcũng như các đối số.length không?
PeanutsMonkey

@PeanutsMonkey. Có hiệu lực! không có cảnh báo không có lỗi, nó thậm chí còn hữu ích, tôi sẽ cung cấp cho bạn bản demo trong giây lát.
gdoron đang hỗ trợ Monica

1
@PeanutsMonkey. Nó cũng hoạt động với IE nếu bạn đã cài đặt bảng điều khiển dành cho nhà phát triển, tôi nghĩ nó được cài đặt theo mặc định từ IE8 +. Tôi không hiểu những gì bạn đã viết về alert.
gdoron đang hỗ trợ Monica

1
@PeanutsMonkey. 1. Bạn không thể có mã sau khi returnnó bị bỏ qua. 2. bạn sẽ không nhận được lỗi hoặc cảnh báo. Xem DEMO này
gdoron đang hỗ trợ Monica

9

Tất cả các đối số trong các hàm JavaScript là tùy chọn (đọc là "được gõ kiểu lỏng").

Các hàm JavaScript có thể được gọi với bất kỳ số lượng đối số nào, bất kể số lượng đối số có tên trong định nghĩa hàm. Bởi vì một hàm được nhập lỏng lẻo, không có cách nào để nó khai báo loại đối số mà nó mong đợi và việc chuyển các giá trị thuộc bất kỳ loại nào cho bất kỳ hàm nào là hợp pháp. Khi một hàm được gọi với ít đối số hơn được khai báo, thì các đối số bổ sung có giá trị không xác định.

Bạn có thể tham chiếu đến các đối số của một hàm trong hàm bằng cách sử dụng các biến đối số được đặt tên hoặc đối tượng đối số. Đối tượng này chứa một mục nhập cho mỗi đối số được truyền cho hàm, chỉ mục của mục nhập đầu tiên bắt đầu bằng 0. Ví dụ: nếu một hàm được truyền ba đối số, bạn có thể tham khảo đối số như sau:

arguments[0]
arguments[1]
arguments[2]
  • JavaScript - Hướng dẫn Cuối cùng, Ấn bản thứ 5

7

Đó chỉ là cách JavaScript hoạt động. Các tham số là tùy chọn và sẽ có giá trị không thực sự là một giá trị "không xác định" trong hàm nếu chúng bị thiếu trong một lệnh gọi hàm.

Bởi "tùy chọn", ý tôi chỉ là: việc gọi bất kỳ hàm nào liên quan đến một danh sách dài các tham số tùy ý. Không cần có mối quan hệ giữa số tham số được truyền vào một hàm và số được khai báo . Cách tốt nhất để nghĩ về tuyên bố này, sau đó:

function x(a, b, c) {
  // ...
}

là bạn đang khai báo một hàm và liên kết tên "a" với tham số đầu tiên, "b" với tham số thứ hai và "c" với tham số thứ ba. Tuy nhiên, không có nghĩa là không được đảm bảo rằng bất kỳ cái nào trong số đó sẽ thực sự bị ràng buộc với một giá trị trong bất kỳ lệnh gọi hàm nào đó sau này.

Bằng cách tương tự, bạn có thể xác định một hàm mà không có bất kỳ tham số nào, và sau đó "tìm" chúng thông qua argumentsđối tượng:

function noArgs() {
  var a = arguments[0], b = arguments[1], c = arguments[2];
  // ...
}

Vì vậy, nó không hoàn toàn giống với hàm đầu tiên, nhưng nó gần giống với hầu hết các cách đếm thực tế.

Giá trị "không xác định" trong JavaScript là một giá trị, nhưng ngữ nghĩa của nó khá bất thường khi các ngôn ngữ sử dụng. Đặc biệt nó không giống hoàn toàn với nullgiá trị. Ngoài ra, bản thân "không xác định" không phải là một từ khóa; nó chỉ là một tên biến nửa đặc biệt!


Bạn có thể giải thích thêm ý của bạn optionalcũng như giá trị "không thực sự là một giá trị" undefinedkhông?
PeanutsMonkey

@PeanutsMonkey - Nếu biến không được cung cấp, thì nó sẽ là undefined.
Derek 朕 會 功夫

@Pointy - Ý của bạn là không có gì đảm bảo rằng bất kỳ tham số đã khai báo nào sẽ thực sự bị ràng buộc với một giá trị?
PeanutsMonkey

1
@PeanutsMonkey JavaScript là một ngôn ngữ động . Khi gọi một hàm, việc khai báo hàm không quan trọng, kể cả số lượng tham số. Do đó, bạn có thể khai báo một hàm với bao nhiêu tham số tùy thích, nhưng điều đó không có giới hạn về số lượng tham số thực sự được truyền vào khi hàm của bạn được gọi. (Theo cách đó, nó giống như C, ít nhất là C trong ngày xưa.) Vì vậy, nếu bạn khai báo một tham số và một lệnh gọi được thực hiện mà không có bất kỳ giá trị tham số nào được cung cấp, tham số sẽ là undefined.
Pointy

3

JavaScript không có giá trị mặc định cho các tham số hàm như các ngôn ngữ khác. Vì vậy, bạn có thể chuyển nhiều hoặc ít đối số tùy thích.

Nếu bạn không chuyển một giá trị, tham số là undefined.

function myfunction(x) {
    alert(x);
}

myfunction(); // alerts undefined
myfunction(1); // alerts 1
myfunction(1,2,3); // alerts 1

Nếu bạn truyền nhiều tham số hơn là trong chữ ký, bạn có thể sử dụng arguments.

function myfunction(x) {
    alert(x);
    console.log(arguments);
}

myfunction(1,2,3); // alerts 1, logs [1,2,3]

Cảm ơn. Thay vì gửi bài chéo, bạn có thể xin vui lòng xem ví dụ của tôi, tôi cung cấp cho David Thomas như tôi vẫn nhận được lỗiundefined
PeanutsMonkey

@PeanutsMonkey: Hả? Vấn đề của bạn là gì?
Rocket Hazmat

Không thành vấn đề. Tôi đang đề cập đến câu hỏi tiếp theo của mình với David về việc chuyển thêm các tham số mà bạn đã đưa vào câu trả lời của mình. Những gì tôi không hoàn toàn theo dõi là những gì bạn có nghĩa là logs? Nó ghi nó ở đâu?
PeanutsMonkey

1
@PeanutsMonkey: Nó ghi nó vào "bảng điều khiển JavaScript" của bạn. Trong hầu hết các trình duyệt, bạn có thể nhấn F12hoặc Ctrl+Shift+Jđể truy cập.
Rocket Hazmat

1
Câu đầu tiên đã lỗi thời kể từ ES2015 ...
Heretic Monkey

2

Bạn cũng có thể cung cấp nhiều đối số hơn là chỉ đối số được đề cập trong hàm

myFunction(1,2,3,4,5,6,7,'etc');

Bạn có thể sử dụng thuộc argumentstính là một mảng để xem các đối số được cung cấp.


@albert đối số không phải là mảng mảng của nó giống như đối tượng see
Mahi

1

Bởi vì không có lỗi cho đến khi hàm dự kiến ​​có thể hoạt động với tham số mà bạn phải truyền vào.

Ví dụ:

function myfunction(x) {
    return x*2;
}

Sẽ đưa ra một lỗi; mặc dù có thể chỉ là a NaN(trong trường hợp này) hoặc a variable is undefined.


Được rồi, miễn là tôi không tham chiếu đến tham số trong hàm, tôi sẽ không gặp lỗi? Có đúng không?
PeanutsMonkey

Bây giờ nếu tôi giải thích rõ hơn về ví dụ bạn cung cấp tức là function myfunction(a,b) { var calc = a+b; return;}và sau đó gọi hàm document.write(myfunction(1.2));tại sao tôi vẫn nhận được giá trị undefinedmặc dù tôi đang truyền một tham số?
PeanutsMonkey

1
Bởi vì bạn không trả lại bất cứ thứ gì. Trong ví dụ của bạn, bạn phải trả về một cách rõ ràng một giá trị: hoặc return calc; hoặc return a+b;(hiển nhiên là dòng cuối cùng; và giá trị sau returnthay cho var calc).
David nói hãy phục hồi Monica

Vì vậy, bạn có nghĩa là tôi không phải khai báo một biến nếu tôi làm return a+b;thế?
PeanutsMonkey

@PeanutsMonkey - Bạn có thể đọc thêm trên return đây .
Derek 朕 會 功夫

0

Nếu bạn bỏ qua đối số, giá trị của nó sẽ là undefined. Điều này cho phép bạn tạo các tham số tùy chọn khá dễ dàng.

Một tính năng khác là khả năng xác định một hàm không có tham số và gọi nó với các đối số thành công, sử dụng argumentsđối tượng. Điều này cho phép bạn dễ dàng tạo mảng đối số có độ dài thay đổi.


0

Trong javascript console.log, bên trong một hàm cung cấp đầu ra không xác định cho các tham số không được vượt qua nhưng bên ngoài hàm, nó đưa ra lỗi không xác định vì bên trong trình duyệt hàm khai báo biến rõ ràng. Ví dụ

console.log(x) 

đưa ra VM1533: 1 Uncaught ReferenceError: x không được xác định trong khi

function test(x) {
console.log(x)
}
test(); 

cho không xác định. Đó là vì hàm test () được trình duyệt viết lại thành:

function test(x) {
    var x;
    console.log(x)
    }

Một vi dụ khac : -

var x =5 ;
function test(x) {
console.log(x)
}
test(); 

vẫn chưa được xác định khi hàm trở thành

function test(x) {
    var x;
    console.log(x)
    }

Cảnh báo trong ví dụ dưới đây sẽ không xác định: -

    var x =5;
    function test() {
    alert(x);
    var x =10;
    }

test(); 

Hàm trên sẽ trở thành: -

 function test() {
    var x;
    alert(x);
    x =10;
    }

Phạm vi của biến javascript bên trong một hàm là phạm vi cấp hàm chứ không phải cấp khối. Ví dụ

function varScope() {

for(var i = 0; i < 10; i++){
    for(var j = 0; j < 5; j++){}
        console.log("j is "+j)
    }
    console.log("i is "+i);


}
varScope();

sẽ cung cấp đầu ra là:

j is 5 
i is 10

Một lần nữa hàm đã trở thành: -

  function varScope() {
    var i;
    var j;
    for(i = 0; i < 10; i++){
        for(j = 0; j < 5; j++){}
            console.log("j is "+j)
        }
        console.log("i is "+i);
    }
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.