2012-05-01 43 views
6

Tôi đọc ECMA-262 tài liệu tham khảo mới nhất, phiên bản 5.1 tháng Sáu năm 2011.Là một hàm tạo luôn luôn là một đối tượng hàm?

Trong phần 8.6.2 bảng 9 chúng tôi có liên quan đến các [[Xây dựng]] tài sản nội bộ:

Tạo một đối tượng . Được viện dẫn thông qua toán tử mới. Các đối số đối với SpecOp là các đối số được truyền cho toán tử mới . Các đối tượng thực hiện phương thức bên trong này là được gọi là các hàm tạo.

Tiêu chuẩn không nói rằng hàm tạo phải là đối tượng Hàm. Vì vậy, chúng ta có thể có một đối tượng constructor không phải là một đối tượng hàm?

Link to the standard as requested

+0

Bạn có thể liên kết với tài liệu đặc tả không? Tôi không nghĩ rằng nhiều người sẽ có thể trả lời mà không có một ngữ cảnh đầy đủ hơn cho báo giá bạn đã cung cấp. (Câu hỏi thú vị!) – apsillers

+2

Bạn có thể quan tâm đến [Chú thích ES5] (http://es5.github.com/) là một chuyển đổi HTML của các tiêu chuẩn PDF ECMA-262 5.1. Nó có các phần neo như phần cho [Mục 8.6.2] (http://es5.github.com/#x8.6.2). –

+0

nếu tôi nhớ chính xác, Crockford nói rằng nói chung, bằng cách sử dụng một constructor không phải là một mô hình tốt trong JS – thepoosh

Trả lời

3

Trong khi thuật ngữ "Constructor" được định nghĩa (như @RobG pointed out), không có gì ngăn cản đối tượng không "Constructor" có phương thức [[Construct]].

Điều này hơi khó hiểu. Nó có nghĩa là bạn có thể sử dụng toán tử new trên một đối tượng không phải là Function (do đó không phải là "hàm tạo" theo 4.3.4 ), nhưng thực sự cung cấp phương thức [[Construct]].

Lưu ý rằng không có đối tượng chuẩn nào đủ điều kiện cho điều đó, nhưng thực tế là host objects. Một plugin trình duyệt như Java có thể tiếp xúc với một số đối tượng như vậy:

new java.lang.String(); // it works, so java.lang.String has a [[Construct]] method 
java.lang.String instanceof Function // false 
Object.prototype.toString.call(java.lang.String).indexOf('Function') // -1 

Lưu ý rằng typeof java.lang.String lợi nhuận "function" mặc dù java.lang.String không phải là một hàm. Điều này đúng theo 11.4.3 (nó là đối tượng lưu trữ với phương thức [[Call]])

+0

Tiếp theo, bạn sẽ bị lạc trong ngữ nghĩa "chức năng là gì?". Thông số này chỉ bao gồm các đối tượng gốc (bao gồm cả các phần tử tích hợp sẵn) và cho phép các đối tượng lưu trữ một cách rõ ràng để làm những gì chúng thích. Nó có ý nghĩa đối với những người sáng tạo của các đối tượng lưu trữ theo ECMA-262, nhưng có rất nhiều trường hợp họ không có, tốt đẹp để xem một ví dụ không phải là IE. :-) – RobG

+0

@RobG Không chắc chắn những gì bạn đang cố gắng để nói ở đây. [8.6.2] (http://es5.github.com/#x8.6.2) bao gồm các đối tượng lưu trữ ở một mức độ nhất định. Ngoài ra, thuật ngữ "hàm" được định nghĩa trong [4.3.24] (http://es5.github.com/#x4.3.24) – user123444555621

+0

@RobG Tôi nghĩ rằng vấn đề là spec không hoàn toàn nhất quán. – Roland

4

Câu trả lời cực kỳ đơn giản. ES5 § 4.3.4 nói:

Constructor Function object that creates and initialises objects.

Vì vậy, có bạn có nó, theo định nghĩa chỉ là một chức năng có thể là một nhà xây dựng. Tuy nhiên, có khả năng có các đối tượng lưu trữ hoạt động như các hàm tạo không có bất kỳ thuộc tính nào khác của các đối tượng hàm gốc (ví dụ: đối tượng XMLHttpRequest gốc trong IE đã được triển khai trong ActiveX).

+0

Tôi chấp nhận điều này làm câu trả lời. IMHO spec không hoàn toàn rõ ràng trong đó có vẻ như một đối tượng mà không phải là một chức năng vẫn có thể có một [[Xây dựng]] tài sản nội bộ, ít nhất là bảng 9 tham chiếu trong câu hỏi không rõ ràng cấm này. Nếu bất cứ ai biết ai là tác giả của spec là tôi muốn viết cho anh ta một email và yêu cầu làm rõ. – Roland

0

Để thêm vào Pumbaa80 answer (điều này sẽ quá dài để nhận xét).

Sự nhầm lẫn được tăng 13.2.2 theo đó khi một hàm củaconstruct được thực hiện hoạt động call của nó đã được thực hiện (nhưng nó không nói gì đã được thực hiện khi construct của một đối tượng đó không phải là một hàm được thực hiện). Bây giờ, các đối tượng triển khai call có thể gọi chức năng các đối tượng theo 9.11.

Cũng theo 4.2 "một hàm là đối tượng có thể gọi". Nhưng tất nhiên điều này không ngụ ý rằng mọi đối tượng có thể gọi là một hàm.

Vì vậy, nếu tôi có quyền này, các đối tượng chức năng có thể có phương thức Construct và cũng là phương pháp Call. java.lang.String sẽ là một ví dụ như vậy.

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