ตัวแปร

ตัวแปรคือโครงสร้างข้อมูลที่กำหนดชื่อตัวแทนให้กับค่า โดยจะประกอบด้วยข้อมูลประเภทใดก็ได้

ชื่อของตัวแปรจะเรียกว่าตัวระบุ ตัวระบุที่ถูกต้องต้องเป็นไปตาม กฎเหล่านี้

  • ตัวระบุมีตัวอักษร Unicode, สัญลักษณ์ดอลลาร์ ($), ขีดล่าง อักขระ (_), ตัวเลข (0-9) หรือแม้แต่อักขระ Unicode บางตัว
  • ตัวระบุไม่สามารถมีช่องว่างได้ เนื่องจากโปรแกรมแยกวิเคราะห์ใช้ช่องว่างในการ แยกองค์ประกอบอินพุต เช่น หากคุณพยายามเรียกตัวแปร my Variable แทนที่จะเป็น myVariable โปรแกรมแยกวิเคราะห์จะเห็นตัวระบุ 2 ตัว my และ Variable และระบบแสดงข้อผิดพลาดของไวยากรณ์ ("โทเค็นที่ไม่คาดคิด: ")
  • ตัวระบุต้องขึ้นต้นด้วยตัวอักษร ขีดล่าง (_) หรือสัญลักษณ์ดอลลาร์ ($) ต้องไม่ขึ้นต้นด้วยตัวเลข เพื่อป้องกันความสับสนระหว่างตัวเลขกับ ตัวระบุ:

    let 1a = true;
    
    > Uncaught SyntaxError: Invalid or unexpected token
    

    หาก JavaScript อนุญาตให้ใช้ตัวเลขที่ด้านหน้าของตัวระบุ ก็จะทำให้ ตัวระบุที่สร้างขึ้นจากตัวเลขเท่านั้น ทำให้เกิดข้อขัดแย้งระหว่างตัวเลขที่ใช้เป็น ตัวเลขและตัวเลขที่ใช้เป็นตัวระบุ

    let 10 = 20
    
    10 + 5
    > ?
    
  • "คำที่สงวนไว้" ที่มีความหมายในไวยากรณ์อยู่แล้วใช้เป็นตัวระบุไม่ได้

  • ตัวระบุต้องไม่มีสัญลักษณ์พิเศษ (! . , / \ + - * =)

กฎต่อไปนี้ไม่ใช่กฎที่เข้มงวดสำหรับการสร้างตัวระบุ แนวทางปฏิบัติที่ดีที่สุดของอุตสาหกรรมที่จะทำให้การดูแลโค้ดของคุณเป็นเรื่องง่ายขึ้น หาก โปรเจ็กต์มีมาตรฐานที่แตกต่างกัน โปรดทำตามมาตรฐานเหล่านั้นแทนเพื่อความสอดคล้อง

จากตัวอย่างที่กำหนดโดยเมธอดและพร็อพเพอร์ตี้ในตัวของ JavaScript เคสลายอูฐ (ที่ทำสไตไลซ์เป็น "camelCase") เป็นแบบที่ใช้กันทั่วไปมากสำหรับ ซึ่งประกอบด้วยคำหลายคำ Camel Case เป็นแนวทางปฏิบัติของ การใช้อักษรตัวพิมพ์ใหญ่กับตัวอักษรแรกของทุกคำ ยกเว้นอักษรแรกเพื่อให้ปรับปรุง ให้อ่านง่ายขึ้นโดยไม่ต้องใช้ช่องว่าง

let camelCasedIdentifier = true;

บางโปรเจ็กต์ใช้รูปแบบการตั้งชื่ออื่นๆ ขึ้นอยู่กับบริบทและลักษณะ ของข้อมูล เช่น อักษรตัวแรกของชั้นเรียน มักเป็นตัวพิมพ์ใหญ่ ดังนั้นชื่อคลาสที่มีหลายคำจึงมักจะใช้อูฐ ตัวพิมพ์ใหญ่หรือเล็กที่เรียกกันโดยทั่วไปว่า "อูฐบน" หรือ กรณี Pascal

class MyClass {

}

