2012-11-19 54 views
6

Tôi thường sử dụng var options = options || {} làm cách để mặc định đối tượng trống. Nó thường được sử dụng để khởi tạo một đối tượng tùy chọn trong trường hợp nó không được thông qua trong tham số của một cuộc gọi hàm.Sự khác biệt giữa `var options = options || {} `và` tùy chọn || (options = {}) `

Điều tôi đã đọc ở một số nơi (bài đăng blog, mã nguồn) mà options || (options = {}) thể hiện rõ hơn ý định của nhà phát triển. Ai đó có thể xây dựng nó? Tôi không thấy sự khác biệt chức năng giữa hai, vì vậy có một cái gì đó tôi phải mất tích ở đây.

--- chỉnh sửa

tôi thấy trong mã nguồn Backbone.js ở một số nơi, như https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L273

Tôi nghĩ rằng tôi thấy nó quá trong mã nguồn của jQuery quá. Và trong nhiều hướng dẫn phong cách viết Js phát triển mạnh mẽ.

--- chỉnh sửa 2 mã ví dụ:

var func = function(param, options) { 
    // How I do it 
    var options = options || {}; 
    // How I should do it in the "same" way 
    options = options || {}; 
    // The "other" way 
    options || (options = {}); 

} 
+0

Bạn có thể liên kết với một số bài đăng này không? –

+0

Đây là IMHO chủ quan, cá nhân tôi thích cái mà bạn thích, họ thực sự làm điều tương tự. –

+1

Tôi thường làm 'options = options || {} ', mà không cần khai báo lại biến với' var'. Đáng tiếc là không có '|| =' trong Javascript – Kos

Trả lời

3

Họ nên làm điều tương tự, nhưng có một cách tốt hơn.

Về mặt lý thuyết thứ hai, chỉ gán nếu giá trị là giả, có thể loại bỏ bài tập và nhanh hơn. Thật vậy trong một jsperf chúng ta thấy nó là (12%).

Trong thực tế, rõ ràng nếu tuyên bố là chỉ nhanh như điều kiện-then-assign:

if(!options) 
    options = {}; 

Try the test on your browser/machine.

Tôi nghĩ rằng rõ ràng nếu là rõ ràng nhất và không bị phạt.

Edit:

Nếu bạn đang mong đợi một đối tượng để được thông qua vào một chức năng, sau đó tôi nghĩ rằng thử nghiệm tốt hơn là:

if(typeof options !== 'object') 
    options = {}; 

Điều này sẽ đảm bảo rằng bạn có một đối tượng sau , ngay cả khi nó trống. Bất kỳ thử nghiệm nào khác (đối với không xác định hoặc giả) sẽ cho phép một đối tượng không trung thực thông qua một số không khác hoặc một chuỗi không trống. Tuy nhiên, khi jsperf hiển thị, tốc độ này chậm hơn ~ 15%. Vì bạn chỉ làm điều này khi nhập vào một hàm sẽ xử lý các đối tượng, tôi cho rằng đó là một sự cân bằng đáng giá, và là hầu như không chậm hơn là luôn gán.

+0

Tôi đã thử jsperf, sử dụng Chrome 23. Về cơ bản không có sự khác biệt. – DjebbZ

+0

@DjebbZ: Chính xác, làm điều dễ đọc nhất, không có lợi ích nào khác ngoại trừ sự chứng kiến ​​của bài kiểm tra cuối cùng. –

4

Không có một sự khác biệt chức năng.

Cấu trúc thứ hai chỉ (chủ quan) trông giống như nó hoạt động nhiều hơn cấu trúc đầu tiên.

Đối số phản đối là cấu trúc đầu tiên là mẫu chung, do đó dễ dàng hơn được công nhận để thực hiện công việc.

+0

Đồng ý, với một người không quá gần với JavaScript, ký hiệu đầu tiên sẽ trông dễ hiểu hơn . – naivists

5

Không có khác biệt thực sự, giả sử bạn có nghĩa là:

function fn(options) { 
    // type a 
    options = options || {}; 

    // type b 
    options || (options = {}); 
} 

