2012-06-23 42 views
16

Trong khi xem mã nguồn không nén của jQuery, tôi tình cờ gặp một điều mà tôi không hiểu lắm. Khi tạo hàm ẩn danh của chúng, chúng đặt không xác định làm đối số thứ 2. Điều này đang làm gì và tại sao họ sử dụng không xác định? Có cần phải đặt không xác định làm đối số trong một hàm ẩn danh không? Dưới đây là một ví dụ về những gì tôi đang nói về.Mục đích của tham số có tên "không xác định" trong một hàm JavaScript là gì?

(function(window, undefined) { 
    ...code here 
})(window); 
+1

Related: http://stackoverflow.com/q/5020479/ – CMS

+0

Liên quan: [Tại sao window.undefined có thể thay đổi trong trình duyệt cũ?] (Https://stackoverflow.com/q/29742135/1048572) – Bergi

Trả lời

17

Điều này đang làm, được giao lại undefined-undefined bên trong đóng cửa đó. Đó là một failsafe.Bởi vì mã khác có thể vô tình làm điều gì đó như

undefined = something; 
console.log(undefined); // will output 'something' 

và thats hợp lệ trong javascript (nếu động cơ JS đang được sử dụng đã không được thực hiện ECMAScript 5 đặc điểm kỹ thuật, trong ECMAScript 5 đặc tả undefined là phi non-writable, MDN DOC),

Trích dẫn từ MDN New_in_JavaScript 1.8.5 (ECMA 5) trang

thay đổi các đối tượng toàn cầu

đối tượng toàn cầu khiến chỉ đọc

Các NaN, Infinitykhông xác định toàn cầu đối tượng đã được thực hiện chỉ đọc, mỗi đặc tả ECMAScript 5.

Và từ ES5 Annotated Spec trong Guthub

ES5 spec Sectionx15.1.1.3

15.1.1.3 không xác định

Giá trị không xác định là undefined (xem 8.1).

Thuộc tính này có các thuộc tính {[[Có thể ghi]]: false, [[Có thể đếm được]]: false, [[Configurable]]: false}.

Thậm chí nếu global undefined không thể ghi Bạn có thể có một biến địa phương tên là undefined và có thể mess up mã của bạn (chủ yếu là so sánh với undefined). Nhưng đó là trách nhiệm của bạn. Mã có thể được như

(function(){ 
    console.log('Second Case: '); 
    var undefined = 'Something'; 
    console.log(undefined); // Will log `something` 
    var a ; // a is undefined 
    console.log(a === undefined); // false, as undefined is changed 
    // you might expect a === undefined will return true, but as 
    // `undefined` is changed it will return false. 
    console.log(a); // undefined 
})(); 

Demo:http://jsfiddle.net/joycse06/V4DKN/

Tuy nhiên nếu undefined là có khả năng ghi thì việc chuyển nhượng trên có thể cản trở nhiều comparison thực hiện với undefined sau đó dòng mã như undefined không phải là undefined nữa. Nó có một số giá trị bây giờ.

Vì vậy, khi chúng được gọi là chức năng ẩn danh như

(window) // one argument only 

Và nhận

(window, undefined) // only window is passed when calling the function 
      // Second argument is not passed means it's undefined 
      // so undefined is restored to undefined inside that function 
      // and no global accidental assignments can hamper jQuery's 
      // code using 'undefined' now 

Điều đó có nghĩa bên trong đóng cửa mà undefined được phục hồi để undefined, vì nó đã không được thông qua bất kỳ giá trị như vậy, đảm bảo sử dụng undefined bên trong hàm ẩn danh đó.

Một bài báo chi tiết rất tốt về vấn đề này http://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/

Tôi trích dẫn một số dòng từ liên kết bài viết ở trên để làm cho mọi việc rõ ràng

là gì không xác định?

Trong JavaScript có Không xác định (loại), không xác định (giá trị)không xác định (biến).

Không xác định (loại) là loại JavaScript được tích hợp sẵn.

không xác định (giá trị) là nguyên thủy và là giá trị duy nhất của loại Không xác định.

Bất kỳ thuộc tính nào chưa được gán giá trị, giả định giá trị không xác định. (ECMA 4.3.9 và 4.3.10).

Hàm không có câu lệnh trả về hoặc hàm có khai báo trống trả về không xác định. Giá trị của đối số hàm unsupplied không xác định.

var a; 
typeof a; //"undefined" 

window.b; 

typeof window.b; //"undefined" 



var c = (function() {})(); 

typeof c; //"undefined" 



var d = (function(e) {return e})(); 

typeof d; //"undefined" 

không xác định (biến) là một tài sản toàn cầu mà ban đầu giá trị là undefined (giá trị), từ một tài sản toàn cầu của mình, chúng tôi cũng có thể truy cập vào nó như là một biến. Để nhất quán, tôi luôn gọi nó là một biến trong bài viết này.

typeof undefined; //"undefined" 
var f = 2; 
f = undefined; //re-assigning to undefined (variable) 
typeof f; //"undefined" 

Tính đến ECMA 3, giá trị của nó có thể được bố trí:

undefined = "washing machine"; //assign a string to undefined (variable) 
typeof undefined //"string" 
f = undefined; 
typeof f; //"string" 
f; //"washing machine" 

Không cần phải nói, lại gán giá trị cho biến không xác định là thực hành rất xấu, và trong thực tế nó không được phép bởi ECMA 5.

+1

console.log (không xác định) .. hay không? yep, như vậy :) – Luceos

+1

@Luceos, Cảm ơn bạn đã chỉ ra lỗi đánh máy. :) –

+0

vì vậy, ví dụ nếu tôi đã có "var undefined = 1" bên ngoài một chức năng ẩn danh, và tôi đã có một chức năng ẩn danh trông như thế này: (function (window, undefined) {}) (window); ... are bạn nói rằng undefined = 1 bây giờ có một giá trị không xác định? – JaPerk14

3

Không xác định là loại nhưng cũng là biến toàn cục.

Bạn có thể có mô-đun ghi đè giá trị không xác định bằng cách thực hiện undefined = whatever.

undefined trong thực sự là một thông số không xác định của một hàm gói toàn bộ mã:

(function(window, undefined) { 
    // undefined is the undefined parameter 
}(window)); 

Đó là an toàn, như tham số undefined là trong phạm vi địa phương, và không có ai ngoại trừ các mã trong chức năng này có thể gán cho nó.

Không cần sử dụng undefined làm thông số khi xác định hàm ẩn danh.

Nếu bạn thấy chức năng ở trên, bạn sẽ nhận thấy rằng nó mong đợi hai thông số nhưng một được cung cấp.

Tại sao cần phải khôi phục undefined?

bởi vì, để đảm bảo rằng undefined thực sự là undefined trong phạm vi giữa dấu ngoặc nhọn, thậm chí nếu ai đó đã viết một cái gì đó giống như undefined = "defined"; trong phạm vi toàn cầu, bởi vì undefined thực sự có thể được định nghĩa lại.

Vì vậy, nếu bạn có một cái gì đó giống như

var undefined = 1; 

(function(window, undefined) { 
    console.log(undefined); // output will be undefined not 1 
}(window)); 
+0

bạn không giải thích lý do tại sao undefined cần phải được khôi phục, các câu trả lời khác làm. – Luceos

2

jQuery là đảm bảo rằng undefined thực sự là undefined trong phạm vi của nó bằng cách không đi qua một cuộc tranh cãi với tham số đó.

Hãy mã này ví dụ như khi undefined không thực sự không xác định:

var undefined = 1; 
alert(undefined); // 1 
Các vấn đề liên quan