ตัวระบุควรอธิบายถึงลักษณะของข้อมูลที่มีอย่างกระชับ (สำหรับ เช่น currentMonthDays เป็นชื่อที่ดีกว่า theNumberOfDaysInTheCurrentMonth) และอ่านได้ชัดเจนในพริบตา (originalValue ดีกว่า val) ตัวระบุ myVariable ที่ใช้ตลอดโมดูลนี้ทำงานในบริบทของ เป็นตัวอย่างแยกต่างหาก แต่จะไม่มีประโยชน์ในโค้ดการผลิต ไม่ได้ให้ข้อมูลใดๆ ในข้อความดังกล่าว

ตัวระบุไม่ควรมีความเฉพาะเจาะจงเกี่ยวกับข้อมูลที่อยู่ในนั้นมากเกินไป เนื่องจาก ค่าอาจเปลี่ยนแปลงไปตามวิธีที่สคริปต์ดำเนินการกับข้อมูลนั้น หรือ ที่ผู้ดูแลในอนาคตตัดสินใจ ตัวอย่างเช่น ตัวแปรเดิมกำหนด อาจต้องเปลี่ยนตัวระบุ miles เป็นค่าเป็นกิโลเมตรภายหลัง ทำให้ผู้บำรุงรักษาต้องเปลี่ยนการอ้างอิงตัวแปรดังกล่าวเป็น เพื่อไม่ให้เกิดความสับสนในอนาคต ใช้ distance เป็นตัวระบุเพื่อป้องกันปัญหานี้ แทน

JavaScript ไม่ได้ให้สิทธิพิเศษหรือความหมายใดๆ แก่ตัวระบุที่ เริ่มต้นด้วยอักขระขีดล่าง (_) แต่โดยปกติแล้วจะใช้เพื่อแสดงว่า ตัวแปร เมธอด หรือพร็อพเพอร์ตี้เป็นแบบ "ส่วนตัว" ซึ่งหมายความว่า สำหรับการใช้งานภายในบริบทของออบเจ็กต์ที่มีรายการดังกล่าว และไม่ควร เข้าถึงหรือแก้ไขนอกบริบทนั้น นี่คือการประชุมที่ยกมา จากภาษาโปรแกรมอื่นๆ และเป็นมาก่อนการเพิ่ม JavaScript พร็อพเพอร์ตี้ส่วนตัว

การประกาศตัวแปร

มีหลายวิธีที่จะทำให้ JavaScript รับรู้ถึงตัวระบุ ซึ่งเป็นกระบวนการ เรียกว่า "การประกาศ" ตัวแปร จะประกาศตัวแปรโดยใช้ let, const หรือ var คีย์เวิร์ด

let myVariable;

ใช้ let หรือ var เพื่อประกาศตัวแปรที่เปลี่ยนแปลงได้ทุกเมื่อ เหล่านี้ คีย์เวิร์ดจะบอกตัวแปลคำสั่ง JavaScript ว่าสตริงอักขระเป็น ที่อาจมีค่าอยู่

เมื่อทำงานในฐานของโค้ดสมัยใหม่ ให้ใช้ let แทน var var ยังใช้งานได้อยู่ ในเบราว์เซอร์สมัยใหม่ แต่มีลักษณะการทำงานบางอย่างที่ผิดกฎเกณฑ์ซึ่งกำหนดไว้ใน JavaScript เวอร์ชันแรกสุด แล้วจะไม่สามารถ เปลี่ยนเป็น เพื่อคงความเข้ากันได้แบบย้อนหลัง มีการเพิ่ม let ใน ES6 เพื่อแก้ไขปัญหาบางอย่าง ด้วยดีไซน์ var

ตัวแปรที่ประกาศจะเริ่มต้นด้วยการกําหนดค่าให้กับตัวแปร ใช้ เครื่องหมายเดี่ยวเท่ากับ (=) เพื่อกำหนดหรือกำหนดค่าให้กับตัวแปรใหม่ คุณทำได้ นี้เป็นส่วนหนึ่งของข้อความเดียวกันที่ประกาศว่า

let myVariable = 5;

myVariable + myVariable
> 10

คุณยังประกาศตัวแปรด้วย let (หรือ var) โดยไม่ต้องเริ่มต้นได้ด้วย ตอนนี้เลย หากคุณใช้ค่านี้ ค่าเริ่มต้นของตัวแปรคือ undefined จนกว่า จะกำหนดค่าให้กับโค้ด

