2012-03-11 30 views
13

jQuery có phương thức extend rất gọn gàng, kết hợp 2 đối tượng thành một.Tại sao chuyển một đối tượng rỗng vào phương thức mở rộng của jQuery?

Trên jQuery Plugins authoring page họ cho thấy một ví dụ như sau:

var settings = $.extend({ 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, options); 

Tuy nhiên, tôi đã nhìn thấy nhiều plugin vượt qua một đối tượng rỗng như tham số đầu tiên, như vậy:

var settings = $.extend({}, { 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, options); 

As far như tôi có thể nói, cả hai đều làm điều tương tự. Sự khác biệt duy nhất là nếu defaults sẽ được lưu trữ trong biến riêng của mình:

var defaults = { 
    'location'   : 'top', 
    'background-color' : 'blue' 
}, 
settings = $.extend({}, defaults, options); 

Bằng cách này, bạn luôn có thể truy cập mặc định của bạn mà không có họ được ghi đè bởi các options.


Dưới đây là câu hỏi: Tại sao rất nhiều tác giả Plugin lựa chọn để vượt qua một đối tượng trống để extend, ngay cả khi họ không lưu trữ các giá trị mặc định trong một biến?

Tôi có thiếu gì đó không?

+1

vẻ vô nghĩa đối với tôi. Nó làm cho một dân cư, sao chép nó vào một sản phẩm nào, và loại bỏ nó. Ví dụ thứ ba của bạn cho thấy một lý do hợp lệ. Tôi đoán mọi người làm điều đó bởi vì họ không nghĩ về những gì họ đang làm. –

+0

@amnotiam Đó là chính xác những gì tôi đang nghĩ, nhưng tôi đã thấy * rất nhiều plugin * làm điều này. Rõ ràng tôi đang thiếu một cái gì đó ... –

+0

Không, tôi nghĩ rằng rắc rối là bạn đang * nhận * một cái gì đó. –

Trả lời

8

Có thể lý do (cho ví dụ thứ hai) ...

  • Kế thừa sự thiếu hiểu biết ...(thấy nó được thực hiện theo cách đó, và sao chép các thực hành)

  • Intrinsic ngu dốt ... (đã thấy nó được thực hiện đúng như trong khối mã cuối cùng của bạn, nhưng thay thế các đối tượng được lưu trữ với một đối tượng on-the-fly và không biết rằng đối tượng trống phải được loại bỏ)

  • Sự nóng lên toàn cầu.

  • Thiếu sự chú ý đến từng chi tiết ... (tương tự như chỉ 2, biết nó không phải là cần thiết nhưng không bao giờ thực sự mất thời gian để kiểm tra mã)

  • làm mát toàn cầu.

  • mã hóa Quá phòng thủ ... (sợ rằng giá trị mặc định một ngày nào đó có thể được làm lại vào một đối tượng tái sử dụng, và sợ rằng đối tượng trống sẽ không được chèn vào thời điểm đó)

  • phát triển jQuery luôn luôn làm những gì các giọng nói cho họ biết ;-)

Nhìn chung, bạn nói đúng. Đối tượng ở giữa được tạo ra, được sao chép vào một đối tượng trống, sau đó bị loại bỏ. Đó là một thực hành không cần thiết và lãng phí.

9

Mở rộng là một chức năng rất hữu ích để sao chép các đối tượng.

Ví dụ xem xét việc này:

foo = {'foo':'a'} 
f = foo 
f.foo = 'hello' 
console.log(f) 
    Object {foo="hello"} 
console.log(foo) 
    Object {foo="hello"} 

f = $.extend({},foo) 
f.foo = 'hello world' 
console.log(f) 
    Object {foo="hello world"} 
console.log(foo) 
    Object {foo="hello"} 

Như bạn có thể nhìn thấy $ .extend thực sự sao chép các đối tượng.

EDIT

Lý do tại sao các tham số đầu tiên phải là một đối tượng rỗng là vì cách extend công trình. Sau đây là cách jQuery định nghĩa extend:

jQuery.extend(target [, object1] [, objectN]) 
    target An object that will receive the new properties 
      if additional objects are passed in or that will 
      extend the jQuery namespace if it is the sole argument. 
    object1 An object containing additional properties to merge in. 
    objectN Additional objects containing properties to merge in. 

Và thêm cụm từ này là rất quan trọng:

Hãy ghi nhớ rằng đối tượng mục tiêu (số đầu tiên) sẽ được sửa đổi, và cũng sẽ được trả từ $ .mở rộng().

Vì vậy, bằng cách chuyển thông số {} làm tham số đầu tiên, đối tượng trống đó được mở rộng và sau đó trả về.

Quay lại ví dụ của bạn về settings = $.extend({}, defaults, options);. Nếu bạn thay đổi nó thành settings = $.extend(defaults, options);, các cài đặt sẽ giống nhau tuy nhiên ở đây các giá trị mặc định cũng sẽ bị thay đổi. Đó là lý do tại sao bạn cần đối số đầu tiên là {}.

+0

Cảm ơn bạn đã cập nhật, nhưng đó chính xác là những gì tôi đã mô tả trong câu hỏi của mình. Tôi hiểu lợi ích của việc sử dụng một đối tượng trống trong ví dụ thứ 3 của tôi. Điều tôi đang cố hiểu là sự khác biệt giữa ví dụ thứ nhất và thứ 2 của tôi ... –

+0

Tôi đoán tôi đã không theo dõi câu hỏi của bạn. Tôi thích câu trả lời của cộng đồng wiki là tại sao mọi người thích viết ví dụ # 2. – miki725

+0

Cuối cùng tôi nhận ra bạn đúng khi tôi vô tình làm hỏng đối tượng đầu tiên của tôi trong '$ .extend {}' mà tôi không mong đợi nó được thay đổi. – jasonslyvia

3

Một cách khác để đưa những gì miki nói:

var defaults = { 
    one: 'foo', 
    two: 'bar' 
}; 

var options = { 
    two: 'apples', 
    three: 'bananas' 
}; 

// The safe way to extend 
var settings = $.extend({}, defaults, options); 

console.log(settings); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(defaults); // {one: 'foo', two: 'bar'} 
console.log(options); // {two: 'apples', three: 'bananas'} 
console.log(settings === defaults); // false 

// Careless way to extend 
var settings = $.extend(defaults, options); 

console.log(settings); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(defaults); // {one: 'foo', two: 'apples', three: 'bananas'} 
console.log(options); // {two: 'apples', three: 'bananas'} 
console.log(settings === defaults); // true 
+0

Một lần nữa, đây chính xác là những gì tôi đã nêu trong câu hỏi của mình. Xem đoạn mã thứ 3 của tôi (và đoạn trước của nó). –

+0

Tôi đoán tôi không hiểu bạn là câu hỏi sau đó. Bạn hỏi: Tại sao rất nhiều tác giả plugin chọn để vượt qua một đối tượng trống để mở rộng? Câu trả lời của tôi có lẽ là lý do tại sao. Việc lưu trữ các giá trị mặc định của bạn trong một biến sẽ không ngăn chúng bị ghi đè. – ianstarz

+0

Câu hỏi của tôi là: tại sao nhiều tác giả plugin chọn chuyển một đối tượng trống để mở rộng * mặc dù chúng không lưu trữ các giá trị mặc định trong một biến *? Tôi đã cập nhật câu hỏi của mình để làm rõ điều đó. –

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