การทำงานของโปรแกรมคอมพิวเตอร์ต้องใช้ค่าการทำงานเช่นหมายเลข 3.14 หรือข้อความ "Hello World" ในภาษาการเขียนโปรแกรมประเภทของค่าที่สามารถแสดงและดำเนินการได้เรียกว่าชนิดข้อมูล คุณสมบัติพื้นฐานที่สุดของภาษาการเขียนโปรแกรมคือการโฮสต์ข้อมูลหลายประเภท เมื่อโปรแกรมจำเป็นต้องเก็บค่าสำหรับการใช้งานในอนาคตจะได้รับมอบหมายให้ ("บันทึก" ค่าเป็น) ตัวแปร ตัวแปรเป็นชื่อสัญลักษณ์ของค่าและการอ้างอิงถึงค่าสามารถรับได้ด้วยชื่อ กลไกการทำงานของตัวแปรเป็นคุณสมบัติพื้นฐานของภาษาการเขียนโปรแกรม บทนี้จะอ้างถึงส่วนก่อนหน้านี้เพื่อช่วยให้เข้าใจเนื้อหาของบทนี้และจะอธิบายในเชิงลึกมากขึ้นในภายหลัง
ข้อมูล JavaScript แบ่งออกเป็นสองประเภท: ประเภทดั้งเดิมและประเภทวัตถุ
คลาสดั้งเดิมใน JavaScript รวมถึงตัวเลขสตริงและค่าบูลีน บทนี้จะมีบทที่แยกต่างหากโดยเฉพาะการหารือเกี่ยวกับตัวเลขของ JavaScript สตริงและค่าบูลีนโดยเฉพาะ JavaScript ยังมีค่าดิบพิเศษสองค่า NULL (ว่าง) และไม่ได้กำหนด (ไม่ได้กำหนด) พวกเขาไม่ใช่ตัวเลขสตริงหรือค่าบูลีน พวกเขาเป็นตัวแทนสมาชิกคนเดียวของประเภทพิเศษที่เกี่ยวข้อง
JavaScript เป็นวัตถุนอกเหนือจากตัวเลข, สตริง, ค่าบูลีน, โมฆะและไม่ได้กำหนด วัตถุคือชุดของคุณสมบัติ แต่ละแอตทริบิวต์ประกอบด้วย "คู่ชื่อ/ค่าคู่" (ค่าอาจเป็นค่าดั้งเดิมเช่นตัวเลขสตริงหรือวัตถุ) หนึ่งในวัตถุพิเศษ (วัตถุระดับโลกจะถูกนำเสนอใน Miss Fifth และส่วนที่หกจะอธิบายรายละเอียดเพิ่มเติม)
วัตถุจาวาสคริปต์ปกติเป็นคอลเลกชันที่ไม่จำเป็นของ "ค่าชื่อ" JavaScript ยังกำหนดวัตถุพิเศษ - อาร์เรย์ซึ่งแสดงชุดที่สั่งซื้อของค่าที่มีหมายเลข JavaScript กำหนดไวยากรณ์เฉพาะสำหรับอาร์เรย์ ทำให้อาร์เรย์มีคุณสมบัติพฤติกรรมที่ไม่ซ้ำกันซึ่งแตกต่างจากวัตถุธรรมดา
JavaScript ยังกำหนดฟังก์ชั่นวัตถุพิเศษ ฟังก์ชั่นเป็นวัตถุที่มีรหัสปฏิบัติการที่ต้องการเชื่อมโยงกับ มันเรียกใช้รหัสโดยเรียกใช้ฟังก์ชันและส่งคืนผลลัพธ์ของการดำเนินการ เช่นอาร์เรย์ลักษณะพฤติกรรมของฟังก์ชั่นแตกต่างจากวัตถุอื่น ๆ JavaScript กำหนดไวยากรณ์พิเศษสำหรับการใช้ฟังก์ชั่น สำหรับฟังก์ชั่น JavaScript สิ่งสำคัญที่สุดคือพวกเขาเป็นค่าที่แท้จริงทั้งหมดและ JavaScript สามารถใช้ในการปฏิบัติต่อพวกเขาเป็นวัตถุธรรมดา
หากฟังก์ชั่นเริ่มต้น (โดยใช้ตัวดำเนินการใหม่) วัตถุใหม่เราจะเรียกมันว่าตัวสร้าง แต่ละคอนสตรัคเตอร์กำหนดอ็อบเจ็กต์คลาส-คอลเลกชันที่ประกอบด้วยวัตถุเริ่มต้นคอนสตรัคเตอร์ ชั้นเรียนถือได้ว่าเป็นชนิดย่อยของประเภทวัตถุ นอกเหนือจากคลาสอาร์เรย์และคลาสฟังก์ชั่น JavaScript ยังกำหนดคลาสอื่น ๆ อีกสามคลาสที่ใช้ วันที่กำหนดวัตถุที่แสดงวันที่ Regexp กำหนดวัตถุของการแสดงออกปกติ คลาสข้อผิดพลาดกำหนดบรรทัดที่แสดงถึงข้อผิดพลาดรันไทม์และวัตถุข้อผิดพลาดไวยากรณ์ในโปรแกรม JavaScript คุณสามารถกำหนดคลาสที่ต้องการได้โดยกำหนดตัวสร้างของคุณเอง
JavaScript Interpreter มีกลไกการจัดการหน่วยความจำของตัวเองซึ่งสามารถเก็บรวบรวมการรวบรวมหน่วยความจำโดยอัตโนมัติ ซึ่งหมายความว่าโปรแกรมสามารถสร้างวัตถุตามความต้องการและโปรแกรมเมอร์ไม่ต้องกังวลเกี่ยวกับการทำลายวัตถุเหล่านี้และการรีไซเคิลหน่วยความจำ เมื่อไม่มีจุดอ้างอิงไปยังวัตถุล่ามจะรู้ว่าวัตถุนั้นไร้ประโยชน์และจะรีไซเคิลทรัพยากรหน่วยความจำที่อยู่โดยอัตโนมัติ
JavaScript เป็นภาษาที่มุ่งเน้นวัตถุ ไม่ได้พูดอย่างเคร่งครัดซึ่งหมายความว่าเราไม่ได้ใช้ฟังก์ชั่นนิยามทั่วโลกเพื่อใช้งานค่าประเภทต่าง ๆ ประเภทข้อมูลเองสามารถกำหนดวิธีการใช้ค่า ตัวอย่างเช่นในการเรียงลำดับองค์ประกอบในอาร์เรย์ A ไม่จำเป็นต้องส่งผ่านฟังก์ชัน sort () แต่เพื่อถ่ายโอนวิธีการเรียงลำดับ ()
A.Sort (); // sort (a) เวอร์ชันที่มุ่งเน้นวัตถุ
ในทางเทคนิคเฉพาะวัตถุ JavaScript เท่านั้นที่สามารถมีวิธีการ อย่างไรก็ตามตัวเลขสตริงและค่าบูลีนก็มีวิธีการของตัวเอง ใน JavaScript มีเพียงค่า NULL และ Undevined เท่านั้นที่ไม่มีค่าใช้จ่าย
ประเภทของจาวาสคริปต์สามารถแบ่งออกเป็นประเภทดั้งเดิมและประเภทวัตถุและสามารถแบ่งออกเป็นประเภทที่สามารถมีวิธีการและประเภทที่ไม่มีวิธีการ นอกจากนี้ยังสามารถแบ่งออกเป็นประเภทที่ไม่เปลี่ยนแปลงและไม่เปลี่ยนรูป ค่าของประเภทที่ไม่แน่นอนสามารถแก้ไขได้และวัตถุและอาร์เรย์เป็นของประเภทที่ไม่แน่นอน: โปรแกรม JavaScript สามารถเปลี่ยนค่าของค่าแอตทริบิวต์ของวัตถุและค่าขององค์ประกอบอาร์เรย์
ตัวเลขบูลีนโมฆะและที่ไม่ได้กำหนดเป็นประเภทที่ไม่สามารถเปลี่ยนแปลงได้ ตัวอย่างเช่นการแก้ไขเนื้อหาของอาร์เรย์นั้นไม่สมเหตุสมผล สตริงสามารถถือได้ว่าเป็นอาร์เรย์ของตัวละครและคุณสามารถคิดว่ามันสามารถเปลี่ยนแปลงได้ อย่างไรก็ตามใน JavaScript สตริงไม่เปลี่ยนรูป คุณสามารถเข้าถึงข้อความได้ทุกตำแหน่งของสตริง แต่ JavaScript ไม่ได้ให้วิธีการแก้ไขเนื้อหาข้อความของสตริงตลอดเวลา
JavaScript สามารถทำการแปลงชนิดข้อมูลได้อย่างอิสระ ตัวอย่างเช่นหากมีการใช้ตัวเลขที่โปรแกรมคาดว่าจะใช้สตริง JavaScript จะแปลงหมายเลขเป็นสตริงโดยอัตโนมัติ หากคุณคาดว่าจะใช้ค่าที่ไม่ใช่ boolean ที่ใช้ค่าบูลีน JavaScript จะแปลงตามนั้น ใน JavaScript กฎ "ความเท่าเทียมกันของการตัดสิน" ใช้เพื่อ "ความเท่าเทียมกันในการตัดสิน" (ความเท่าเทียมกัน)
ตัวแปร JavaScript นั้นไม่ได้ถูกกำหนด ตัวแปรสามารถกำหนดให้กับผู้คนและประเภท สามารถประกาศตัวแปรโดยใช้คำหลัก VAR JavaScript ใช้ขอบเขตไวยากรณ์ ตัวแปรที่ไม่ได้ประกาศในฟังก์ชั่นใด ๆ เรียกว่าตัวแปรทั่วโลก พวกเขาสามารถมองเห็นได้ทุกที่ในโปรแกรมของ JavaScript
1. ตัวเลข
ซึ่งแตกต่างจากภาษาการเขียนโปรแกรมอื่น ๆ JavaScript ไม่ได้แยกความแตกต่างระหว่างค่าจำนวนเต็มและค่าจุดลอยตัว ค่าทั้งหมดในจาวาสคริปต์จะแสดงโดยค่าจุดลอยตัว เมื่อตัวเลขปรากฏโดยตรงในโปรแกรม JavaScript เราเป็นตัวอักษรตัวเลขและ JavaScript รองรับปริมาณโดยตรงตัวเลขในหลายรูปแบบ (หมายเหตุ: การเพิ่มเครื่องหมายลบ (-) โดยตรงก่อนที่ตัวเลขใด ๆ จะได้รับค่าลบ) แต่เครื่องหมายลบเป็นตัวดำเนินการผกผันทางเดียว ไม่ใช่ส่วนประกอบของไวยากรณ์ของปริมาณตัวเลขโดยตรง -
ฉันจำนวนเต็มประเภทปริมาณโดยตรง
จำนวนเต็มทศนิยมถูกแสดงโดยลำดับอาร์เรย์ใน JavaScript
นอกเหนือจากปริมาณโดยตรงของทศนิยมจำนวนเต็มแล้วจาวาสคริปต์ยังรับรู้ถึงค่าของกลไกสิบหก (16) ในฐานะที่เป็น cardinality ระบบ hexadecimal ที่เรียกว่าเป็นปริมาณโดยตรงที่นำหน้าด้วย "0x" หรือ "0x" ตามด้วยสตริงของเลขฐานสิบหก ค่าเลขฐานสิบหกประกอบด้วยตัวอักษรระหว่าง 0-9 ถึง A (a) -f (f) ตัวอักษรของ AF แสดงเป็นหมายเลข 10-15 ด้านล่าง นี่คือตัวอย่างของจำนวนเต็มเลขฐานสิบหกโดยตรง
การคัดลอกรหัสมีดังนี้:
0xff // 15*16+15 = 255
0xCafe911
แม้ว่า Ecmascript จะไม่รองรับปริมาณโดยตรงแบบแปดทาง แต่การใช้งานของ JavaScript บางอย่างสามารถอนุญาตให้มีการเป็นตัวแทนของจำนวนเต็มใน octal (ฐาน 8) ปริมาณโดยตรงแปดจุดเริ่มต้นด้วยหมายเลข 0 ตามด้วยลำดับของตัวเลขระหว่าง 0 ถึง 7
การคัดลอกรหัสมีดังนี้:
0377 // 3*64 +7*8 +7 = 255 (ทศนิยม)
เนื่องจากการใช้งาน JavaScript บางตัวรองรับ Octal Inter-number ในขณะที่บางคนไม่ได้ดีที่สุดที่จะไม่ใช้จำนวนเต็มอินเตอร์หมายเลขคำนำหน้าด้วย 0 หลังจากทั้งหมดเราไม่สามารถรู้ได้ว่าการใช้งาน JavaScript ปัจจุบันรองรับการแยก Octal หรือไม่ ในโหมดที่เข้มงวดของ ECMASCript6 ปริมาณแปดทิศตรงนั้นเป็นสิ่งต้องห้ามอย่างชัดเจน
ii. ปริมาณจุดลอยตัวโดยตรง
ปริมาณจุดลอยตัวโดยตรงอาจมีจุดทศนิยมและใช้วิธีการเขียนจำนวนจริงแบบดั้งเดิม จำนวนจริงประกอบด้วยชิ้นส่วนจำนวนเต็มจุดทศนิยมและส่วนทศนิยม
นอกจากนี้ยังสามารถใช้วิธีการนับแบบเอ็กซ์โปเนนเชียลเพื่อแสดงปริมาณจุดลอยตัวโดยตรง นั่นคือจำนวนจริงตามด้วยตัวอักษร E หรือ E ตามด้วยเครื่องหมายบวกและลบและจากนั้นจะเพิ่มเลขชี้กำลังจำนวนเต็ม ค่าตัวเลขที่แสดงโดยวิธีการนับนี้เป็นพลังทวีคูณของจำนวนจริงก่อนหน้านี้คูณด้วย 10
สามารถแสดงในไวยากรณ์ที่กระชับมากขึ้น
การคัดลอกรหัสมีดังนี้:
[ตัวเลข] [. ตัวเลข] [(e | e) [(+|-)] ตัวเลข]
3.14
2345.455
.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
6.02E23 //6.02*10 ถึงกำลัง 23
1.255454E-23 //1.255454*10 ถึงกำลัง 23
การดำเนินการทางคณิตศาสตร์ใน iii.javascript
โปรแกรม JavaScript ใช้ตัวดำเนินการเลขคณิตที่จัดทำโดยจังหวัดภาษาเพื่อดำเนินการเชิงตัวเลข ตัวดำเนินการเหล่านี้มีตัวดำเนินการ + - * / และตัวดำเนินการที่เหลือ (แบ่งส่วนที่เหลือ) %
นอกเหนือจากตัวดำเนินการขั้นพื้นฐานแล้ว JavaScript ยังรองรับการดำเนินการทางคณิตศาสตร์ที่ซับซ้อนมากขึ้น การดำเนินการที่ซับซ้อนนี้ถูกนำมาใช้โดยฟังก์ชั่นและค่าคงที่ที่กำหนดเป็นคุณสมบัติของวัตถุคณิตศาสตร์
การคัดลอกรหัสมีดังนี้:
Math.pow (2, 53) // => 9007199254740992 Document.write (Math.Pow (2,53)))
Math.Round (.6) //=>1.0 รอบ
Math.Ceil (.6) //=>1.0 การค้นหาขึ้นไปข้างบน
math.floor (.6) //=>0.0 ลง
math.abs (-5) // => 5 ค้นหาค่าสัมบูรณ์
math.max (x, y, z) // ส่งคืนค่าสูงสุด
math.min (x, y, z) // ส่งคืนค่าต่ำสุด
math.random () // สร้างหมายเลขหลอกแท่งมากกว่า 0 และน้อยกว่า 1
math.pi // pi
Math.E // E: ฐานลอการิทึมธรรมชาติ
math.sqrt (3) // 3 สแควร์รูท
Math.pow (3, 1/3) // รูทลูกบาศก์ของ 3
Math.sin (0) // ฟังก์ชั่นตรีโกณมิติเช่นเดียวกับ Math.cos, Math.atan ฯลฯ
Math.log (10) //=>2.302585092994046 ลอการิทึมธรรมชาติพร้อมฐาน 10
math.log (512) /math.ln2 // log ของ 512 ด้วยฐาน 2
math.log (100) /math.ln10 // log ของ 100 พร้อมฐาน 10
Math.exp (3) // พลังของสาม
การดำเนินการทางคณิตศาสตร์ใน JavaScript จะไม่รายงานข้อผิดพลาดเมื่อเป็นศูนย์ล้นหรือหารด้วยศูนย์ อย่างไรก็ตามผลการดำเนินการเชิงตัวเลขเกินจำนวนที่สามารถแสดงใน JavaScript (ล้น) และผลลัพธ์เป็นค่าที่ไม่มีที่สิ้นสุด (Infinty) พิเศษซึ่งแสดงเป็น Infinty ใน JavaScript ในทำนองเดียวกันเมื่อค่าของจำนวนลบเกินช่วงของตัวเลขลบที่ JavaScript สามารถแสดงออกได้ผลลัพธ์คืออินฟินิตี้เชิงลบซึ่งแสดงเป็น -infinty ใน JavaScript คุณสมบัติเชิงพฤติกรรมของค่าอินฟินิตี้นั้นสอดคล้องกับสิ่งที่เราคาดหวัง: ผลของการเพิ่มการลบการคูณและการแบ่งตามพวกเขาคืออินฟินิตี้ (รักษาสัญญาณ)
Underflow เป็นสถานการณ์ที่เกิดขึ้นเมื่อผลการคำนวณอยู่ใกล้กับศูนย์และมีขนาดเล็กกว่าค่าต่ำสุดที่ JavaScript สามารถเป็นตัวแทนได้ เมื่อจำนวนเงินลบ underflows JavaScript ส่งคืนค่าพิเศษ "ลบศูนย์" ซึ่ง (ลบศูนย์) เกือบจะเหมือนกับศูนย์ปกติ โปรแกรมเมอร์ JavaScript ไม่ค่อยใช้ศูนย์ลบ
JavaScript ที่กำหนดไว้ล่วงหน้าตัวแปรทั่วโลก Infinaty และ NAN เพื่อแสดงค่าที่ไม่ใช่ตัวเลข ใน ECMASCIPT3 ค่าทั้งสองนี้สามารถอ่านและเขียนได้ Ecmascript5 แก้ไขปัญหานี้โดยกำหนดว่าเป็นการอ่านอย่างเดียว ค่าแอตทริบิวต์ที่กำหนดโดยวัตถุตัวเลขใน ECMASCIPT3 ยังอ่านได้อย่างเดียวนี่คือตัวอย่างบางส่วน:
การคัดลอกรหัสมีดังนี้:
Infinity // เริ่มต้นตัวแปรที่อ่านได้/เขียนเป็นอินฟินิตี้
number.positive_infinity // ค่าเดียวกันอ่านเท่านั้น
1/0 // นี่คือค่าเดียวกัน
number.max_value + 1 // ผลการคำนวณยังคงไม่มีที่สิ้นสุด
number.negative_infinity // หมายถึงอินฟินิตี้เชิงลบ
-ความมีสติสัมปชัญญะ
-1/0
-number.max_value -1
NAN // เริ่มต้นตัวแปรที่อ่านได้/เขียนไปยัง NAN
number.nan // ค่าเดียวกัน แต่อ่านเท่านั้น
0/0 // ผลการคำนวณยังคงเป็น NAN
number.min_value/2 // underflow เกิดขึ้น ผลลัพธ์ที่คำนวณคือ 0
-number.min_value/2 // ลบศูนย์
-1/infinity // zero ลบ
-0 // ลบศูนย์
มีความพิเศษเล็กน้อยเกี่ยวกับค่าที่ไม่ใช่ตัวเลขใน JavaScript ซึ่งไม่เท่ากับมนุษย์และค่านิยมรวมถึงตัวเอง กล่าวอีกนัยหนึ่งมันเป็นไปไม่ได้ที่จะตัดสินว่า x เป็น nan โดย x == nan ควรใช้ X แทน! = x เพื่อตัดสินว่าถ้า X เป็น NAN เท่านั้นผลลัพธ์ของการแสดงออกนั้นเป็นจริง ฟังก์ชั่นฟังก์ชัน iSnan () คล้ายกับนี้ หากพารามิเตอร์เป็น NAN หรือค่าที่ไม่ใช่ตัวเลข (เช่นสตริงและวัตถุ) จะส่งคืนจริง มีฟังก์ชั่นที่คล้ายกันใน JavaScript ที่ isfinite () ซึ่งส่งคืนจริงเมื่อพารามิเตอร์ไม่ใช่ Nan, Infinty หรือ -infinity
ค่าศูนย์ลบก็ค่อนข้างพิเศษ มันเท่ากับศูนย์บวกและลบ (แม้จะตัดสินโดยใช้การทดสอบความเท่าเทียมกันอย่างเข้มงวดของ JavaScript) ซึ่งหมายความว่าค่าทั้งสองนี้เกือบจะเหมือนกันทั้งหมดยกเว้นการยกเว้น:
การคัดลอกรหัสมีดังนี้:
var zero = 0;
var negz = -0;
zero === negz // => ค่าบวกเป็นบวกและค่าลบจริงค่าเท่ากัน
1/zero === 1/negz // false positive infinity และ infinity เชิงลบแตกต่างกัน
IIII.Binary หมายเลขจุดลอยตัวและข้อผิดพลาดในการปัดเศษ
มีจำนวนจริงนับไม่ถ้วน แต่ JavaScript สามารถแสดงตัวเลข จำกัด ผ่านรูปแบบของหมายเลขจุดลอยตัว (เพื่อความแม่นยำมี 18 437 736 874 454 810 627) กล่าวคือเมื่อใช้จำนวนจริงในจาวาสคริปต์
JavaScript ใช้สัญลักษณ์หมายเลขจุดลอยตัว IEEE-754 (ใช้โดยเกือบทุกภาษาการเขียนโปรแกรมที่ทันสมัย) นี่คือการเป็นตัวแทนไบนารีที่สามารถแสดงเศษส่วนได้อย่างถูกต้องเช่น 1/2 1/8 และ 1/1024 น่าเสียดายที่เศษส่วนที่เรามักใช้โดยเฉพาะอย่างยิ่งในการคำนวณทางการเงินทั้งหมดขึ้นอยู่กับเศษส่วนทศนิยม 1/10, 1/100 ฯลฯ สัญกรณ์ไบนารีไม่สามารถแสดงจำนวนง่าย ๆ เช่น 0.1
ตัวเลขในจาวาสคริปต์มีความแม่นยำเพียงพอ และสามารถใกล้เคียงกับ 0.1 แต่ในความเป็นจริงการไม่สามารถแสดงตัวเลขได้อย่างถูกต้องทำให้เกิดปัญหาบางอย่าง
การคัดลอกรหัสมีดังนี้:
var x = .3 - .2;
var y = .2 - .1;
การแจ้งเตือน (x == y) // => เท็จค่าสองค่าไม่เท่ากัน
x == .1 // => false .3-.2 ไม่เท่ากับ. 1
y == .1 // => true .2-.1 เท่ากับ 1
เนื่องจากข้อผิดพลาดในการปัดเศษความแตกต่างโดยประมาณระหว่าง 0.3 และ 0.2 ไม่ได้เท่ากับความแตกต่างโดยประมาณระหว่าง 0.2 และ 0.1 (ในสภาพแวดล้อมการจำลองจริง 0.3-0.2 = 0.099 999 999 999 999 999 999 98 98) ปัญหานี้ไม่เพียง แต่มีอยู่ใน JavaScript เป็นสิ่งสำคัญมากที่จะเข้าใจสิ่งนี้: ปัญหานี้จะเกิดขึ้นในภาษาการเขียนโปรแกรมใด ๆ ที่ใช้หมายเลขจุดลอยไบนารี นอกจากนี้ยังเป็นสิ่งสำคัญที่จะต้องทราบว่าค่าของ X และ Y ในรหัสด้านบนนั้นใกล้เคียงกันมากและค่าที่ถูกต้องสุดท้าย ผลการคำนวณนี้สามารถมีความสามารถสำหรับงานการคำนวณส่วนใหญ่ ปัญหานี้เกิดขึ้นเฉพาะเมื่อเปรียบเทียบว่าทั้งสองค่าเท่ากัน
JavaScript เวอร์ชันในอนาคตอาจสนับสนุนประเภทตัวเลขทศนิยมเพื่อหลีกเลี่ยงปัญหานี้ก่อนที่คุณอาจต้องการใช้จำนวนเต็มขนาดใหญ่สำหรับการคำนวณทางการเงินที่สำคัญ ตัวอย่างเช่นใช้จำนวนเต็ม "เซ็กเมนต์" แทนองค์ประกอบทศนิยม "องค์ประกอบ" สำหรับหน่วยการเงิน
iiiii.date และเวลา
แกนหลักของภาษา JavaScript รวมถึงตัวสร้างวันที่ () ซึ่งเดิมสร้างวัตถุที่สร้างวันที่และเวลา วิธีการของวัตถุวันที่เหล่านี้ให้ API อย่างง่ายสำหรับการคำนวณวันที่ วัตถุวันที่ไม่สามารถเป็นประเภทข้อมูลพื้นฐานเช่นตัวเลข
การคัดลอกรหัสมีดังนี้:
var zhen = วันที่ใหม่ (2011, 0, 1); // 1 มกราคม 2554
var later = วันใหม่ (2011, 0, 1, 17, 10, 30); // วันเดียวกัน
var now = new Date (); // วันที่และเวลาปัจจุบัน
var vertapsed = ตอนนี้ - Zhen; // การลบวันที่ คำนวณจำนวนมิลลิวินาทีของช่วงเวลา
ในภายหลัง getulyear (); // => 2011
ภายหลัง getMonth (); // => 0 เดือนนับตั้งแต่ 0
ภายหลัง getDate (); // => 1 จำนวนวันนับตั้งแต่ 1
ในภายหลัง getday (); // => 5 รับวันของสัปดาห์ 0 หมายถึงวันอาทิตย์ 5 หมายถึงวันอาทิตย์
ภายหลัง. getHours () // => เวลาท้องถิ่น
ภายหลัง. getUtchours () // ใช้ UTC เพื่อแสดงเวลาของชั่วโมงขึ้นอยู่กับเขตเวลา
2. ข้อความ
สตริงเป็นลำดับที่ไม่เปลี่ยนรูปและสั่งซื้อของค่า 16 บิตตัวละครแต่ละตัวมักจะมาจากชุดอักขระ Unicode JavaScript แสดงข้อความผ่านประเภทสตริง ความยาวของสตริงคือจำนวนค่า 16 บิตที่มี ดัชนีของสตริง JavaScript (และอาร์เรย์) เริ่มต้นที่ 0 ความยาวของสตริงว่างคือ 0 และไม่มี "ประเภทตัวอักษร" ที่แสดงถึงอักขระตัวเดียวใน JavaScript เพื่อแสดงค่า 16 บิตเพียงกำหนดให้กับตัวแปรสตริง ความยาวของสตริงนี้คือ 1
ชุดอักขระรหัสด้านในและสตริง JavaScript
JavaScript ใช้ชุดอักขระ Unicode ที่เข้ารหัส UTF-16 และสตริง JavaScript เป็นลำดับที่ประกอบด้วยชุดของค่า 16 บิตที่ไม่ได้เรียงลำดับ อักขระ Unicode ที่ใช้กันมากที่สุดจะแสดงด้วยรหัสด้านใน 16 บิตและแสดงถึงอักขระตัวเดียวในสตริง อักขระ Unicode ที่ไม่สามารถแสดงเป็น 16 บิตตามด้วยกฎการเข้ารหัส UTF-16-ใช้ค่า 16 บิตสองค่าเพื่อสร้างลำดับ (หรือที่เรียกว่า "คู่พร็อกซี") ซึ่งหมายความว่าสตริง JavaScript ที่มีความยาว 2 (สองค่า 16 บิต) อาจเป็นตัวแทนของอักขระ Unicode
การคัดลอกรหัสมีดังนี้:
var p = "π"; // πแสดงด้วยรหัสภายใน 16 บิต 0x03c0
var e = "e"; // E แสดงด้วยรหัสภายใน 17 บิต 0x1d452
p.length // => 1 p มีค่า 16 บิต
E.Length // => 2 E ที่เข้ารหัสโดย UTF-16 มีสองค่า: "/UD835/UDC52"
วิธีการดำเนินการสตริงทั้งหมดที่กำหนดโดย JavaScript ACT ในค่า 16 บิตไม่ใช่อักขระและไม่ประมวลผลรายการพร็อกซีแยกกัน ในทำนองเดียวกัน JavaScript จะไม่สร้างมาตรฐานการประมวลผลสตริง ไม่มีการรับประกันว่าสตริงเป็นรูปแบบ UTF-16 ตามกฎหมาย
ฉันสตริงปริมาณโดยตรง
ปริมาณโดยตรงของสตริงในโปรแกรม JavaScript เป็นลำดับของอักขระที่ล้อมรอบด้วยเครื่องหมายคำพูดเดียวหรือคำพูดสองเท่า สตริงที่คั่นด้วยเครื่องหมายคำพูดเดียวสามารถมีคำพูดสองเท่าและสตริงที่คั่นด้วยคำพูดสองเท่ายังสามารถมีใบเสนอราคาเดียว นี่คือตัวอย่างบางส่วนของการหาปริมาณโดยตรงของสตริง
การคัดลอกรหัสมีดังนี้:
"" // สตริงว่าง, 0 อักขระ
'การทดสอบ'
"3.14"
'name = "myform"'
"คุณไม่ชอบหนังสือของ O'Reily เหรอ?"
ใน eCmascript3 ปริมาณโดยตรงของสตริงจะต้องเขียนในหนึ่งบรรทัดในขณะที่ใน eCmascript5 ปริมาณโดยตรงของสตริงสามารถแบ่งออกเป็นหลายบรรทัดและแต่ละบรรทัดจะต้องจบลงด้วย backslash (/) ไม่ว่าจะเป็น backslash หรืออักขระที่สิ้นสุดบรรทัดเป็นเนื้อหาของปริมาณโดยตรงของสตริง หากคุณต้องการอยู่ด้วยกันคุณสามารถใช้ /n เพื่อหลบหนีอักขระ
ควรสังเกตว่าเมื่อใช้คำพูดเดี่ยวเพื่อกำหนดสตริงคุณต้องระมัดระวังเป็นพิเศษเกี่ยวกับตัวย่อและรูปแบบทั้งหมดเป็นภาษาอังกฤษ อะพอสโทรฟีภาษาอังกฤษและคำพูดเดี่ยวเป็นตัวละครเดียวกันดังนั้น backslashes (/) จะต้องใช้เพื่อหลบหนี
II Escape อักขระ
ในสตริง JavaScript backslashes (/) มีวัตถุประสงค์พิเศษ การเพิ่มตัวละครลงในแบ็คสแลชจะไม่แสดงถึงความหมายที่แท้จริงของพวกเขาอีกต่อไป ตัวอย่างเช่น /n เป็นตัวละครหลบหนีซึ่งแสดงถึงแนวใหม่
การคัดลอกรหัสมีดังนี้:
/o // อักขระ nul
/b // อักขระ backspace
/t // อักขระแท็บแนวนอน
/n // อักขระใหม่บรรทัด
/v // อักขระแท็บแนวตั้ง
/f // การต่ออายุหน้า
/r // อักขระ Return Carriage
/"// คำพูดสองครั้ง
// backslash
/xxx latin-1 อักขระที่ระบุโดยสองบิต hexadecimal
/xxxxxx unicode อักขระที่ระบุโดย hexadecimal xxxxx สี่บิต
การใช้สตริง III
หนึ่งในคุณสมบัติในตัวของ JavaScript คือการเชื่อมต่อสตริง ใช้ Operator + สำหรับสตริงเพื่อแสดงถึงการเชื่อมต่อสตริง ตัวอย่างเช่น
การคัดลอกรหัสมีดังนี้:
var msg = "hello" + "World"; // สร้างสตริงสวัสดีโลก
ในการกำหนดความยาวของสตริง - จำนวนค่า 16 บิตที่มีอยู่คุณสามารถใช้แอตทริบิวต์ความยาวเช่นความยาวของสตริง s
S.Length
นอกเหนือจากแอตทริบิวต์ความยาวแล้วสตริงยังมีวิธีการมากมายที่สามารถเรียกได้
การคัดลอกรหัสมีดังนี้:
var s = "สวัสดีโลก";
S.Charat (0); // "h" ตัวละครตัวแรก
S.Charat (S.Length - 1) // "D" ตัวละครตัวสุดท้าย
S.SubString (1, 4) // "ell" 2-4 อักขระ
S.Slice (1, 4) // ell เหมือนกับข้างบน
S.Slice (-3) // อักขระ 3 ตัวสุดท้ายปรากฏขึ้น
S.Indexof (l ") // 2 ตัวละคร l ตำแหน่งแรกเกิดขึ้น
s.lastindexof ("l") // 10 ครั้งสุดท้ายที่ตัวละคร l ปรากฏขึ้น
s.indexof ("l", 3) // หลังจากตำแหน่ง 3 ตำแหน่งแรกที่อักขระ l ปรากฏขึ้น
s.split (",") // => ["สวัสดี", "โลก"] ถูกแยกออกเป็นย่อย
s.replace ("h", "h") // => "hllo, world" การแทนที่ตัวละครข้อความเต็มรูปแบบ
S.touppercase () // => "สวัสดีโลก"
ใน JavaScript สตริงได้รับการแก้ไขและไม่เปลี่ยนแปลง วิธีการเช่นแทนที่ () และ touppercase () ส่งคืนสตริงใหม่และอักขระดั้งเดิมเองก็ไม่เปลี่ยนแปลง
ใน eCmascript ตัวละครสามารถถือว่าเป็นอาร์เรย์แบบอ่านอย่างเดียว นอกเหนือจากการใช้วิธี Charat () แล้ววงเล็บเหลี่ยมยังสามารถใช้ในการเข้าถึงอักขระแต่ละตัวในสตริง (ค่า 16 บิต)
การคัดลอกรหัสมีดังนี้:
s = "สวัสดีโลก"
S [0] // => "H"
s [s.length-1] // => "d"
Foxfire ได้รองรับการจัดทำดัชนีสตริงสำหรับวิธีนี้มานานแล้วและเบราว์เซอร์ที่ทันสมัยที่สุด (ยกเว้น IE) ตามรอยเท้าของ Mozailla และเสร็จสิ้นคุณสมบัตินี้ก่อนที่ ECMASCRIPT จะเกิดขึ้น
การจับคู่รูปแบบ IIII
JavaScript กำหนดตัวสร้าง regexp () ซึ่งใช้เพื่อสร้างวัตถุที่แสดงถึงการจับคู่รูปแบบข้อความ รูปแบบเหล่านี้เรียกว่า "นิพจน์ทั่วไป" ไวยากรณ์การแสดงออกปกติใน JavaScript Perl ทั้งวัตถุสตริงและ regexp กำหนดฟังก์ชั่นที่ใช้นิพจน์ทั่วไปเพื่อจับคู่รูปแบบค้นหาและแทนที่
วัตถุ Regexp ไม่ใช่ประเภทข้อมูลพื้นฐานในภาษา เช่นวันที่มันเป็นเพียงวัตถุพิเศษที่มี API ที่ใช้งานได้จริง การแสดงออกปกติมีไวยากรณ์ที่ซับซ้อนและ API ที่หลากหลาย มันจะได้รับการแนะนำในรายละเอียดในบทที่ 10 Regexp เป็นเครื่องมือประมวลผลข้อความที่ทรงพลังและใช้กันทั่วไปและนี่เป็นเพียงภาพรวม
แม้ว่า regexp ไม่ใช่ประเภทข้อมูลพื้นฐานในภาษา แต่ก็ยังมีปริมาณโดยตรงและสามารถใช้โดยตรงใน JavaScript ข้อความระหว่างสองสแลชเป็นปริมาณโดยตรงของนิพจน์ทั่วไป สแลชที่สองอาจติดตามตัวอักษรอย่างน้อยหนึ่งตัว ใช้เพื่อปรับเปลี่ยนความหมายของรูปแบบการจับคู่ ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
/^html/// สตริงจับคู่เริ่มต้นด้วย html
/[1-9] [0-9]*/// จับคู่หมายเลขที่ไม่ใช่ศูนย์ตามด้วยหมายเลขใด ๆ
// bjavascript/b/i/// จับคู่คำ JavaScript และละเว้นตัวพิมพ์บนและล่าง
วัตถุ regexp กำหนดวิธีการที่มีประโยชน์มากมายและสตริงก็มีวิธีการที่สามารถยอมรับพารามิเตอร์ regexp ได้ ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
var text = "การทดสอบ: 1,2,3"; // ตัวอย่างข้อความ
รูปแบบ var = // d+/g // จับคู่อินสแตนซ์ทั้งหมดที่มีหมายเลขหนึ่งหรือมากกว่า
pattern.test (text) // => true: การจับคู่สำเร็จ
text.search (รูปแบบ) // => 9: ตำแหน่งที่นัดแรกสำเร็จ
text.match (รูปแบบ) // => ["1", "2", "3"] ทั้งหมดที่ตรงกัน
text.repeat (รูปแบบ, "#"); // => "การทดสอบ:#,#,#"
text.split (// d+/); // => ["", "1", "2", "3"]: ใช้อักขระที่ไม่ใช่ตัวเลขเพื่อสกัดกั้นสตริง
3. ค่าบูลีน
ค่าบูลีนหมายถึงจริงหรือเท็จเปิดหรือปิด ประเภทนี้มีเพียงสองค่าและคำว่าจริงหรือเท็จสงวนไว้
ผลลัพธ์ของคำสั่งเปรียบเทียบในจาวาสคริปต์มักจะเป็นค่าบูลีน ตัวอย่างเช่น
A == 4
รหัสนี้ใช้เพื่อตรวจสอบว่าค่าของ A ของตัวแปรเท่ากับ 4 ถ้าเท่ากันค่าจะเป็นจริงหรือไม่หากค่าไม่เท่ากัน
ค่าบูลีนมักจะใช้ในคำสั่งควบคุม JavaScript เช่นคำสั่ง IF/อื่น ๆ ใน JavaScript หากค่าบูลีนเป็นจริงให้ดำเนินการตรรกะชิ้นแรกและหากรหัสชิ้นอื่นเป็นเท็จเช่น
การคัดลอกรหัสมีดังนี้:
ถ้า (a == 4)
b = b + 1;
อื่น
a = a + 1;
ค่า JavaScript ใด ๆ สามารถแปลงเป็นค่าบูลีนและค่าต่อไปนี้จะถูกแปลงเป็นเท็จ
การคัดลอกรหัสมีดังนี้:
ไม่ได้กำหนด
โมฆะ
0
-0
น่าน
"" // สตริงว่างเปล่า
ค่าอื่น ๆ ทั้งหมดรวมถึงวัตถุทั้งหมด (อาร์เรย์) จะถูกแปลงเป็นจริงเท็จและค่า 6 ข้างต้นที่สามารถแปลงเป็นเท็จบางครั้งเรียกว่า "ค่าเท็จ" JavaScript คาดว่าเมื่อใช้ค่าบูลีนค่าเท็จจะถือว่าเป็นเท็จและค่าที่แท้จริงจะถือว่าเป็นจริง
ลองมาดูตัวอย่าง การเพิ่มตัวแปร O เป็นวัตถุหรือโมฆะคุณสามารถใช้คำสั่ง IF เพื่อตรวจจับว่า o เป็นค่าที่ไม่ใช่ NULL
ถ้า (o! == null) ...
ตัวดำเนินการที่ไม่เท่ากัน "! ==" เปรียบเทียบ O และ NULL และให้ผลลัพธ์ที่เป็นจริงหรือเท็จ ก่อนอื่นคุณสามารถเพิกเฉยต่อคำสั่งเปรียบเทียบได้ที่นี่ NULL เป็นค่าเท็จและวัตถุเป็นค่าที่แท้จริง
ถ้า (o) ...
สำหรับกรณีแรกรหัสหลังจากนั้นจะถูกดำเนินการเฉพาะเมื่อ O ไม่เป็นโมฆะและข้อ จำกัด ของกรณีที่สองนั้นไม่เข้มงวด สิ่งนี้จะถูกดำเนินการเฉพาะในกรณีที่ O ไม่ใช่เท็จหรือค่าเท็จใด ๆ (เช่น NULL หรือไม่ได้กำหนด)
บูลีนมีวิธี TOSTRING () ดังนั้นคุณสามารถใช้วิธีนี้เพื่อแปลงสตริงเป็น "จริง" หรือ "เท็จ" แต่มันไม่มีวิธีการที่เป็นประโยชน์อื่น ๆ และนอกเหนือจาก API ที่ไม่สำคัญนี้แล้วยังมีตัวดำเนินการบูลีนที่สำคัญสามตัว
&& โอเปอเรเตอร์ || โอเปอเรเตอร์และผู้ดำเนินการ Unary "!" ดำเนินการบูลีนไม่ใช่ (ไม่ใช่) หากค่าที่แท้จริงส่งคืนค่าเท็จค่าเท็จจะส่งกลับจริงเช่น
การคัดลอกรหัสมีดังนี้:
if ((x == 0 && y == 0) ||! (z == 0)) {
// x และ y เป็นทั้งศูนย์หรือ z ไม่ใช่ศูนย์
-
4. ไม่ได้กำหนดและไม่ได้กำหนด
NULL เป็นคำหลักในภาษา JavaScript มันแสดงถึงค่าพิเศษ "ค่า NULL" สำหรับ NULL มันจะดำเนินการ typeof () และส่งคืนวัตถุ กล่าวคือ NULL ถือได้ว่าเป็นค่าวัตถุพิเศษความหมาย "ไม่ใช่วัตถุ" แต่ในความเป็นจริง NULL มักจะถือว่าเป็นสมาชิกประเภทเดียวของมัน มันสามารถแสดงถึงตัวเลขสตริงและวัตถุนั้นเป็น "ไร้ค่า" ภาษาการเขียนโปรแกรมส่วนใหญ่มี null เช่น JavaScript และคุณสามารถคุ้นเคยกับ NULL หรือ NIL
JavaScript ยังมีค่าที่สองที่ระบุตำแหน่งว่างของค่า ใช้เพื่อแสดงถึง "ค่า NULL" ที่ลึกกว่า มันเป็นค่าของตัวแปร บ่งชี้ว่าตัวแปรยังไม่ได้เริ่มต้น หากคุณต้องการสอบถามค่าของแอตทริบิวต์วัตถุหรือองค์ประกอบอาร์เรย์มันจะส่งคืนที่ไม่ได้กำหนดหมายความว่าแอตทริบิวต์หรือองค์ประกอบไม่มีอยู่ Undefined เป็นตัวแปรทั่วโลกที่กำหนดไว้ล่วงหน้า (แตกต่างจาก NULL ไม่ใช่คำหลัก) และค่าของมันไม่ได้กำหนด หากคุณใช้ typeof เพื่อทดสอบประเภทที่ไม่ได้กำหนด "undefined" จะถูกส่งคืนแสดงให้เห็นว่าค่าเป็นสมาชิกประเภทเดียวเท่านั้น
แม้ว่า Null และ Undefined นั้นแตกต่างกัน แต่พวกเขาทั้งคู่เป็นตัวแทน "ตำแหน่งงานว่างของค่า" และทั้งสองมักจะใช้แทนกันได้ ผู้ประกอบการที่ตัดสินความเท่าเทียมกัน "==" คิดว่าทั้งสองมีความเท่าเทียมกัน (ใช้ตัวดำเนินการความเท่าเทียมกันอย่างเข้มงวด "===" เพื่อแยกแยะพวกเขา) ในกรณีที่ค่าคาดว่าจะเป็นประเภทบูลีนค่าของพวกเขาทั้งหมดเป็นเท็จ คล้ายกับเท็จ ทั้ง null และ undefined ไม่มีคุณสมบัติและวิธีการใด ๆ ในความเป็นจริงการใช้ "." และ "[]" เพื่อเข้าถึงสมาชิกหรือวิธีการของค่าทั้งสองนี้จะสร้างข้อผิดพลาดประเภท
คุณอาจคิดว่า Undefined แสดงถึงตำแหน่งที่มีการใช้ชีวิตในระดับระบบโดยไม่คาดคิดในขณะที่ Null แสดงถึงตำแหน่งระดับโปรแกรมปกติหรือที่คาดหวังของค่านิยม หากคุณต้องการคัดลอกไปยังตัวแปรหรือคุณสมบัติหรือส่งผ่านเป็นพารามิเตอร์ลงในฟังก์ชั่น NULL เป็นตัวเลือกที่ดีที่สุด
5. วัตถุระดับโลก
ส่วนก่อนหน้านี้หารือเกี่ยวกับประเภทองค์ประกอบและค่าดั้งเดิมของ JavaScript ประเภทวัตถุ - วัตถุอาร์เรย์และฟังก์ชั่น / แต่มีคลาสที่สำคัญมากของวัตถุที่ต้องไม่ชัดเจนในขณะนี้: วัตถุทั่วโลก
Global Object มีการใช้งานที่สำคัญใน JavaScript คุณสมบัติของวัตถุระดับโลกเป็นสัญลักษณ์ที่กำหนดทั่วโลก โปรแกรม JavaScript สามารถใช้โดยตรง เมื่อล่าม JavaScript เริ่มต้นจะสร้างวัตถุระดับโลกใหม่และให้ชุดของคุณสมบัติเริ่มต้นที่กำหนดไว้
อสังหาริมทรัพย์ระดับโลกเช่น Infinty ที่ไม่ได้กำหนดและ NAN
ฟังก์ชั่นทั่วโลกเช่น isnan (), parseint () และ eval ()
ตัวสร้างเช่นวันที่ (), regexp (), สตริง (), วัตถุ () และอาร์เรย์ ()
วัตถุระดับโลกเช่นคณิตศาสตร์และ JSON
แอตทริบิวต์เริ่มต้นของวัตถุระดับโลกไม่ใช่คำที่สงวนไว้ แต่ควรได้รับการปฏิบัติเป็นคำที่สงวนไว้
ที่ระดับบนสุดของรหัส - รหัส JavaScript ไม่ได้อยู่ในฟังก์ชั่นใด ๆ คุณสามารถอ้างถึงวัตถุส่วนกลางผ่านคำหลัก JavaScript
var global = this; // กำหนดตัวแปรทั่วโลกที่อ้างอิงวัตถุระดับโลก
ในไคลเอนต์ JavaScript วัตถุหน้าต่างทำหน้าที่เป็นวัตถุระดับโลก วัตถุหน้าต่างทั่วโลกนี้มีการอ้างอิงหน้าต่างที่คุ้นเคย มันสามารถแทนที่สิ่งนี้เพื่ออ้างถึงวัตถุทั่วโลก Windows กำหนดคุณลักษณะหลักทั่วโลก อย่างไรก็ตามแอตทริบิวต์ทั่วโลกอื่น ๆ บางส่วนถูกกำหนดไว้สำหรับเว็บเบราว์เซอร์และจาวาสคริปต์แบบโต้ตอบ
เมื่อสร้างขึ้นเป็นครั้งแรกวัตถุทั่วโลกจะกำหนดค่าทั่วโลกที่กำหนดไว้ล่วงหน้าทั้งหมดใน JavaScript และวัตถุพิเศษนี้ยังมีค่าทั่วโลกที่กำหนดไว้สำหรับโปรแกรม หากรหัสประกาศตัวแปรทั่วโลก ตัวแปรทั่วโลกนี้เป็นคุณลักษณะของวัตถุส่วนกลาง
6. วัตถุบรรจุภัณฑ์
วัตถุ JavaScript เป็นค่าผสม: มันเป็นคอลเลกชันของแอตทริบิวต์หรือค่าที่มีชื่อ ค่าแอตทริบิวต์ถูกอ้างอิงผ่าน "." เมื่อค่าแอตทริบิวต์เป็นฟังก์ชันมันเป็นวิธีการและใช้ OM () เพื่อถ่ายโอนวิธีการในวัตถุ o
เราเห็นว่าสตริงยังมีคุณสมบัติและวิธีการ
การคัดลอกรหัสมีดังนี้:
var s = "Hello World";
var word = s.substring (s.indexof ("")+1, s.length); // ใช้แอตทริบิวต์ของสตริง
document.write (Word) // "Ello World"
เนื่องจากสตริงไม่ใช่วัตถุทำไมจึงมีคุณสมบัติ? ตราบใดที่แอตทริบิวต์ของสตริงถูกอ้างอิง JavaScript จะแปลงค่าของสตริงเป็นวัตถุโดยเรียกสตริงใหม่ซึ่งสืบทอดวิธีการสตริง และใช้ในการประมวลผลการอ้างอิงแอตทริบิวต์ เมื่ออ้างอิงแอตทริบิวต์ใหม่ เมื่อการอ้างอิงเสร็จสิ้นวัตถุที่สร้างขึ้นใหม่จะถูกทำลาย (วัตถุชั่วคราวนี้ไม่จำเป็นต้องสร้างหรือทำลาย แต่กระบวนการนี้มีลักษณะเช่นนี้)
เช่นสตริงตัวเลขและค่าบูลีนยังมีวิธีการของตัวเองสร้างวัตถุชั่วคราวผ่านตัวสร้างหมายเลข () และตัวสร้างบูลีน () วิธีการทั้งหมดเหล่านี้เรียกจากวัตถุชั่วคราวนี้ (null และ undefined ไม่ได้ถูกห่อหุ้มวัตถุการเข้าถึงคุณสมบัติของพวกเขาจะมีข้อผิดพลาดประเภท)
ดูรหัสต่อไปนี้และคิดเกี่ยวกับกระบวนการดำเนินการของพวกเขา
การคัดลอกรหัสมีดังนี้:
var s = "ทดสอบ";
s.len = 4; // ตั้งค่าคุณสมบัติสำหรับมัน
var t = s.len // ค้นหาคุณสมบัตินี้
เมื่อเรียกใช้รหัสนี้ค่าของ t จะไม่ได้กำหนด บรรทัดที่สองของรหัสสร้างวัตถุสตริงชั่วคราวและให้ค่า LEN เป็น 4 วัตถุจะถูกทำลาย บรรทัดที่สามใช้สตริงต้นฉบับ (ไม่ได้แก้ไข) เพื่อสร้างวัตถุสตริงใหม่และพยายามอ่านแอตทริบิวต์ของ Len
คุณสมบัตินี้ไม่ได้มีอยู่ตามธรรมชาติแสดงให้เห็นว่าผลลัพธ์ไม่ได้กำหนด รหัสนี้แสดงให้เห็นว่าเมื่ออ่านค่าคุณสมบัติ (หรือวิธีการ) ของสตริงอาร์เรย์และค่าบูลีนมันจะทำงานเหมือนวัตถุ แต่ถ้าคุณพยายามกำหนดค่าให้กับคุณสมบัติของมัน การดำเนินการนี้จะถูกละเว้น; การดัดแปลงเกิดขึ้นกับวัตถุชั่วคราวเท่านั้น วัตถุชั่วคราวนี้ไม่ได้เก็บไว้
ควรสังเกตว่าการสร้างวัตถุ wrapper สามารถแสดงผ่านสตริง (), number () และ boolean () ตัวสร้าง:
การคัดลอกรหัสมีดังนี้:
var s = "ทดสอบ"
n = 1,
b = true;
var s = สตริงใหม่;
var n = หมายเลขใหม่ (n);
var b = บูลีนใหม่ (b);
JavaScript แปลง wrapper เป็นค่าดั้งเดิมเมื่อจำเป็นดังนั้นวัตถุ SNB ในรหัสก่อนหน้าบ่อยครั้ง - แต่ไม่เสมอไป - แสดงถึงค่าเดียวกับ SNB, "==" เท่ากับผู้ปฏิบัติงานถือว่าค่าดั้งเดิมและวัตถุ wrapper เท่ากับ
แต่ตัวดำเนินการเต็ม "===" ถือว่าพวกเขาเป็นความไม่เท่าเทียมกันและความแตกต่างระหว่างค่าดั้งเดิมและวัตถุที่ห่อสามารถมองเห็นได้ผ่านตัวดำเนินการประเภทของ Typeof
7. ค่าดั้งเดิมที่ไม่เปลี่ยนรูปและการอ้างอิงวัตถุที่ไม่แน่นอน
ค่าดั้งเดิมของ JavaScript (หมายเลขบูลีนโมฆะที่ไม่ได้กำหนด) นั้นแตกต่างจากวัตถุโดยพื้นฐาน (รวมถึงอาร์เรย์และฟังก์ชั่น) ค่าดั้งเดิมไม่สามารถเปลี่ยนแปลงได้ ไม่มีวิธีใดที่สามารถ (หรือกลายพันธุ์) ค่าดั้งเดิม เห็นได้ชัดว่ามันเป็นความจริงสำหรับตัวเลขและบูลีน - การเปลี่ยนค่าของตัวเลขนั้นไม่สมเหตุสมผลในตัวเอง แต่ก็ไม่ชัดเจนสำหรับสตริงเพราะสตริงดูเหมือนจะเป็นตัวละคร เราคาดหวังว่าอักขระในสตริงสามารถแก้ไขได้โดยดัชนีที่ระบุ ในความเป็นจริง JavaScript ห้ามการทำสิ่งนี้ วิธีการทั้งหมดในสตริงดูเหมือนจะส่งคืนสตริงที่แก้ไขซึ่งเป็นสตริงใหม่
การคัดลอกรหัสมีดังนี้:
var s = "Hello World";
S.touppercase (); // ส่งคืน "Hello World" และไม่เปลี่ยนมูลค่าของ S
S // => สตริงดั้งเดิม "Hello World" ไม่เปลี่ยนแปลง
原始值的比较是值的比较,只有在他们的值相当时它们在才相等。这对数字、布尔值、null和undefined来说听起来有点难,并没有其他办法来比较他们。同样,对于字符串来说则不那么明显;如果比较两个单独的字符串,当且仅当他们的长度相等且每个索引的字符都相等时,javascript的才认为相等。
การคัดลอกรหัสมีดังนี้:
var o = {x:1} //定义一个对象
ox = 2 //通过修改对象的属性来改变对象
oy = 3 //再次更改这个对象,给它增加一个新属性
var a =[1,2,3] //数组也是可以修改的
a[0]=0; //更改数组中的一个元素
a[3]=4; 给数组增加一个新元素
对象的比较并非值的比较:即使两个对象包含同样的属性及相同的值,他们也是不相等的,各个索引元素完全相等的两个数组也不相等
การคัดลอกรหัสมีดังนี้:
var o ={x:1}, p={x:1}//两个具有相同属性的两个对象
o === p ;//=>false 两个单独的对象永不相等( o == p ; =>false)
var a =[],b=[]; //两个单独的空数组
a === b ; //=>false两个单独的数组永不相等
我们通常将对象称为引用类型(reference type),以此来和javascript的基本类型区分开来。依照术语的叫法,对象都是引用(reference),对象的比较均是引用的比较;当且当它们应用同一个基对象时,它们才相等。
การคัดลอกรหัสมีดังนี้:
var a = []; //定义一个引用空数组的变量a
var b = a; //变量b引用同一个数组
b[0] = 1;
a[0] //=>1 变量a也会修改
a === b //=>true a和b引用同一个数组,因此他们相等。
就像你刚才看到的如上代码,将对象(或数组)赋值给一个变量,仅仅是赋值的引用值:对象本身并没有复制一次。
如果你想得到一个对象或数组的副本,则必须显式复制对象的每个属性或数组的每个元素。下面的这个例子则是通过循环来完成对数组的复制。
การคัดลอกรหัสมีดังนี้:
var a = ['a', 'b', 'c']; //待复制的数组
var b = []; //复制到目标的空数组
for (var i = 0; i < a.length; i++) { //遍历a[]中的每个元素
b[i] = a[i]; //将元素复制到b中。
-
同样的,如果我们想比较两个单独或者数组,则必须比较他们的属性或元素。下面这段代码定义了一个比较练个数组的函数。
การคัดลอกรหัสมีดังนี้:
function equalArrays(a, b) {
if (a.length != b.length) return false; //两个长度不相同的数组不相等
for (var i = 0; i < a.length; i++) //循环遍历所有元素
if (a[i] !== b[i]) return false; //如果有任意元素不等,则数组不相等
return true; // 否则他们相等
-
8.类型转化
javascript中的取值型非常灵活,我们已经从布尔值看到了这一点:当javascript期望使用一个布尔值时候,你可以提供任意类型值。javascript将根据需要自行转换类型。一些值(真值)为true,其它值(假值)转化为false.这在其它类型中同样适用。如果javascript期望使用一个字符串,它把给定的值转换为字符串。如果javascript期望使用一个数组,它把给定的值转换为数字(如果转化结果无意义的话将返回NaN),一些例子如下:
การคัดลอกรหัสมีดังนี้:
10 + "object" //=> "10object";
"7" * "4" // =>28 两个字符串均转化为数字
var n = 1 - "x" // =>NaN字符串x无法转换为数字
n + " objects" // =>"NaN objects":NaN转换为字符串"NaN"
下表说明了在javascript中如何进行类型转化。粗体突出了那些让你倍感意外的类型转化。空单元格表示不必要也没有执行的转换。
| ค่า | 转换为字符串 | ตัวเลข | 布尔值 | วัตถุ |
| undefined โมฆะ | "undefined" "โมฆะ" | NaN 0 | เท็จ เท็จ | throws TypeError throws TypeError |
| จริง เท็จ | "ture" "เท็จ" | 1 0 | new Boolean(true) new Boolean(false) | |
| ""(空字符串) "1.2"(非空,数字) "one"(非空,非数字) | 0 1.2 NaN | เท็จ จริง จริง | new String("") new String("1.2") new String("one") | |
| 0 -0 NaN Infinty -Infinty 1(无穷大,非零) | "0" "0" "NaN" "Infinity" "-Infinity" "1" | เท็จ เท็จ เท็จ จริง จริง จริง | new Number(0); new Number(-0); new Number(NaN) new Number(Infinty) new Number(-Infinty) new Number(1) | |
| {}(任意对象) [](任意数组) [9](1个数字元素) ['a'](其它数组) function(){}(任意函数) | 参考本小节第三节内容 - "9" 使用join()方法 参考本小节第三节内容 | 参考本小节第三节内容 0 9 NaN NaN | จริง จริง จริง จริง จริง |
上表提到的原始值到原始值的转换行对简单,我们已经在第本文第三小节讨论过转换为布尔值的情况了。所有原始值转换为字符串的情形也已经明确定义。转换为数字的情形比较微妙。那些以数字表示的字符串可以直接转化为数字,也允许在开始和结尾处带有空格。但在开始和结尾处的任意非空字符都不会被当成数字量的一部分,进而造成字符串为数字的结果为NaN。有一些数字转换看起来让人奇怪:true转换为1,false、空字符串""转换为0.
原始值到对象的转换也非常简单,原始值通过调用String(),Number()或Boolean()构造函数,转化为它们各自的包装对象。见本文第6节。
null和undefined属于例外,当将它们用在期望是一个对象的地方都会造成一个类型错误(TypeError)异常。而不会执行正常的转换。
对象到原始值的转换多少有些复杂,本小节第三小节有专门描述。
ฉัน. Conversion and Equality
由于javascript可以做灵活的类型转换,因此其“==”相等运算符也随相等的含义灵活多变。例如:如下这些比较结果均是true;
null == undefined //这两值被认为相等
"0" == 0 //在比较之前,字符串转换成数字。
0 = false //在这之前布尔值转换成数字。
"0" ==false //在比较之前字符串和布尔值都转换成数字
在第四章9节第一小节相信讲解了“==”等于运算符在判断两个值是否相等时做了那些类型转换,并同样介绍了“===”恒等运算符在判断相等时并未做任何的类型转换。
需要特别注意的是:一个值转换为另一个值并不意味着两个值相等。比如在期望使用布尔值的地方使用了undefined,将会转换为false,但这不表明undefined==false。javascript运算符和语句期望使用多样化的数据类型,并可以互相转换。if语句将undefined转化为false,但“==”运算符从不试图将其转化为布尔值。
ii.显式类型转化
尽管javascript可以做做很多类型转换,但有时仍需要做显式转换,或者为了使代码变得清晰易读而做显式转换。
做显式转换最重简单的方法就是使用Boolean()、Number()、String()或Object函数。我们在本文第6节已经介绍过了. 当不通过new运算符调运这些函数时,他们会作为类型转换函数并按照上边表格所描述的规则做类型转换。
การคัดลอกรหัสมีดังนี้:
Number("3") //=>3
String(false) //=>"false"或使用false.toString()
Boolean([]) //=>true
Object(3) // =>new Number(3)
需要注意的是,除了null或undefined之外的任何值都具有toString()方法,在这个方法的执行结果通常和String()方法返回的结果一致。同样需要注意的话,如果试图把null或undefined转化为对象。则会抛出一个类型错误typeerro。Object()函数在这种情况下不会抛出异常:它仅简单返回一个新创建的空对象。
javascript中的某些运算符会做隐式的类型转换,有时用于类型转换。如果“+”运算符的一个操作数是字符串,它将会把令一个操作数转换为字符串。一元“+”运算符将其操作数转换为数字。同样,一元“!”运算符将其操作数转换为布尔值取反,在代码中常会看到这种类型转换的惯用法。
การคัดลอกรหัสมีดังนี้:
x + "" // 等于字符串String(x)
+x //等价于Number(x),也可以写成x-0
!!x //等价于Boolean(x)
在计算机中数字的解析和格式化代码是非常普通的工作。javascript中提供了专门的函数和方法用来更加精确的数字到字符串(number-to-string)和字符串到数字(string-to-number)的抓换。
Nmuber类定义的toString()方法可以接收表示基数(二进制,八进制,十六进制等)的可选参数,如果不指定该参数,转化规则将是十进制。同样也可以将数字转换为其它进制数。(范围在2-36之间)
การคัดลอกรหัสมีดังนี้:
var n = 17;
b_string = n.toString(2); //转化为10001
o_string = "0" + n.toString(8); //转化为八进制021
hex_string = "0x" + n.toString(16); //转化为16进制0x11
javascript为控制输出中小数点位置和有效数字位数,或者决定是否需要指定指数计数法。Number类为这种数字到字符串定义了三个方法。
toFixed()根据小数点后指定位数,将数字转换为字符串,它从不使用指数计数法。toExponential()使用指数计数法,将数字转换为指数形式的字符串,其中小数点前只有一位,小数点后的位置则由参数指定(也就是说有效数字位数要比指定的位数多一位)。toPrecision()根据指定的有效数字位数,将数字转换为字符串。如果有效数字的位数小于数字整数部分的位数,则转换成指数形式。我们注意到,三个方法都会适当的进行四舍五入或填充0,
การคัดลอกรหัสมีดังนี้:
var n = 123456.789;
n.toFixed(0); //"123457"
n.toFixed(2); //"123456.79"
n.toFixed(5); //"123456.78900"
n.toExponential(1); //"1.2e+5"
n.toExponential(3); //"1.235e+5"
n.toPrecision(4); // "1.235e+5"
n.toPrecision(7); //"123456.8"
n.toPrecision(10); //"123456.7890"
如果通过Number()转换函数传入一个字符串,它会试图将其转化为一个整数或浮点数直接量,这个方法只能基于十进制进行转换,并且不能出现非法的尾随字符。parseInt()和parseFloat()函数(它们是全局函数,不属于人和类的方法),更加灵活。parseInt()只解析整数。而parseFloat()则可以解析整数和浮点数。如果字符串前边是0x或0X,parseInt()将其解析为16进制数。两个方法都会跳过任意量的前导空格,尽可能解析更多数值字符。并忽略后边的内容。如果第一个是非法的数字直接量,则返回NaN
การคัดลอกรหัสมีดังนี้:
parseInt("3many nice") //=>3;
parseFloat("3.14meters") //=>3.14
parseInt("-12.34") //=>-12
parseInt("0xff") //=>255
parseInt("-0XFF") //=>-255
parseFloat(".1") // =>0.1
parseInt("0.1") //=> 0
parseInt(".1") //=>NaN 不能以.开始
parseInt("$112") //=>NaN 不能以$开头
parseInt()可以接收第二个可选参数。这个参数指定数字转换的基数。合法的取值范围是2-36
การคัดลอกรหัสมีดังนี้:
parseInt("11", 2) //=>3(1*2+1)
parseInt("ff", 16) //=> 255(15*16 +15)
parseInt("zz", 36) //=>1295(35*36+35)
parseInt("077", 8) // 63(7*8 +7)
parseInt("077", 10) //77(7*10+7)
iii.对象转化为原始值。
对象到布尔值的转换非常简单:所有的对象(包括数组和函数)都转换为true。对于包装对象亦是如此,new Boolean(false)是一个对象而不是原始值,它将转换为true。 对象到字符串(object-to-String)和对象到数字(object-to-number)的转换是通过调用带转换对象的一个方法来完成的。一个麻烦的事实是,javascript对象有两个不同的方法来执行转换,并且接下来要讨论并且接下来要讨论的场景更加复杂。值得注意的是,这里提到的字符串和数字的转换规则只适用于本地对象(native fangf object).宿主对象(例如:由web浏览器定义的对象),根据各自的算法可以转换成字符串和数字。
所有的对象继承了两个转换方法。第一个是toString(), 它的作用是返回一个反映这个对象的字符串。默认的toString()方法并不会返回一个有趣的值。
({x:1,y:2}).toString() //=>"[object object]"
很多类定义了更多特定版本的toString()方法.
例如:数组类(Array class)的toString()方法将每个数组元素转换为一个字符串,并在元素之间添加逗号后并合成结果字符串。
函数类(Function class)的toString()方法返回这个函数的实现定义的表示方式。实际上,这里的实现方式是通常是将用户定义函数转换为javascript源代码字符串。
日期类(Date class)定义toString()方法返回一个可读的(可被javascript-parsable解析的)日期和事件字符串
RegExp class定义的toString()方法将RegExp对象转换为正则表达式直接量字符串。
การคัดลอกรหัสมีดังนี้:
[1, 2, 3].toString(); //=> "1,2,3"
(function(x) {f(x);}).toString(); // =>"function(x){/nf(x); /n}"
//d+/g.toString(); //=> ///d+/g
new Date(2015, 0, 1).toString() //=>Thu Jan 01 2015 00:00:00 GMT+0800 (中国标准时间)
另外一个函数是valueOf(),这个方法的任务并未详细定义:如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示一个原始值,数组、函数和正则表达式简单地继承了这个默认方法,调用这些类型的实例的的valueOf()方法简单地返回对象本身。日期类定义的valueOf()方法返回它的一个内部表示:1970年1月1日以来的毫秒数。
การคัดลอกรหัสมีดังนี้:
var d = new Date(2015, 0, 1); //=>Thu Jan 01 2015 00:00:00 GMT+0800 (中国标准时间)
d.valueOf() //=>1420041600000
通过是用我们刚才讲解过的toString()和valueOf()方法,就可以做到对象到字符串和对象到数字的转换了。但在某些场景中,javascript执行了完全不同的对象到原始值的转换。这些特殊的场景在本节的最后会讲到。
javascript对象到字符串的转换经过了如下这些步奏
如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,javascript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
如果对象没toString()方法,或者这个方法并不返回一个原始值,那么javascript会调用valueOf()方法。如果存在这个方法,则javascript调用它。如果返回值是原始值,javascript将责怪值转换为字符串。
9.变量声明。
在javascript程序中,使用一个变量之前应该先声明,变量是通过var来声明的,如下所示:
var i;
var sum;
也可以通过一个var关键字声明多个变量
var i,sun;
而且还可以将变量的初始值和变量声明和写在一起;
var message = "hello";
var i=0 ,j=0,k=0;
If the variable is specified in the var declaration statement, even though the variable is declared, its initial value is undefined before storing it a value. We noticed that the var statement can also be used in the for and fo/in loops, which can more concisely declare the loop variables used in the loop body syntax. ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
for (var i = 0; i < 10; i++) log(i);
for (var i = 0, j = 10; i < 10, j = 100; i++, j--) console.log(i * j)
for (var p in o) console.log(p);
If the variable is specified in the var declaration statement, even though the variable is declared, its initial value is undefined before storing it a value. We noticed that the var statement can also be used in the for and fo/in loops, which can more concisely declare the loop variables used in the loop body syntax. ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
var i=10;
i="ten";
10.变量作用域
一个变量的左右域(scope)是程序源代码中定义这个变量的区域,全局变量拥有全局作用域,在javascript代码中的任何地方都是定义。然而在函数内部声明变量只在函数体内有定义。他们是局部变量,作用是局部性的。函数参数也是局部变量,它们只在函数体内有定义。
在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖。
การคัดลอกรหัสมีดังนี้:
var scope = "global"; //声明一个全局变量
function checkscope() {
var scope = "local"; //声明一个同名的局部变量
return scope;
-
checkscope(); //=>"local"
尽管在全局作用域编写代码时可以不写var语句,但声明局部变量时则必须使用var语句。
การคัดลอกรหัสมีดังนี้:
scope = "global"; //声明一个全局变量,甚至不使用var来声明
function checkscope2() {
scope = "local"; //修改了全局变量
myscope = "local"; //这里显示式得声明了一个新的全局变量
return [scope, myscope]; -
-
checkscope2(); //=> ["local","local"]:产生了副作用
scope // =>"local"全局变量修改了
myscope //=> "local"全局命名空间搞乱了。
函数定义是可以嵌套的。由于每个函数都有它直接的作用域,因此会出现几个局部作用域嵌套的情况。
การคัดลอกรหัสมีดังนี้:
var scope = "global scope"; //全局变量
function checkscope() {
var scope = "local scope"; //局部变量
function nested() {
var scope = "sested scope"; //嵌套作用域内的局部变量
return scope;
-
return nested();
-
checkscope() //=>"嵌套作用域" sested scope
ฉัน. Function scope and declaration in advance
在一些类似c语言的编程语言中,花括号内的每一段代码都具有各自的左右域,而且变量在声明他们的代码之外是不可见的我们称之为块级作用域(block scope),而javascript中没有块级作用域,javascript取而代之的使用了函数作用域(function scope);变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有意义的。
如下代码,在不同的位置定义了ijk,他们都在同一个作用域内,这三个变量在函数体内均有定义的。
การคัดลอกรหัสมีดังนี้:
function test(o) {
var i = 0; //i在整个函数体内均是定义的
if (typeif o == "object") {
var j = 0; //j在函数体内是有定义的,不仅仅是在这个代码段内
for (var k = 0; k < 10; k++) { //k在函数体内是有定义的,不仅仅是在循环内
console.log(k); //输出数字0-9
-
console.log(k); //k已经定义,输出10
-
console.log(j); //j已经定义了,但可能没有初始化。
-
javascript的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味这变量在声明之前甚至已经可用。javascript的这个特性被非正式的称为声明提前(hoisting),即javascript函数里声明的所有变量(但不涉及赋值)都被提前至函数整体的顶部。如下代码:
การคัดลอกรหัสมีดังนี้:
var scope = "global";
function f() {
console.log (ขอบเขต); //Output "undefined", not "global"
var scope = "local"; //变量在这里赋初始值,但变量本身在函数体内任何地方都是有定义的
console.log (ขอบเขต); //Output "local"
你可能误以为函数的第一行会输出"global",因为代码还没有执行到var语句声明局部变量的地方。其实不然,由于函数作用域的特性模具部变量在整个函数体内始终有定义的,也就是说,在函数体内局部变量覆盖了同名全局变量。尽管如此,只有在程序执行到var语句的时候,局部变量才能正真的被赋值。
因此,上述的过程等价于:将函数内的变量声明"提前"至函数顶部,同时变量初始化留在原来的位置:
การคัดลอกรหัสมีดังนี้:
function f() {
var scope; //在函数的顶部声明了局部变量
console.log (ขอบเขต); //The variable exists, but its value is "undefined"
scope = "local"; //在这里将其初始化,并赋值
console.log (ขอบเขต); //Here it has the value we expect
-
在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来说,这是一个非常不错的编程习惯。由于在javascript中没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,而不是将声明放在靠近使用变量之处。这种做法使得他们的源代码非常清晰地反映了真实的变量作用域。
ii作为属性的变量
当声明一个javascript全局变量时面试及上是定义了全局对象的一个属性。见本文第三节。
当使用var声明一个变量时,创建的这个属性是不可配置的。见第六章第7节。也就是说这个变量无法通过delete运算符删除。可能你已经注意到了,如果你没有使用严格模式并给一个未声明的变量赋值的话。javascript会自动创建一个全局变量。以这种方式创建变量是全局对象正常的可配置属性。可以删除它们。
การคัดลอกรหัสมีดังนี้:
var truevar = 1; //声明一耳光不可删除的全局变量
fakevar = 2; //创建全局对象的一个可删除的属性
this.fakevar2 = 3; //同上
delete truevar // =>false 变量并没有删除
delete fakevar //=>true 变量被删除
delete this.fakevar2 //=>true 变量被删除
javascript全局变量是全局对象的属性,这是在ECMAScript规范中强制规定的。对于局部变量则没有此规定,但我们可以想象得到,局部变量当做跟函数调用相关的某个对象的属性。ECMAScript3规范称对象为“调用对象”(call object),ECMAScript5规定范称为“声明上下文对象”(declarative environment record)。javascript可以允许使用this关键字引用全局对象,却没有方法可以引用局部变量中存放的对象。这种存放局部变量的对象的特有性质,是一种对我们不可见的内部实现。然而,这些局部变量对象存在的观念是非常重要的。
iii作用域链
javascript是基于词法作用域的语言:通过阅读包含变量定义在内的舒航源码就能知道变量的作用域。
全局变量在程序中始终是都是有定义的。局部变量在声明它的函数体内以及其所嵌套的函数内始终是有定义的。