let myVariable;

myVariable;
> undefined

myVariable = 5;

myVariable + myVariable
> 10

ตัวแปรที่มีค่า undefined แตกต่างจากตัวแปรที่ไม่ระบุ ที่ตัวระบุยังไม่ได้ประกาศ การอ้างอิงตัวแปรที่คุณไม่ได้อ้างอิง ที่ประกาศไว้ทำให้เกิดข้อผิดพลาด

myVariable
> Uncaught ReferenceError: myVariable is not defined

let myVariable;

myVariable
> undefined

โดยทั่วไปการเชื่อมโยงของตัวระบุกับค่าจะเรียกว่า "การเชื่อมโยง" ไวยากรณ์ที่ตามหลังคีย์เวิร์ด let, var หรือ const จะเรียกว่า "เชื่อมโยงรายการ" และอนุญาตให้ประกาศตัวแปรที่คั่นด้วยคอมมาได้หลายรายการ (ลงท้ายด้วยเครื่องหมายเซมิโคลอนที่คาดไว้) วิธีนี้ทำให้ข้อมูลโค้ดต่อไปนี้ มีฟังก์ชันการทำงานเหมือนกัน:

let firstVariable,
     secondVariable,
     thirdVariable;
let firstVariable;
let secondVariable;
let thirdVariable;

การกําหนดค่าของตัวแปรใหม่ไม่ได้ใช้ let (หรือ var) เนื่องจาก JavaScript ทราบอยู่แล้วว่ามีตัวแปรนี้อยู่

let myVariable = true;

myVariable
> true

myVariable = false;

myVariable
> false

คุณกำหนดค่าใหม่ของตัวแปรได้โดยอิงตามค่าที่มีอยู่ ดังนี้

let myVariable = 10;

myVariable
> 10

myVariable = myVariable * myVariable;

myVariable
> 100

หากคุณพยายามประกาศตัวแปรอีกครั้งโดยใช้ let ในสภาพแวดล้อมที่ใช้งานจริง คุณจะได้รับข้อผิดพลาดทางไวยากรณ์

let myVariable = true;
let myVariable = false;
> Uncaught SyntaxError: redeclaration of let myVariable

เบราว์เซอร์ เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ อนุญาตการประกาศซ้ำlet (และ class) มากกว่า ดังนั้นคุณจึงไม่ควร เห็นข้อผิดพลาดเดียวกันใน Developer Console

var อนุญาตการประกาศซ้ำที่ไม่จำเป็นเพื่อรักษาความเข้ากันได้ของเบราว์เซอร์เดิมไว้ โดยไม่มีข้อผิดพลาดในบริบทต่างๆ:

var myVariable = true;
var myVariable = false;

myVariable\
> false

const

ใช้คีย์เวิร์ด const เพื่อประกาศค่าคงที่ ซึ่งเป็นตัวแปรประเภทหนึ่งที่ต้องมี เริ่มต้นทันที และไม่สามารถเปลี่ยนแปลงได้ ตัวระบุสําหรับค่าคงที่ ทำตามกฎเดียวกันทั้งหมดกับตัวแปรที่ประกาศโดยใช้ let (และ var) ดังนี้

const myConstant = true;

myConstant
> true

คุณไม่สามารถประกาศค่าคงที่ได้หากไม่กำหนดค่าทันที เนื่องจาก คุณจะไม่สามารถกำหนดค่าคงที่ใหม่ได้หลังจากที่สร้างแล้ว ดังนั้นค่าคงที่ใดๆ ที่ไม่ได้เริ่มต้น ค่าคงที่จะคงอยู่ที่ undefined ตลอดไป ถ้าคุณพยายามประกาศค่าคงที่ โดยไม่เริ่มต้นใช้งาน คุณจะได้รับข้อผิดพลาดทางไวยากรณ์

const myConstant;
Uncaught SyntaxError: missing = in const declaration

พยายามเปลี่ยนค่าของตัวแปรที่ประกาศด้วย const ในแบบที่คุณอาจ เปลี่ยนค่าของตัวแปรที่ประกาศด้วย let (หรือ var) จะทำให้เกิดประเภท ข้อผิดพลาด:

const myConstant = true;

myConstant = false;
> Uncaught TypeError: invalid assignment to const 'myConstant'

แต่เมื่อค่าคงตัวเชื่อมโยงกับวัตถุ คุณสมบัติของวัตถุนั้น สามารถดัดแปลงได้

const constantObject = { "firstvalue" : true };

constantObject
> Object { firstvalue: true }

constantObject.secondvalue = false;

constantObject
> Object { firstvalue: true, secondvalue: false }

ค่าคงที่ที่มีวัตถุจะเปลี่ยนแปลงไม่ได้ อ้างอิงถึงค่าข้อมูลที่เปลี่ยนแปลงได้ แม้ว่าตัวค่าคงที่นั้นไม่สามารถเปลี่ยนแปลงได้ แต่คุณสมบัติของการอ้างอิง สามารถเปลี่ยนแปลง เพิ่ม หรือนำออกได้

const constantObject = { "firstvalue" : true };

constantObject = false
> Uncaught TypeError: invalid assignment to const 'constantObject'

เมื่อคุณไม่ได้คาดหวังว่าจะมีการกำหนดตัวแปรใหม่ แนวทางปฏิบัติแนะนำคือให้ตัวแปรดังกล่าว คงที่ การใช้ const จะแจ้งทีมพัฒนาหรือผู้ดูแลในอนาคต ไม่ให้เปลี่ยนแปลงค่าดังกล่าว เพื่อหลีกเลี่ยงการทำลายสมมติฐานของโค้ดของคุณ สร้างตัวแปรในการนำตัวแปรไปใช้ ตัวอย่างเช่น ตัวแปรจะกลายเป็น กับประเภทข้อมูลที่คาดไว้

ขอบเขตตัวแปร

ขอบเขตของตัวแปรเป็นส่วนหนึ่งของสคริปต์ที่ตัวแปรนั้นพร้อมใช้งาน นอกขอบเขตของตัวแปรจะไม่ได้รับการกำหนด ไม่ใช่เป็นตัวระบุ ที่มีค่า undefined แต่ไม่มีการประกาศ

ขึ้นอยู่กับคีย์เวิร์ดที่คุณใช้ประกาศตัวแปรและบริบท คุณสามารถกำหนดขอบเขตของตัวแปรเพื่อบล็อกคำสั่ง (บล็อกขอบเขต) แต่ละฟังก์ชัน (ขอบเขตของฟังก์ชัน) หรือแอปพลิเคชัน JavaScript ทั้งหมด (ขอบเขตทั้งหมด)

บล็อกขอบเขต

ตัวแปรที่คุณประกาศโดยใช้ let หรือ const มีการกำหนดขอบเขตที่ใกล้เคียงที่สุด ที่มีคำสั่งบล็อก ซึ่งหมายความว่าตัวแปรจะเข้าถึงได้ภายในบล็อกนั้นเท่านั้น กำลังพยายาม การเข้าถึงตัวแปรที่กำหนดขอบเขตบล็อกภายนอกการบล็อกจะทำให้ ข้อผิดพลาดเกี่ยวกับการพยายามเข้าถึงตัวแปรที่ไม่มีอยู่

{
    let scopedVariable = true;
    console.log( scopedVariable );
}
> true

scopedVariable
> ReferenceError: scopedVariable is not defined

สำหรับ JavaScript ตัวแปรที่กำหนดขอบเขตระดับบล็อกไม่มีอยู่ นอกบล็อกที่มีแท็กนั้นอยู่ เช่น คุณสามารถประกาศค่าคงที่ ภายในบล็อก แล้วประกาศค่าคงที่อื่นนอกบล็อกที่ใช้ ตัวระบุเดียวกัน

{
  const myConstant = false;
}
const myConstant = true;

scopedConstant;
> true

แม้ว่าตัวแปรที่ประกาศจะขยายเข้าไปในบล็อกระดับบนสุดไม่ได้ แต่ตัวแปรที่ประกาศจะ ใช้ได้กับบล็อกองค์ประกอบสืบทอดทั้งหมด

{
    let scopedVariable = true;
    {
    console.log( scopedVariable );
    }
}
> true

