Hành vi này của JavaScript được gọi là cẩu. Có một lời giải thích tốt về MDN (https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
Trong JavaScript, chức năng và biến được hoisted. Hoisting là hành vi của JavaScript về việc chuyển các khai báo đến đỉnh của một phạm vi (phạm vi toàn cục hoặc phạm vi chức năng hiện tại).
Điều đó có nghĩa là bạn có thể sử dụng hàm hoặc biến trước khi nó được khai báo hoặc nói cách khác: một hàm hoặc biến có thể được khai báo sau khi đã được sử dụng.
Về cơ bản, nếu bạn khai báo một biến như thế này:
console.log(s); // s === undefined
var s = 'some string';
s
khai sẽ được "treo" đến đầu phạm vi (ví dụ: sẽ không có ReferenceError
trên phù hợp với console.log
). Giá trị của biến số sẽ không được xác định tại thời điểm đó mặc dù.
Cũng vậy với giao một chức năng ẩn danh cho một biến, vì vậy:
console.log(f); // f === undefined
f(); // TypeError: f is not a function
var f = function() {}; // assigning an anonymous function as a value
f(); // ok, now it is a function ;)
Biến sẽ được kéo lên và do đó có thể nhìn thấy trong toàn bộ phạm vi, nhưng giá trị của nó, ngay cả khi đó là một chức năng, sẽ vẫn chưa được xác định - do đó sẽ xảy ra lỗi nếu bạn cố thực thi nó.
Mặt khác nếu bạn khai báo một tên chức năng:
console.log(f); // f === function f()
f(); // we can already run it
function f() {}; // named function declaration
nét Nó cũng sẽ được kéo lên, do đó bạn có thể chạy nó ngay cả trong dòng đầu tiên của phạm vi bạn đã tuyên bố nó.
Nguồn
2015-07-10 08:00:35
bản sao có thể có của [Chức năng và phạm vi chức năng Javascript] (http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting) – DTing
Có. Khi nhập [* ngữ cảnh thực thi *] (http://ecma-international.org/ecma-262/6.0/index.html#sec-execution-contexts), tất cả các khai báo hàm và biến được xử lý trước khi bất kỳ mã nào được chạy. – RobG