Chủ yếu là vấn đề sở thích, tôi nghĩ rằng (a) là rõ ràng hơn một toàn bộ rất nhiều, tôi không thích những tuyên bố không có nhiệm vụ vào LHS .

1

Thực sự không có sự khác biệt chức năng giữa hai, mặc dù cơ học của chúng không giống nhau.

Biểu mẫu đầu tiên đặt biến cục bộ options bằng tham số options hoặc đối tượng trống nếu đối số có giá trị giả (ví dụ: nếu nó chưa được cung cấp).

Biểu mẫu thứ hai đánh giá giá trị của tham số options (nếu nó không bị lỗi), nếu không nó sẽ đánh giá kết quả của việc gán đối tượng rỗng cho tham số đó. Vì vậy, sự khác biệt từ hình thức đầu tiên là nếu options là sự thật, không có nhiệm vụ được thực hiện.

Cá nhân tôi xem xét các hình thức thứ hai là một phiên bản ít có thể đọc các

if(!options) { 
    options = {}; 
} 

mà là giống hệt nhau trong cả hai chức năng cơ.

1

Không có sự khác biệt chức năng, ý tưởng là options || (options = {}); là gần gũi hơn với những gì các lập trình viên thực sự muốn bày tỏ, mà thực sự là:

if (typeof options == "undefined") { 
    options = {}; 
} 

Nhà điều hành || được sử dụng để làm cho mã ngắn hơn, không mã rõ ràng hơn.

+0

Có khoảng cách khá giả và không xác định, vì vậy nếu bạn thực sự muốn ghi đè không xác định, hãy làm điều đó một cách rõ ràng. –

+0

@PhilH: Có, có một khoảng trống, nhưng không phải phiên bản mã nào cũng được trang bị để xử lý tất cả các giá trị trong khoảng trống. Cả hai phiên bản đều cho phép một số giá trị vô dụng trong ngữ cảnh này, ví dụ như 'true', trượt qua và để phần còn lại của mã choke trên chúng. – Guffa

+0

Rất đúng. Đây là một trong những nhược điểm của ngôn ngữ được nhập động. –

0

Chắc chắn chủ quan, nhưng tôi sẽ không sử dụng thứ hai.

Lý do: Tôi cảm thấy rằng các bài tập trong các biểu thức ở bất kỳ đâu sâu hơn cấp cao nhất = obfuscation.

Một số lập trình viên C như thế (trước đây tôi từng sử dụng), họ làm những việc như thêm parens để phân công rõ ràng hơn ... bằng cách làm cho toàn bộ biểu hiện trông không quen thuộc. Tại sao bận tâm nếu bạn có thể chỉ đơn giản?

Các rõ ràng nhất có lẽ sẽ là:

if (!options) options = {}; 
2

Có một sự khác biệt chức năng: một sử dụng var và loại kia thì không. Nếu có bất kỳ khả năng nào biến số options không tồn tại trong phạm vi hiện tại, thì tốt hơn hết là sử dụng var thay vì rủi ro options bị rò rỉ ra ngoài phạm vi bên ngoài.

Nếu tùy chọn được đảm bảo để tồn tại (ví dụ, trong một chức năng mà các thông số bao gồm options), hai báo cáo có chức năng giống hệt như vậy vấn đề làm giảm đến những giá trị phong cách tương đối của options = options || {} so options || (options = {}). Cá nhân tôi thấy sự khác biệt nhỏ: cả hai yêu cầu cùng một kiến ​​thức về cách hoạt động của nhà điều hành || của JavaScript, vì vậy khi bạn loại bỏ yếu tố đó khỏi phương trình, tôi có thể ưu tiên options = options || {} vì có thể đọc được dễ dàng hơn nhờ tính ngắn hơn và đơn giản hơn. Ý định của nhà phát triển có vẻ rõ ràng đối với tôi trong cả hai trường hợp.

+0

Có tất nhiên. Tôi quên thêm một chút mã để làm cho nó rõ ràng, trong đó biến 'options' thực sự tồn tại trong các paramaters của hàm. Vì vậy, trong khi điểm của bạn là rất hợp lệ, nó không có tác động trong trường hợp của tôi. – DjebbZ

Các vấn đề liên quan