ค่าของตัวแปรที่ประกาศจะเปลี่ยนได้จากภายในบล็อกองค์ประกอบสืบทอด ดังนี้

{
    let scopedVariable = false;
    {
    scopedVariable = true;
    }
    console.log( scopedVariable );
}
> true

ตัวแปรใหม่อาจเริ่มต้นด้วย let หรือ const ภายในองค์ประกอบสืบทอด บล็อกโดยไม่มีข้อผิดพลาด แม้ว่าจะใช้ตัวระบุเดียวกันกับตัวแปรใน บล็อกระดับบนสุด:

{
    let scopedVariable = false;
    {
    let scopedVariable = true;
    }
    console.log( scopedVariable );
}
> false

ขอบเขตของฟังก์ชัน

ตัวแปรที่ประกาศโดยใช้ var จะกำหนดขอบเขตให้ฟังก์ชันที่มีตัวแปรที่ใกล้เคียงที่สุด (หรือบล็อกการเริ่มต้นแบบคงที่ในคลาส)

function myFunction() {
    var scopedVariable = true;

    return scopedVariable;
}

scopedVariable;
> ReferenceError: scopedVariable is not defined

ซึ่งยังคงเป็นเช่นนี้หลังจากที่เรียกใช้ฟังก์ชันแล้ว แม้ว่า เริ่มต้นขณะที่ฟังก์ชันดำเนินการ ตัวแปรนั้นยังคงอยู่ ไม่พร้อมใช้งานนอกขอบเขตของฟังก์ชัน:

function myFunction() {
    var scopedVariable = true;

    return scopedVariable;
}

scopedVariable;
> ReferenceError: scopedVariable is not defined

myFunction();
> true

scopedVariable;
> ReferenceError: scopedVariable is not defined

ขอบเขตรวมทั้งหมด

ตัวแปรร่วมจะใช้ได้ในแอปพลิเคชัน JavaScript ทั้งหมด ภายในบล็อกและฟังก์ชันทั้งหมด ไปยังสคริปต์ใดก็ได้ในหน้าเว็บ

ถึงแม้สิ่งนี้จะดูเหมือนใช้ค่าเริ่มต้นที่ต้องการ แต่ตัวแปรที่ว่า สามารถเข้าถึงและแก้ไข อาจเพิ่มค่าใช้จ่ายที่ไม่จำเป็น หรือแม้กระทั่งทำให้ เกิดความขัดแย้งกับตัวแปรในตำแหน่งอื่นในแอปพลิเคชันที่มีตัวระบุเดียวกัน ซึ่งจะมีผลกับ JavaScript ทั้งหมดที่เกี่ยวข้องในการแสดงผลของหน้าเว็บ รวมถึงสิ่งต่างๆ เช่น ไลบรารีของบุคคลที่สามและข้อมูลวิเคราะห์ผู้ใช้ ดังนั้น แนวทางปฏิบัติแนะนำเพื่อหลีกเลี่ยงการสร้างมลพิษในขอบเขตระดับโลกเมื่อเป็นไปได้

ตัวแปรที่ประกาศโดยใช้ var นอกฟังก์ชันหลัก หรือใช้ let หรือ const นอกการบล็อกระดับบนสุดจะเป็นแบบทั่วโลก:

var functionGlobal = true; // Global
let blockGlobal = true; // Global

{
    console.log( blockGlobal );
    console.log( functionGlobal );
}
> true
> true

(function() {
    console.log( blockGlobal );
    console.log( functionGlobal );
}());
> true
> true

การกำหนดค่าให้กับตัวแปรโดยไม่ประกาศอย่างชัดแจ้ง (กล่าวคือ ไม่ใช้ var, let หรือ const ในการสร้าง) จะยกระดับตัวแปรเป็น ขอบเขตรวมทั้งหมด แม้ว่าจะเริ่มต้นภายในฟังก์ชันหรือบล็อกก็ตาม ตัวแปร ที่สร้างขึ้นโดยใช้รูปแบบนี้บางครั้งเรียกว่า "สากลโดยนัย"

function myFunction() {
    globalVariable = "global";

    return globalVariable
}

myFunction()\
> "global"

globalVariable\
> "global"

รอกตัวแปร

