2013-02-22 24 views
5

Tôi đang đọc phần Môi trường thực thi/Môi trường thực tế của ECMA 262 5 specification. Nó nêu rõ những điều sau: (nhấn mạnh thêm)Biểu thức hàm có môi trường phạm vi/từ vựng riêng của mình

Môi trường Lexical là loại đặc điểm được sử dụng để xác định liên kết các định danh cho các biến và chức năng cụ thể dựa trên cấu trúc tổ hợp từ vựng của mã ECMAScript. Một môi trường Lexical bao gồm một bản ghi môi trường và một tham chiếu có thể null đến một môi trường bên ngoài. Thông thường một môi trường Lexical được kết hợp với một số cấu trúc cú pháp cụ thể của mã ECMAScript chẳng hạn như FunctionDeclaration, một mệnh đề WithStatement hoặc Catch của một TryStatement và một Môi trường Lexical mới được tạo ra mỗi khi mã được đánh giá.

Tôi nhận thấy rằng nó không nói gì về việc tạo môi trường từ vựng cho Biểu thức hàm. Là một môi trường từ vựng được tạo ra cho các biểu thức hàm, hay là một tạo ra chỉ cho các khai báo hàm? Tui bỏ lỡ điều gì vậy?

Chỉnh sửa: Tôi nhận thấy rằng mã chức năng sẽ có its own execution context, đó là lý do tại sao tôi cũng nhầm lẫn tại sao biểu thức hàm không được đề cập trong phần môi trường từ vựng.

+4

Vì danh sách các ví dụ bắt đầu bằng "chẳng hạn như", tôi không nghĩ rằng nó có ý định đầy đủ. – Pointy

+0

[Phần 13] (http://www.ecma-international.org/ecma-262/5.1/#sec-13) dường như gợi ý rằng các môi trường từ vựng mới chỉ được tạo ra cho các biểu thức hàm có tên (và không phải cho hàm ẩn danh biểu thức hoặc khai báo hàm). Nhưng tôi phải giải thích nó không chính xác. –

Trả lời

3

Vâng, mỗi chức năng được (§10.4.3) riêng của mình ExecutionContext khi được gọi (§13.2.1). Ngữ cảnh mới được khởi tạo với một mới LexicalEnvironment (được tạo bởi NewDeclarativeEnvironment, §10.2.2.2), lấy từ hàm [[Scope]] của hàm - tức là LexicalEnvironment nó được khai báo/"thể hiện" trong (§13).

Như @Pointy đã chỉ ra, câu bạn đã đánh cắp khi không liệt kê hết chúng: "... một số [cấu trúc] chẳng hạn như ...".

2

Hàm khởi tạo có phạm vi. Nó không quan trọng cho dù nó đã được khởi tạo như là một phần của một tuyên bố khai báo hàm hay một biểu thức khởi tạo hàm.

(Có lẽ chính xác hơn để nói rằng một chức năng khởi tạo có một phạm vi khi nó được gọi là, và rằng tất cả các cuộc gọi tạo ra một khác biệt phạm vi .)

3

Nếu tên được bao gồm trong FunctionExpression, tên đó sẽ trở thành một liên kết chỉ đọc để che bất kỳ khai báo bên ngoài nào có cùng tên. Nhưng ràng buộc đó có thể bị che khuất bởi một tham số chính thức hoặc khai báo cục bộ trong hàm. Một ràng buộc cho tên hàm chỉ được tạo cho tên FunctionExpressions và không cho ẩn danh FunctionExpressions hoặc FunctionDeclarations. Tên liên kết cho một FunctionDeclaration được tạo trong môi trường xung quanh VariableEnvironment.

Đây là một explantion chi tiết tham khảo spec ES5.1:

Có nhiều hơn một kỷ lục môi trường liên kết với một đối tượng hàm. Bất cứ khi nào một hàm được gọi là một DeclarativeEnvironmentRecord mới được tạo ra để chứa các ràng buộc cục bộ của lời gọi hàm cụ thể đó.Bản ghi đó sẽ trở thành cả VariableEnvironment và LexicalEnvironment ban đầu của ExecutionContext được tạo cho lời gọi đó. Điều này được quy định trong phần 10.4.3.

Khi bản ghi môi trường này được tạo ra, "môi trường bên ngoài" được đặt thành giá trị của thuộc tính bên trong [[Phạm vi]] của đối tượng hàm đang được gọi. (dòng 5, 10.4.3) Môi trường bên ngoài cung cấp các ràng buộc cho tất cả các khai báo phi địa phương. [[Phạm vi]] được đặt khi một đối tượng hàm được tạo (xem các ngữ nghĩa trong phần 13 và cũng là 13.2). Vì vậy, mỗi lời gọi riêng biệt của một đối tượng hàm cụ thể có một môi trường cục bộ khác nhau nhưng tất cả các lời gọi hàm đó chia sẻ cùng một [[Phạm vi] bên ngoài.

Đối với hầu hết các chức năng, [[Phạm vi]] đã chụp chỉ đơn giản là LexicalEnvironment của ExecutionContext đã hoạt động khi hàm được tạo. Tuy nhiên FunctionExpressions bao gồm số Mã định danh làm tên hàm có thêm DeclarativeEnvironmentRecord chèn vào phần đầu của chuỗi [[Scope]]. (xem các bước 1-3 của thuật toán thứ ba trong phần 13).

Bản ghi môi trường bổ sung này được sử dụng để ghi lại ràng buộc cho tên hàm được đưa ra trong FunctionExpression.

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