2014-11-26 22 views
5

Đối tượng kế thừa từ Function.prototype mà lần lượt kế thừa từ Object.prototype.Javascript :: Tại sao Object.hasOwnProperty ('người gọi') trả về true?

này là bởi vì trong nội bộ, đối tượng thực sự là một chức năng

function Object(){[native code]} 

đó là lý do chúng ta có thể viết mã như

var ob=new Object(); 

Object được thừa hưởng tài sản như 'gọi', 'arity', vv từ Function.prototype

Tuy nhiên (và đây là điều gây nhầm lẫn)

alert(Object.hasOwnProperty('caller')); //returns TRUE ! surprising 

không được trả về false vì Object thực sự thừa kế thuộc tính 'người gọi' từ Function.prototype?

Cùng một cách

alert(Function.hasOwnProperty('caller')); 
/*returns True. expected 'false' as Function object has no property of its own and inherits everything from Function.prototype*/ 

alert(Number.hasOwnProperty('caller')); //again returns true, unexpectedly 

Vì vậy, ai đó có bất kỳ ý tưởng về việc tại sao điều này xảy ra?

cảm ơn bạn rất nhiều. Tôi hy vọng tôi không nghe có vẻ ngây thơ

EDIT

cố gắng Object.getOwnPropertyNames(Object) thực sự trở 'caller' như một thuộc tính trực tiếp trên bản thân đối tượng. Vì vậy, Object.hasOwnProperty('caller') là thực tế chính xác

Nhưng, bây giờ câu hỏi là lý do tại sao trong tài liệu MDN, 'caller' được đề cập là được kế thừa từ Hàm. Vì vậy, nó chắc chắn dẫn đến sự nhầm lẫn.

Vì vậy, đây có phải là một số sai lầm trong tài liệu không? cảm ơn bạn.

EDIT-2

Tôi có thể đi đến kết luận rằng đối tượng có riêng của mình

caller, length, vv thuộc tính như thậm chí Object.lengthObject.__proto__.length là không giống nhau. Nó cần phải có được bằng nếu thực sự đối tượng được thừa kế tài sản dài từ [[prototype]] của nó, tức là Function.prototype nhưng nó không phải là trường hợp

Vấn đề là tại sao MDN đề cập rằng Object chỉ thừa hưởng caller, length, arity, vv từ đối tượng [[prototype]] của nó ? của nó một chút sai lệch IMHO

+0

Trong đó trình duyệt/JS engine nào 'Object.hasOwnProperty ('caller')' yield 'true'? Tôi không thể tái sản xuất trong Opera. – Bergi

+0

@Bergi trong Firefox hiện tại, ví dụ: – dsuckau

+0

trong chrome. – Sarabjeet

Trả lời

4

Từ MDN:

Một chức năng được tạo ra với một khai báo hàm là một đối tượng Function và có tất cả các thuộc tính, phương pháp và hành vi của các đối tượng Function.

Ở chế độ nghiêm ngặt, mọi chức năng đều có thuộc tính riêng callerarguments. Xem ES5 Spec 15.3.513.2.

trường hợp chức năng tương ứng với các chức năng nghiêm ngặt chế độ (13,2) và trường hợp chức năng tạo ra bằng cách sử dụng phương pháp Function.prototype.bind (15.3.4.5) đã tính đặt tên là “gọi” và “lý luận” rằng ném một Ngoại lệ TypeError.

+0

Uh, 'Đối tượng' có lẽ không phải là một hàm được tạo bằng khai báo hàm? – Bergi

+0

nhưng tôi không sử dụng chế độ nghiêm ngặt như Tôi không sử dụng 'sử dụng nghiêm ngặt; ' Thứ hai, vì vậy, ngay cả khi đối tượng Chức năng của nó? điều thậm chí chính đối tượng 'Hàm' không có bất kỳ thuộc tính riêng ** nào. Tất cả đều được thừa hưởng từ Function.prototype. Vì vậy, ngay cả khi Object là một chức năng, nó vẫn không nên cho thấy 'Object.hasOwnProperty ('người gọi');' là true – Sarabjeet

+1

@Sarabjeet Bạn không thể kiểm soát việc tạo ra 'Object'. Rõ ràng chúng được tạo ở chế độ nghiêm ngặt. Vui lòng đọc [13.2 Bước 19] (http://www.ecma-international.org/ecma-262/5.1/#sec-13.2). Các thuộc tính 'người gọi' và' đối số' sẽ được thêm vào khi tạo, không được kế thừa. – dusky

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