2011-01-26 8 views
53

Tôi đang sử dụng "Closure Compiler", khi biên soạn kịch bản của tôi, tôi dành những điều sau đây:sự khác biệt giữa "void 0" và "không xác định"

Trước khi soạn thảo:

// ==ClosureCompiler== 
// @compilation_level SIMPLE_OPTIMIZATIONS 
// @output_file_name default.js 
// @formatting pretty_print,print_input_delimiter 
// ==/ClosureCompiler== 

var myObj1 = (function() { 

    var undefined; //<----- declare undefined 

    this.test = function(value, arg1) { 

    var exp = 0; 
    arg1 = arg1 == undefined ? true : arg1; //<----- use declare undefined 
    exp = (arg1) ? value * 5 : value * 10; 

    return exp; 
    }; 

    return this; 
}).call({}); 

var myObj2 = (function() { 

    this.test = function(value, arg1) { 

    var exp = 0; 
    arg1 = arg1 == undefined ? true : arg1; //<----- without declare undefined 
    exp = (arg1) ? value * 5 : value * 10; 

    return exp; 
    }; 

    return this; 
}).call({}); 

Biên soạn:

// Input 0 
var myObj1 = function() { 
    this.test = function(b, a) { 
    a = a == void 0 ? true : a; //<----- 
    var c = 0; 
    return c = a ? b * 5 : b * 10 
    }; 
    return this 
}.call({}), myObj2 = function() { 
    this.test = function(b, a) { 
    a = a == undefined ? true : a; //<----- 
    var c = 0; 
    return c = a ? b * 5 : b * 10 
    }; 
    return this 
}.call({}); 

Với điều này tôi tin rằng câu hỏi của việc sử dụng "void 0" và "không xác định", là có bất kỳ sự khác biệt trong việc sử dụng hoặc hai trường hợp là tốt ?.

Sửa

nếu tôi xác định "var không xác định" được biên soạn với "void 0", nếu tôi không xác định "không xác định" được biên soạn với "undedined.", Sau đó không phải là một vấn đề của số ký tự giữa "không xác định "và "void 0"

Test

Sửa II: hiệu suất, dựa trên this link

Code and Test

IE 8:
typeof: 228ms
không xác định: 62ms
void 0: 57ms

Firefox 3.6:
typeof: 10ms
không xác định: 3ms
trống 0: 3ms

Opera 11:
typeof: 67ms
không xác định: 19ms
void 0: 20ms

Chrome 8:
typeof: 3ms
không xác định: 5ms
void 0: 3ms

Trả lời

59

From MDN:

Nhà điều hành void đánh giá cho expression và sau đó trả về undefined.

Toán tử này cho phép chèn các biểu thức tạo ra các hiệu ứng phụ vào những vị trí mà biểu thức đánh giá là không xác định được mong muốn.

Toán tử vô hiệu thường được sử dụng chỉ để lấy giá trị nguyên thủy undefined, thường sử dụng "void(0)" (tương đương với "void 0"). Trong những trường hợp này, biến toàn cầu undefined có thể được sử dụng thay thế (giả sử nó không được gán cho một giá trị không mặc định).

giao dịch hoán đổi Closure Compiler trong void 0 vì nó chứa các ký tự ít hơn undefined, do đó sản xuất tương đương, mã nhỏ.


Re: OP bình luận

vâng, tôi đọc tài liệu, nhưng trong ví dụ tôi đã đưa, "google đóng cửa" trong một trường hợp sử dụng "void 0" và một "không xác định"

Tôi tin rằng đây thực sự là một bug in Google Closure Compiler!

+1

có, tôi đọc tài liệu, nhưng trong ví dụ tôi đã đưa ra, "google closure" trong trường hợp sử dụng "void 0" và một "undefined" –

+0

@andres: hmmm, tôi thấy những gì bạn đang nói. Thật lạ lùng ... –

+1

@andres: xem chỉnh sửa của tôi. –

4

Không có sự khác biệt, Hãy tự thử:

void 0 === undefined 

sẽ đánh giá là true.
undefined là ký tự dài hơn, tôi đoán đó là lý do tại sao họ sử dụng theo cách đó.

+0

Và do đó đó là tối ưu hóa băng thông: gửi ít byte hơn dây? –

+1

@ JoelCoehoorn: trình biên dịch đóng cũng là một minifier tốt, tôi đoán họ cố gắng để squeeze mỗi byte ở đây. – jAndy

+0

nếu tôi xác định "var undefined" được biên dịch với "void 0", nếu tôi không xác định "undefined" được biên dịch với "chưa được xác định". sau đó không phải là vấn đề số lượng ký tự giữa "không xác định" và "void 0" –

50

duy nhất khác biệt ngữ nghĩa thực sự giữa void exprundefined là trên ECMAScript 3, các undefined tài sản của đối tượng toàn cầu (window.undefined trên môi trường trình duyệt) là có thể ghi, trong khi các nhà điều hành void sẽ trả về giá trị undefinedluôn.

Một mô hình phổ biến mà thường được thực hiện, sử dụng undefined mà không cần lo lắng chỉ đơn giản là tuyên bố một cuộc tranh cãi, và không đi qua bất cứ điều gì với nó:

(function (undefined) { 
    //... 
    if (foo !== undefined) { 
    // ... 
    } 

})(); 

Điều đó sẽ cho phép minifiers co lại lập luận có lẽ đến một chữ cái (thậm chí ngắn hơn void 0 :), ví dụ:

(function (a) { 
    //... 
    if (foo !== a) { 
    // ... 
    } 
})(); 
+0

Đẹp. Cảm ơn vì điều đó, tôi đã tự hỏi liệu giá trị 'undefined' có thuộc tính hay không. http://typeofnan.blogspot.com/2011/01/typeof-is-fast.html – jAndy

+0

@ jAndy, bài viết hay, và cảm ơn vì đã đề cập;), BTW bạn có thể thêm một thử nghiệm đối với 'void 0', nó có thể thú vị ... – CMS

+0

Cảm ơn! Tôi insta kiểm tra rằng, 'void 0' thực hiện tốt hơn so với' undefined' rõ ràng bây giờ, nhưng nó vẫn còn đằng sau phiên bản được lưu trữ. – jAndy

8

Chỉ cần theo dõi tất cả câu trả lời trước đây.

Chúng trông giống nhau, nhưng đối với Trình biên dịch, chúng hoàn toàn khác nhau.

Hai phần mã biên dịch thành các đầu ra khác nhau vì một tham chiếu tới biến cục bộ (var undefined) và trình biên dịch chỉ đơn giản là trong dòng vì nó được sử dụng chính xác một lần và không nhiều hơn một dòng. Nếu nó được sử dụng nhiều lần, thì lớp lót bên trong sẽ không xảy ra. Nội tuyến cung cấp kết quả "không xác định", ngắn hơn để biểu thị là "khoảng trống 0".

Biến không có biến cục bộ đề cập đến biến được gọi là "không xác định" bên dưới đối tượng toàn cầu , được tự động "extern'ed" bởi Trình biên dịch đóng cửa (trên thực tế, tất cả các thuộc tính đối tượng chung). Do đó, không có đổi tên diễn ra, và không có trong lót diễn ra. Thì đấy! vẫn "không xác định".