2013-03-25 26 views
7
Object.prototype.doSomething = function(p) { 
    this.innerHTML = "<em>bar</em>"; 
    this.style.color = "#f00"; 
    alert(p); 
}; 

document.getElementById("foo").doSomething("Hello World"); 

<div id="foo"><strong>foo</strong></div>Có ổn không khi xác định hàm nguyên mẫu trên đối tượng trong Javascript?

Đoạn mã trên hoạt động tốt.

Nhưng tôi nhớ rằng tôi đã thấy điều này ở đâu đó: Do not mess with native Object. tốt, một cái gì đó tương tự.

Vì vậy, bạn có thể xác định hàm nguyên mẫu trên Đối tượng? Có lý do gì mà tôi không nên làm điều này?

+0

Đây có phải là một thư viện những người khác sẽ được tiêu thụ? Hoặc cho mã ứng dụng của riêng bạn? –

+0

Tôi đang viết một thư viện nhỏ mà những người khác có thể đang sử dụng. Như các câu trả lời được đề xuất dưới đây, tôi nghĩ rằng tôi không nên làm điều này, bất kể mã được viết cho ai. – user1643156

Trả lời

5

Cách duy nhất an toàn để thêm vào Object.prototype là sử dụng phương pháp ES5 Object.defineProperty để tạo ra một không đếm được tài sản:

Object.defineProperty(Object.prototype, 'doSomething', { 
    value: function(p) { ... }, 
    enumerable: false, // actually the default 
}); 

Điều này đảm bảo rằng các tài sản mới không xuất hiện nếu bạn làm for (key in object) .

Lưu ý rằng chức năng này không thể được tin cậy một cách đáng tin cậy vì các thuộc tính không thể đếm được không tồn tại trong các phiên bản trước của ECMAScript/JavaScript.

Trong mọi trường hợp, nếu phương pháp của bạn chỉ áp dụng cho các phần tử trang HTML, bạn nên thêm điều này vào Element.prototype thay vì Object.prototype, mặc dù trình duyệt cũ hơn (IE) có thể khiếu nại nếu bạn làm điều này.

+0

Không phải là ['hasOwnProperty'] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) là một thực hành tốt nhất hiện nay dù sao? –

+0

@RoatinMarth no, IMHO 'hasOwnProperty' là _old_ thực hành tốt nhất. Trong trình duyệt ES5, nó không cần thiết. Bất kỳ mã nào không rõ ràng gây rối với 'Object.prototype' sẽ bị trục xuất. Ngay cả jQuery cũng bỏ qua bài kiểm tra 'hasOwnProperty' và nói rõ rằng nó sẽ thất bại nếu bạn sử dụng mã lạm dụng nó. – Alnitak

+0

'các thuộc tính không thể đếm được không tồn tại trong các phiên bản trước của Javascript.' phiên bản nào bạn có nghĩa là trước'? – user1643156

1

Nói chung không phải là một ý tưởng hay. Chức năng đó hiện có sẵn trên mọi thứ trong ứng dụng của bạn sử dụng mẫu Object (rất nhiều) và sẽ hiển thị trong các hàm liệt kê proto Object.

Một lựa chọn tốt hơn là xác định một nguyên mẫu riêng biệt:

function MyObject { 
    ... 
} 

MyObject.prototype.doSomething = function() { 
    ... 
} 

var myObj = new MyObject(); 
1

Nếu bạn thêm công cụ để nguyên mẫu đối tượng, bạn sẽ mất các chức năng đối tượng lặp thoải mái sử dụng for p in obj, vì tính đếm được bạn đã thêm được lặp qua như cũng trên tất cả các đối tượng.

Ví dụ:

Object.prototype.doSomething = function(p) { 
    this.innerHTML = "<em>bar</em>"; 
    this.style.color = "#f00"; 
    alert(p); 
}; 

for (p in {foo:"bar"}){ 
    console.log(p); 
} 

//foo 
//doSomething 

Thật bất ngờ, bạn cũng sẽ nhận doSomething đăng nhập. Để sửa lỗi này, bạn sẽ phải thêm một kiểm tra hasOwnproperty khi lặp qua đối tượng của bạn, nhưng rủi ro ở đây là bạn có thể phá vỡ mã khác không mong đợi một đối tượng thuần túy có các thuộc tính khác với các thuộc tính được chỉ định trong chữ.

+0

vì các thuộc tính _enumerable_ bạn đã thêm ... – Alnitak

+0

@Alnitak Đã cập nhật, cảm ơn. –

0

lựa chọn khác là gọi một phương pháp, được xác định không phải là một nguyên mẫu đối tượng phương pháp luận

function doSomething(p) { 
    this.innerHTML = "<em>"+p+"</em>"; 
    this.style.color = "#f00"; 
    alert(p); 
}; 

//

doSomething.call(document.getElementById("foo"),"Hello World"); 
Các vấn đề liên quan