การประกาศตัวแปรและฟังก์ชันจะยกมาไว้ที่ด้านบนสุดของขอบเขต ซึ่งหมายความว่าตัวแปล JavaScript จะประมวลผลตัวแปรใดๆ ที่ประกาศ จุดในสคริปต์ แล้วย้ายไปยังบรรทัดแรกของที่ล้อมรอบอยู่อย่างมีประสิทธิภาพ ก่อนที่จะเรียกใช้สคริปต์ ซึ่งหมายความว่าตัวแปรที่ประกาศโดยใช้ อ้างอิง var ได้ก่อนที่จะประกาศตัวแปรโดยไม่ต้องพบกับ ข้อผิดพลาด:

hoistedVariable
> undefined

var hoistedVariable;

เนื่องจากมีเพียงการประกาศตัวแปรเท่านั้นที่โฮสต์ ไม่ใช่การเริ่มต้น ตัวแปรที่ไม่ได้ประกาศอย่างชัดเจนด้วย var, let หรือ const ไม่มีการรอน:

unhoistedVariable;
> Uncaught ReferenceError: unhoistedVariable is not defined

unhoistedVariable = true;

ดังที่กล่าวไว้ก่อนหน้านี้ ตัวแปรที่ประกาศแต่ไม่ได้เริ่มต้น ได้รับการกำหนดค่าเป็น undefined ลักษณะการทำงานนี้มีผลกับตัวแปรที่รอก ด้วย แต่เฉพาะผู้ที่ประกาศโดยใช้ var เท่านั้น

hoistedVariable
> undefined

var hoistedVariable = 2 + 2;

hoistedVariable\
> 4

พฤติกรรมที่ไม่น่าเชื่อถือนี้ ส่วนใหญ่แล้วเป็นอุปสรรคจากการตัดสินใจด้านการออกแบบใน JavaScript เวอร์ชันแรกสุด และไม่สามารถเปลี่ยนแปลงได้หากไม่มีความเสี่ยง ทำให้เว็บไซต์ที่มีอยู่เสียหาย

let และ const จัดการกับพฤติกรรมนี้โดยแสดงข้อผิดพลาดเมื่อ มีการเข้าถึงตัวแปรก่อนสร้าง:

{
    hoistedVariable;

    let hoistedVariable;
}
> Uncaught ReferenceError: can't access lexical declaration 'hoistedVariable' before initialization

ข้อผิดพลาดนี้แตกต่างจาก "ไม่ได้กำหนด hoistedVariable" ข้อผิดพลาดเธอ เมื่อพยายามเข้าถึงตัวแปรที่ไม่ได้ประกาศ เนื่องจาก JavaScript ยกตัวแปรแล้ว โดยรับรู้ว่าตัวแปรจะสร้างขึ้นภายใน ตามขอบเขตที่กำหนด แต่แทนที่จะทำให้ตัวแปรนั้นพร้อมใช้งานก่อนตัวแปร ด้วยค่า undefined ล่ามจะแสดงข้อผิดพลาด ตัวแปรที่ประกาศด้วย let หรือ const (หรือ class) ถือว่าอยู่ใน "พื้นที่อับสัญญาณชั่วคราว" ("TDZ") ตั้งแต่ต้นบล็อกที่ล้อมรอบจนถึง จุดในโค้ดที่มีการประกาศตัวแปร

โซนตายชั่วคราวทำให้ลักษณะการทำงานของ let ง่ายกว่าของ var สำหรับ ผู้เขียน และมีความสำคัญต่อการออกแบบของ const ด้วย เนื่องจากค่าคงที่ไม่สามารถ เปลี่ยนแปลง ต่อยอดไปสู่ด้านบนสุดของขอบเขตการทำงาน และได้ให้มูลค่าโดยนัย ของ undefined ต้องไม่เริ่มต้นด้วยค่าที่มีความหมาย

ตรวจสอบความเข้าใจ

คุณจะใช้อักขระประเภทใดได้บ้างในการเริ่มใช้ตัวระบุ

ตัวอักษร
ขีดล่าง
ตัวเลข

ข้อใดคือวิธีที่แนะนำในการประกาศตัวแปรที่มีค่า สามารถเปลี่ยนแปลงได้ทุกเมื่อไหม

บอกให้
const
ตัวแปร