ความแตกต่างระหว่าง let
กับ var
มีอยู่ 2 แบบหลัก ดังนี้
- ประกาศตัวแปรโดยใช้
var
จะไม่ support เรื่องของ block scope และ scope การมองเห็นของมันขั้นเล็กที่สุดคือระดับ function ในขณะที่การประกาศตัวแปรโดยใช้let
นั้น scope ที่เล็กที่สุดของมันคือ block scope - ตัวแปรที่ถูกประกาศโดยใช้
var
จะถูก process เลยตั้งแต่เริ่มฟังก์ชั่น ไม่ว่าตัวแปรนั้นจะถูกประกาศไว้ตำแหน่งไหนของฟังก์ชั่นก็ตาม
การประกาศตัวแปรใน Javascript นั้นทำได้หลักๆ 3 แบบก็คือ
- let
- const
- var
ในเทอมของ Lexical นั้น let
กับ const
ไม่มีความแตกต่างกันเลย มีพฤติกรรมเหมือนกันทุกอย่าง แต่การประกาศตัวแปรโดยใช้ var
นั้นกลับแตกต่างไปอย่างสิ้นเชิง ด้วยเพราะว่ามันเกิดขึ้นมานานมากแล้ว และ modern JavaScript code เราก็มักไม่เห็นมันถูกใช้แล้ว ส่วนใหญ่จะเห็นโค้ดยุคเก่าๆ ที่ยังใช้ var
กันอยู่
ถ้าดูผ่านๆ การใช้ var นั้นก็ไม่ได้แตกต่างจากการใช้ let เลย ดังนี้
function sayHi() {
var phrase = "Hello"; // local variable, "var" instead of "let"
alert(phrase); // Hello
}
sayHi();
alert(phrase); // Error, phrase is not defined
ต่อไปนี้ เราจะมาดูกันว่าแท้จริงแล้วการประกาศตัวแปรด้วย var
นั้นจะส่งผลอย่างไรบ้าง
var
ไม่มี concept ของ block scope
if (true) {
var test = true; // use "var" instead of "let"
}
alert(test); // true, the variable lives after if
จะเห็นว่าแม้เราประกาศตัวแปรใน block if
แต่ก็ยังสามารถเรียกใช้ตัวแปร test
ได้อยู่ และถ้าเราเปลี่ยนไปประกาศตัวแปร test ด้วย let
เราจะพบว่า `alert(test);“ จะมองไม่เห็นตัวแปร test
เช่นเดียวกันกับการประกาศตัวแปรโดยใช้ var ใน loop
for(var i = 0; i < 10; i++) {
// ...
}
alert(i); // 10, "i" is visible after loop, it's a global variable
คำสั่ง alert();
จะมองเห็นตัวแปร i
แต่ถ้าประกาศตัวแปรโดยใช้ let
เราจะไม่สามารถอ้างถึงตัวแปร i
ได้นอก for
loop
และถ้าประกาศตัวแปรไว้ใน code block ของ if
เราก็ยังสามารถอ้างถึงตัวแปร test
ได้นอก if
block แต่ไม่สามารถอ้างถึงได้นอกฟังก์ชั่น เพราะ scope ย่อยที่สุดของ var
คือ function block ดังนี้
function sayHi() {
if (true) {
var phrase = "Hello";
}
alert(phrase); // works
}
sayHi();
alert(phrase); // Error: phrase is not defined
var
จะถูก process ตั้งแต่จุดเริ่มต้นของ function
var
จะถูก process ตั้งแต่จุดเริ่มต้นของ function เลย แม้ว่าถูกประกาศไว้ ณ ตำแหน่งใดๆ ก็ตามใน function ยกตัวอย่างเช่น ถ้าเราเขียนโค้ดแบบนี้
function sayHi() {
phrase = "Hello";
alert(phrase);
var phrase;
}
จะมีค่าเท่ากับเราเขียนโค้ดแบบนี้
function sayHi() {
var phrase;
phrase = "Hello";
alert(phrase);
}
หรือแม้แต่เราเขียนโค้ดแบบนี้
function sayHi() {
phrase = "Hello"; // (*)
if (false) {
var phrase;
}
alert(phrase);
}
เราก็สามารถอ้างถึงตัวแปรที่ถูกประกาศด้วยตัวแปร var
ได้ตลอดทั้ง function เราเรียกพฤติกรรมนี้ว่า hoisting (ถูกยกขึ้น) ก็คือ ไม่ว่าจะประกาศตัวแปรด้วยคำสั่ง var
ไว้ที่ไหน การประกาศนั้นจะเสมือนว่าถูกยกขึ้นมาไว้ที่บรรทัดแรกของ function เสมอ
การประกาศตัวแปรถูกยก แต่การกำหนดค่าให้ตัวแปรยังอยู่ที่เดิม
ยกตัวอย่างเช่น
function sayHi() {
alert(phrase);
var phrase = "Hello";
}
sayHi();
บรรทัดที่ประกาศตัวแปร var phrase นั้นจะมี 2 action ที่เกิดขึ้น ได้แก่ ประกาศตัวแปรด้วยคำสั่ง var
กำหนดค่าให้ตัวแปร phrase
ด้วยคำสั่ง =
การประกาศตัวแปรจะถูก ยกขึ้น เหมือนเดิม แต่การกำหนดค่าให้ตัวแปร phrase นั้นยังอยู่ที่เดิม ถ้าแปลงโค้ดก่อนหน้าให้เป็นไปตามพฤติกรรมของ var
เราก็จะได้โค้ดดังนี้
function sayHi() {
var phrase; // declaration works at the start...
alert(phrase); // undefined
phrase = "Hello"; // ...assignment - when the execution reaches it.
}
sayHi();
เมื่อเราเข้าใจความแตกต่างของการใช้ var
และ let
แล้ว ก็จะทำให้เราสามารถไล่โค้ด JavaScript ได้อย่างแม่นยำได้ยิ่งขึ้น