Đây là Phạm vi tĩnh. Các câu lệnh trong một hàm được đặt trong phạm vi hàm đó.
Javascript có một hành vi kỳ quặc, tuy nhiên, đó là nếu không có sự var từ khóa, bạn đã ngụ ý một biến toàn cầu. Đó là những gì bạn nhìn thấy trong bài kiểm tra của bạn. Biến "d" của bạn có sẵn bởi vì nó là một hàm toàn cục ngụ ý, mặc dù được viết bên trong phần thân của hàm.
Ngoài ra, để trả lời phần thứ hai của câu hỏi: Một hàm tồn tại ở bất kỳ phạm vi nào được khai báo, giống như một biến.
Sidenote: Có thể bạn không muốn biến toàn cục, đặc biệt là không có biến thể ngụ ý. Bạn nên luôn sử dụng từ khóa var, để tránh nhầm lẫn và giữ mọi thứ sạch sẽ.
Sidenote: Tiêu chuẩn ECMA có lẽ không phải là nơi hữu ích nhất để tìm câu trả lời về Javascript, mặc dù nó chắc chắn không phải là tài nguyên xấu. Hãy nhớ rằng javascript trong trình duyệt của bạn chỉ là một thực hiện tiêu chuẩn đó, do đó, các tài liệu tiêu chuẩn sẽ được cung cấp cho bạn các quy tắc được (chủ yếu) tiếp theo là những người triển khai khi động cơ javascript đã được xây dựng. Nó không thể cung cấp thông tin cụ thể về các triển khai mà bạn quan tâm, cụ thể là các trình duyệt chính. Có một vài cuốn sách nói riêng sẽ cung cấp cho bạn thông tin rất trực tiếp về cách triển khai javascript trong các trình duyệt chính hoạt động. Để minh họa sự khác biệt, tôi sẽ bao gồm các đoạn trích bên dưới từ cả đặc tả ECMAScript và một cuốn sách trên Javascript. Tôi nghĩ bạn sẽ đồng ý rằng cuốn sách đưa ra câu trả lời trực tiếp hơn.
Dưới đây là từ ECMAScript Ngôn ngữ Đặc điểm kỹ thuật:
10,2 Bước vào một bối cảnh Execution
Mỗi chức năng và xây dựng cuộc gọi vào một bối cảnh thực hiện mới, thậm chí nếu một hàm được tự xưng đệ quy. Mỗi lần thoát đều thoát khỏi ngữ cảnh thực thi . Một ngoại lệ bị ném, nếu không bị bắt, cũng có thể thoát ra một hoặc ngữ cảnh thực thi khác.
Khi kiểm soát vào một bối cảnh thực hiện, chuỗi phạm vi được tạo ra và khởi tạo, biến instantiation được thực hiện, và giá trị này được xác định.
Các khởi động của chuỗi phạm vi, biến instantiation, và xác định giá trị này phụ thuộc vào loại mã đang được nhập vào.
Dưới đây là từ O'Reilly Javascript: The Definitive Guide (5th Edition):
8.8.1 Phạm vi từ vựng
Chức năng trong JavaScript là lexically chứ không phải là động scoped. Điều này có nghĩa là chúng chạy trong phạm vi mà chúng được xác định, không phải phạm vi mà từ đó chúng được thực thi. Khi một hàm được xác định, phạm vi hiện tại chuỗi được lưu và trở thành một phần của trạng thái nội bộ của hàm . ...
Rất khuyến khích cho bao gồm các loại câu hỏi là Douglas Crockford của cuốn sách:
JavaScript, The Good Parts http://oreilly.com/catalog/covers/9780596517748_cat.gif
Javascript, The Good Parts, cũng từ O'Reilly.
Chính xác - nói rộng 'hàm a() {}' tương đương với 'var a = function() {}' (có một số khác biệt ngữ nghĩa nhỏ, nhưng không có gì quá đáng kể). – olliej
cảm ơn bạn, nhưng nơi nào tôi tìm thấy các xác nhận sau trong tiêu chuẩn ECMAScript (hoặc nó bị thiếu?): "Các câu lệnh trong một hàm được đặt trong phạm vi hàm đó." Trong ấn tượng của tôi, ngữ nghĩa của "var a = function() {}" được xác định rõ, nhưng không phải là câu lệnh "function a() {...}". –
Tiêu chuẩn ECMAScript sẽ chỉ cung cấp cho bạn các nguyên tắc để triển khai ECMAScript, trong đó Javascript chỉ là một thành viên gia đình. Vì vậy, bạn sẽ không tìm thấy tuyên bố chính xác đó, nhưng có những tài nguyên khác có thể giúp bạn. Xem ghi chú bổ sung của tôi ở trên. – keparo