Hướng dẫn hoisting javascript la gì
- "Hoisting" là hành động mặc định của JavaScript, nó sẽ di chuyển những câu lệnh khai báo tên biến lên vị trí đầu tiên trong phạm vi (lên đầu tập tin hiện tại hoặc lên đầu hàm hiện tại) Show - Chúng ta có một đoạn mã như sau: Xem ví dụ- JavaScript sẽ tự động chuyển các câu lệnh khai báo tên biến lên vị trí đầu tiên trong phạm vi. - Do đó, đoạn mã phía trên sẽ có ý nghĩa tương tự như đoạn mã sau: Xem ví dụ- Lưu ý: "Hoisting" chỉ di chuyển phần khai báo tên biến lên vị trí đầu tiên trong phạm vi, còn phần gán giá trị thì không được di chuyển lên. - Hai đoạn mã bên dưới có ý nghĩa khác nhau: Đoạn mã 1Đoạn mã 2 Xem ví dụ Xem ví dụ- Đoãn mã 2 sẽ có ý nghĩa tương tự như đoạn mã sau: Xem ví dụ2) Công dụng của Hoisting- Như chúng ta đã biết, nếu sử dụng một biến trong khi nó chưa được khai báo thì câu lệnh sử dụng biến đó sẽ bị lỗi. - Hoisting giúp ta tránh tình trạng bị lỗi khi sử dụng những biến chưa được khai báo. - Ví dụ: Xem ví dụ Xem ví dụ- Ngoài ra, nếu đang ở trong một hàm mà ta gán giá trị cho biến chưa được khai báo thì biến đó sẽ trở thành biến toàn cục. - Hoisting giúp ta tránh tình trạng tạo ra những biến toàn cục không mong muốn. Có thể bạn quan tâm- Ví dụ: Xem ví dụ Xem ví dụVậy tóm lại: Để đảm bảo an toàn, tránh tình trạng bị lỗi do sử dụng những biến chưa được khai báo hoặc vô tình tạo ra biến toàn cục không mong muốn, ta có thể khai báo lại một lần nữa các tên biến ở cuối phạm vi (cuối tập tin hoặc cuối hàm) Hoisting là khái niệm chỉ việc mọi khai báo biến (với từ khóa var) sẽ được chuyển lên trên cùng của hàm. Để kiểm tra, tôi thử ví dụ sau trong Chrome Developer Tools: (function(){ console.log(foo); })(); >> ReferenceError: foo is not defined Oops! Tất nhiên là nó sẽ ra lỗi [email protected]#$% Hãy thử một ví dụ khác: (function(){ console.log(foo); var foo = "hello"; })(); >> undefined ‘undefined’ thay vì lỗi? Nguyên nhân là do việc khai báo biến foo đã được chuyển lên trên cùng. Đoạn code trên thực tế được chuyển thành như sau khi chạy: (function(){ var foo; console.log(foo); foo = "hello"; })(); >> undefined Tất nhiên chỉ có khai báo biến được chuyển lên đầu hàm, còn các biểu thức gán sẽ vẫn nằm tại vị trí cũ. Đối với các trường hợp biến được khai báo trong các khối lệnh như if, for, while, switch,… cũng không ngoại lệ. Đó là kết quả (hoặc cũng có thể là nguyên nhân) của việc:
(function(){ console.log(foo); if(false){ var foo = "hello"; } })(); >> undefinedFunction Declaration và Function Expression Trước tiên ta cần phân biệt hai khái niệm này: // Function Declaration: function foo(){ // code } // Function Expression: var foo = function(){ // code }; Cả hai phương pháp tạo hàm này đều bị ảnh hưởng bởi “hoisting”, tuy nhiên có một điểm khác nhau quan trọng giữa chúng. Để trả lời, bạn có thể xem và dự đoán đoạn code sau sẽ in gì ra màn hình: (function(){ var foo = 1; (function(){ console.log(foo); var foo = 2; })(); console.log(foo); })(); Nếu chưa biết về hoisting, bạn có thể đưa ra kết quả sai. Câu trả lời chính xác là ‘undefined’. Nguyên nhân là do bạn khai báo lại (với từ khóa var) biến foo bên trong hàm con. Nếu bạn không khai báo lại, hàm con sẽ sử dụng biến foo của ngữ cảnh bên ngoài. Một ví dụ khác với hàm: (function(){ console.log(foo()); // 3 var foo = function() { return 1; }; function foo() { return 2; }; function foo() { return 3; }; })(); >> 3 Kết quả xuất ra có thể nằm ngoài dự đoán của bạn do hàm được định nghĩa cuối cùng sẽ ghi đè lên các hàm cùng tên được định nghĩa trước nó. Hãy tưởng tượng bạn có một đoạn javascript rất dài, bạn khai báo biến tại những chỗ mà bạn bắt đầu dùng nó, bạn quên rằng tên biến này đã được dùng hoặc nhầm lẫn giữa các scope với nhau. Kết quả là nó nhảy ra một lỗi hoặc tệ hơn là nó … âm thầm chờ đợi và xuất hiện khi đưa cho khách hàng. Vậy một best practice mà bạn nên tập từ bây giờ là: Trong bài này chúng ta sẽ tìm hiểu hoisting trong Javascript, qua đó sẽ giúp bạn hiểu khái niệm hosting là gì, và cơ chế hoạt động của hosting trong ngôn ngữ javascript. Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức. Hoisting là vấn đề liên quan đến cách khai báo biến trong Javascript. Theo quy tắc chung của hầu hết các ngôn ngữ lập trình, để sử dụng một biến thì bạn phải khai báo nó trước. Nhưng javascript thì lại khác, có một số trường hợp bạn có thể sử dụng biến rồi mới khai báo sau. Lý do là gì thì chúng ta cùng tìm hiểu ngay nhé. 1. Hoisting trong javascript là gì?Khi bạn thực thi một đoạn mã javascript thì trình biên dịch sẽ tạo ra một bối cảnh thực thi chung, ta gọi là global execution context. Bối cảnh thực thi này sẽ có hai giai đoạn, thứ nhất là tạo và thứ hai là thực thi. Bài viết này được đăng tại [free tuts .net] Trong giai đoạn tạo thì javascript sẽ di chuyển các khai báo biến lên đầu của đoạn mã, giúp cho chương trình không bị lỗi khi sử dụng biến trước khi khai báo. Tính năng này ta gọi là tính năng lưu trữ trong javascript, và trong tiếng Anh gọi là Hoisting. 2. Biến hoisting trong javascriptTrong Javascript, bạn có thể định nghĩa một biến sau khi sử dụng nhờ tính năng hoisting. Javascript sẽ di chuyển toàn bộ các khai báo biến lên đầu chương trình. Vì vậy, những dòng code có sử dụng biến mà chưa khai báo sẽ không bị lỗi. // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kết quả: Domain là freetuts.net document.write("Domain là: " + domain); // Khai báo var domain; // Kết quả: Domain là freetuts.net document.write(" Nếu trong lúc khởi tạo mà bạn gán giá trị cho biến thì kết quả sẽ khác // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kêt quả: Domain là freetuts.net document.write("Domain là: " + domain); // Khai báo var domain = 'techtuts.net'; // kêt quả: Domain là freetuts.net document.write(" Nếu khai báo biến trước khi sử dụng thì ta vẫn có kết quả giống nhau. // Khai báo var domain; // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kết quả: Domain là freetuts.net document.write("Domain là: " + domain); // Kết quả: Domain là freetuts.net document.write(" Trong ví dụ thứ 3 này thì ta đã khai báo biến trước rồi mới sử dụng sau. Điều này tuân thủ theo quy tắc tạo biến rồi mới sử dụng của hầu hết các ngôn ngữ lập trình. Nó giúp chương trình trở nên sáng và logic hơn. 3. Từ khóa let và var trong hoistingViệc sử dung từ khóa let và var để khai báo một biến sẽ có sự khác biệt trong hoisting. Sử dụng var: Nếu biến chưa gán giá trị thì sẽ trả về undefined. console.log(counter); // undefined var counter = 1; Đoạn mã trên sẽ tương đương với đoạn mã dưới đây. var counter; console.log(counter); // undefined counter = 1; Sử dụng let: Nếu biến chưa gán giá trị thì sẽ xuất hiện thông báo lỗi Cannot access before initialization. console.log(counter); let counter = 1; Kết quả: "ReferenceError: Cannot access 'counter' before initialization Lỗi này muốn nói rằng biến counter đã được định nghĩa trong bộ nhớ heap nhưng chưa được khởi tạo. 4. Hàm hoisting trong javascriptCũng giống như các biến, công cụ JavaScript cũng lưu trữ các khai báo hàm. Nó sẽ di chuyển các khai báo hàm lên đầu của chương trình. let x = 20, y = 10; let result = add(x,y); console.log(result); function add(a, b){ return a + b; } Trong ví dụ này thì mình đã sử dụng hàm add rồi mới khai báo sau. Tuy nhiên, javascript vẫn không trả về một lỗi nào cả. Lý do là cơ chế hoisting của javascript đã di chuyển các khai báo hàm lên đầu rồi mới thực thi chương trình. Có nghĩa là đoạn code dưới đây sẽ tương đương: function add(a, b){ return a + b; } let x = 20, y = 10; let result = add(x,y); console.log(result); 5. Hoisting trong biểu thức hàmBiểu thức hàm hay còn gọi là function expressions. Nó là một hàm được khai báo bằng cách gán vào một biến. var add = function(x, y) { return x + y; } Hàm add chính là một function expressions. Quay trở lại bài toán. Câu hỏi là chuyện gì sẽ xảy ra nếu ta sử dụng một function expressions trước rồi mới khai báo sau? Hãy xem ví dụ dưới đây. // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kêt quả: Domain là freetuts.net document.write("Domain là: " + domain); // Khai báo var domain = 'techtuts.net'; // kêt quả: Domain là freetuts.net document.write("0 Chạy đoạn code này thì kết quả sẽ xuất hiện lỗi: // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kêt quả: Domain là freetuts.net document.write("Domain là: " + domain); // Khai báo var domain = 'techtuts.net'; // kêt quả: Domain là freetuts.net document.write("1 Lý do rất đơn giản. Javascript sẽ xem biết add là một biến thông thường, nên khi nó đưa lên đầu thì sẽ là một biến chứ không phải là một hàm. Vì vậy, khi sử dụng sẽ xuất hiện lỗi add is not a function. 6. Hoisting trong arrow functionCú pháp tạo arrow function sẽ như sau: // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kêt quả: Domain là freetuts.net document.write("Domain là: " + domain); // Khai báo var domain = 'techtuts.net'; // kêt quả: Domain là freetuts.net document.write("2 Chính vì vậy, nếu bạn sử dụng arrow function trước rồi mới khai báo thì sẽ bị lỗi // Gán nhưng chưa khai báo biến domain = 'freetuts.net'; // Kêt quả: Domain là freetuts.net document.write("Domain là: " + domain); // Khai báo var domain = 'techtuts.net'; // kêt quả: Domain là freetuts.net document.write("3 không phải là một hàm. 7. Lời kếtHoisting nghe có vẻ kì lạ và hay, nhưng riêng cá nhân mình thấy hoisting không thực sự tốt. Bởi theo sự logic của các ngôn ngữ lập trình là bạn phải sử dụng một biến trước khi khai báo chúng. Và Hoisting trong javascript đã phá vỡ đi quy tắc đó. |
Bài Viết Liên Quan
Hướng dẫn dùng open in python
Nội dung chínhCách 1: Sử dụng hàm openCách 2: mở file sử dụng context managerCách 3: Sử dụng thư viện pathlibCách 4: Sử dụng shellCách 5: Xây dựng một thư viện ...
Mùng 6 tết 2023 là ngày mấy
Chẳng bao lâu nữa thì mùa xuân năm 2023 lại về với những khởi đầu mới và hứng khởi mới. Chắc hẳn là hiện tại cũng đang có rất nhiều bạn mong muốn ...
Hướng dẫn convert json string to list of dictionaries python - chuyển đổi chuỗi json thành danh sách từ điển python
19 Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.Learn more. Tôi đang gửi một chuỗi JSON từ Objective-C đến Python. ...
Hướng dẫn python is an interpreted high-level language what does it mean to you - python là một ngôn ngữ cấp cao được thông dịch, nó có ý nghĩa như thế nào đối với bạn
Python là một trong những ngôn ngữ được giải thích phổ biến nhất, nhưng bạn đã bao giờ nghĩ về lý do tại sao Python được gọi là ngôn ngữ được giải ...
Hướng dẫn uniroot python - trăn uniroot
Hướng dẫn fuzzy python - trăn mờChuỗi mờ khớp trong PythonChúng tôi đã thực hiện nhiệm vụ của mình để lấy vé sự kiện từ mọi góc của internet, cho bạn ...
Hướng dẫn how do you sum two inputs in python? - làm thế nào để bạn tổng hợp hai đầu vào trong python?
Trong chương trình này, bạn sẽ học cách thêm hai số và hiển thị nó bằng hàm in ().Để hiểu ví dụ này, bạn nên có kiến thức về các chủ đề lập ...
Hướng dẫn sensitivity analysis python code - phân tích độ nhạy mã python
Composite number in python assignment expertComposite NumberGiven an integer N, write a program to find if the given number is a composite number or not. If it is composite, print True or else print ...
Hướng dẫn is there lcm function in python? - có chức năng lcm trong python không?
Trong chương trình này, bạn sẽ học cách tìm LCM của hai số và hiển thị nó.Để hiểu ví dụ này, bạn nên có kiến thức về các chủ đề lập trình ...
Hướng dẫn how do you click an element in python? - làm thế nào để bạn nhấp vào một phần tử trong python?
Xem thảo luậnCải thiện bài viếtLưu bài viếtĐọcBàn luậnXem thảo luậnCải thiện bài viếtLưu bài viếtĐọcBàn luậnMô -đun Selenium sườn Python được xây ...
Hướng dẫn is python more versatile than r? - python có linh hoạt hơn r không?
Khám phá những điều cơ bản của hai ngôn ngữ lập trình nguồn mở này, sự khác biệt chính làm cho chúng khác biệt và cách chọn đúng ngôn ngữ cho tình huống ...
Hướng dẫn is python little or big endian? - trăn nhỏ hay endian lớn?
21 Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.Learn more. Tôi đang làm việc trên một chương trình nơi tôi lưu ...
Hướng dẫn python get thread id - python lấy id chuỗi
246 Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.Learn more. Tôi có một chương trình Python đa luồng và chức năng ...
Hướng dẫn eclipse javascript - javascript nhật thực
Chào các bạn, trong bài viết này mình sẽ hướng dẫn mọi người tìm hiểu về một IDE (Integrated Development Environment) cực kỳ phổ biến đối với những lập ...
Lệnh thay đổi password trong linux
Trong bài này mình sẽ hướng dẫn cách đổi mật khẩu người dùng trên Linux, bằng cách sử dụng lệnh passwd Linux là bạn có thể đổi mật khẩu user trên Linux ...
25 tháng chạp 2023
Mục lục1 Lịch vạn niên ngày 25 tháng 12 năm 20232 Tử vi tốt xấu ngày 25 tháng 12 năm 20232.1 ☯ Việc tốt trong ngày2.2 ☯ Ngày bách kỵ2.3 ❎ Danh sách giờ xấu ...
Hướng dẫn how do i download mysql jdbc connector? - làm cách nào để tải xuống trình kết nối jdbc mysql?
Tải xuống cộng đồng MySQL Đầu nối/j Tính khả dụng chung (GA) phát hànhLưu trữĐầu nối/j 8.0.31 Chọn hệ điều hành: Tải xuống Windows được đề ...
Hướng dẫn ssh python - trăn ssh
Tiếp series lập trình Python, xin giới thiệu với các bạn đoạn code Python 3 sau sử dụng thư viện paramiko có nhiệm vụ kết nối SSH tới 1 Remote Linux Server và ...
Hướng dẫn how does php know the session? - làm thế nào để php biết phiên?
Một phiên là một cách để lưu trữ thông tin (trong các biến) sẽ được sử dụng trên nhiều trang.Không giống như cookie, thông tin không được lưu trữ trên máy ...
Hướng dẫn trinket python compiler - trình biên dịch trăn trinket
Hướng dẫn how do you extract something from a list in python? - làm thế nào để bạn trích xuất một cái gì đó từ một danh sách trong python?Hãy cùng tìm hiểu các cách ...
Lấy dữ liệu từ web vào excel trên macbook
Lấy dữ liệu, báo cáo từ website nhanh chóng với Excel là thủ thuật ít người biết đến. Trong bài viết dưới đây, chúng ta hãy cùng khám phá tính năng lấy ...