Điều này không có gì để làm với các chức năng mũi tên. Thay vào đó, các hàm thông thường (và varkhai báo) được nâng lên ; bất kể bạn viết chúng ở đâu, chúng sẽ được chuyển lên đầu phạm vi của chúng. Thực tế, cả hai mẫu mã đều hoàn toàn giống nhau và chúng trông như thế này:
var increment; // hoisted
function increment() { // hoisted
alert("normal")
}
increment = () => { // the assignment itself is unaffected
alert("arrow")
}
increment(); //prints arrow
Phần chuyển nhượng var increment = ...xảy ra sau chức năng nâng và varkhai báo, trong cả hai trường hợp. Bất kể nơi bạn thực sự đã viết function increment() { }khai báo, nó được nâng lên trên dòng thực hiện gán cho incrementbiến.
Đây là lý do tại sao đoạn mã sau vẫn hoạt động, mặc dù hàm rõ ràng được xác định sau khi được sử dụng:
increment(); //prints normal
function increment(){
console.log("normal")
}
Nếu bạn muốn so sánh like với like, bạn cần so sánh var increment = () => { ... }với var increment = function () { ... }, đó là hai bài tập. Các kết quả trông như thế này:
var increment = () => { console.log('arrow'); }
var increment = function () { console.log('normal'); }
increment(); # normal
đấu với
var increment = function () { console.log('normal'); }
var increment = () => { console.log('arrow'); }
increment(); # arrow
Trong cả hai trường hợp, có một var increment;tuyên bố được nâng lên , và sau đó các bài tập xảy ra theo thứ tự chúng được viết, nghĩa là bài tập cuối cùng sẽ thắng.
Bên cạnh đó, đây là một trong những lý do chính để thích let x = () => { }khai báo hàm kiểu "cũ". letkhông được nâng lên, do đó, hàm tồn tại từ thời điểm mà bạn mong đợi một cách tự nhiên, thay vì nhảy lên trên phạm vi của bạn.