การแนะนำ
1. ประเภทอ้างอิง
ประเภทการอ้างอิงเป็นประเภทภายในใน JavaScript ส่วนใหญ่จะใช้เป็นข้อมูลอ้างอิง แทนที่ตัวแปรหรือฟังก์ชัน แน่นอนว่าเมื่อต้องการค่าจริง ก็สามารถหาค่าจริงได้จากค่านั้น
2. โครงสร้างของประเภทอ้างอิง
ค่าของประเภทการอ้างอิงประกอบด้วยสองส่วน ส่วนแรกคือออบเจ็กต์ที่อ้างอิงตามค่าของประเภทอ้างอิง ในที่นี้เราเรียกว่าฐาน และอีกส่วนคือชื่อออบเจ็กต์ของออบเจ็กต์ในฐาน แสดงในรหัสเทียม:
คัดลอกรหัสรหัสดังต่อไปนี้:
var valueOfReferenceType = {
ฐาน: <วัตถุฐาน>,
ชื่อคุณสมบัติ: <ชื่อคุณสมบัติ>
-
3.สถานการณ์การใช้งาน
มีสองสถานการณ์การใช้งานสำหรับประเภทการอ้างอิง:
(1) เมื่อประมวลผลตัวระบุ
ตัวระบุคือชื่อตัวแปร ชื่อฟังก์ชัน ชื่อพารามิเตอร์ฟังก์ชัน และชื่อคุณสมบัติที่ไม่รู้จักในออบเจ็กต์ส่วนกลาง
(2) เมื่อประมวลผลการเข้าถึงทรัพย์สิน
คัดลอกรหัสรหัสดังต่อไปนี้:
วาร์ฟู = 10;
แถบฟังก์ชัน( ){}
ในผลลัพธ์ขั้นกลางของการดำเนินการ ประเภทการอ้างอิงจะสอดคล้องกับ
คัดลอกรหัสรหัสดังต่อไปนี้:
var fooReference = {
ฐาน: ทั่วโลก,
ชื่อคุณสมบัติ: 'foo'
-
var barReference = {
ฐาน: ทั่วโลก,
ชื่อคุณสมบัติ: 'บาร์'
-
ยังคงจำเป็นต้องอธิบายฐานที่นี่ ใน JavaScript วัตถุหรือฟังก์ชันทั้งหมดมีวัตถุของตัวเอง ใครก็ตามที่ได้อ่านบทความก่อนหน้าของฉันรู้ว่ามีวัตถุตัวแปรในแต่ละบริบทการดำเนินการเพื่อจัดการตัวแปรหรือฟังก์ชันในบริบทการดำเนินการนี้ .
ดังนั้น เมื่อต้องจัดการกับตัวระบุ:
ในบริบทสากล มันดำเนินไปโดยไม่ได้บอกว่า base === globalVO === global
ในบริบทการดำเนินการของฟังก์ชัน ฐาน === VO/AO
แต่คุณสมบัติของออบเจ็กต์การประมวลผลคือ:
นี่ง่ายกว่านั้นอีก base === owerObject
4. รับค่าที่แท้จริงของประเภทอ้างอิง
ดังที่เราได้กล่าวไว้ในตอนต้น ประเภทการอ้างอิงเป็นเพียงการอ้างอิง แต่ไม่ได้เก็บมูลค่าที่แท้จริง เมื่อต้องการมูลค่าที่แท้จริง สามารถรับได้ผ่านชุดของอัลกอริธึมภายใน เราสามารถอธิบายอัลกอริทึมนี้ด้วยรหัสเทียมแบบง่าย:
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่น GetValue (ค่า) {
ถ้า (ประเภท (ค่า) != การอ้างอิง) {
ค่าส่งคืน;
-
var base = GetBase (ค่า);
ถ้า (ฐาน === โมฆะ) {
โยน ReferenceError ใหม่;
-
กลับฐาน[[รับ]](GetPropertyName(ค่า));
-
เมธอดภายใน [[รับ]] ส่งคืนค่าที่แท้จริงของคุณสมบัติของออบเจ็กต์ รวมถึงการวิเคราะห์คุณสมบัติที่สืบทอดมาในห่วงโซ่ต้นแบบ ดังนั้นด้วย GetValue เราจึงสามารถรับมูลค่าที่แท้จริงของประเภทการอ้างอิงได้อย่างง่ายดาย ตัวอย่างเช่น:
คัดลอกรหัสรหัสดังต่อไปนี้:
GetValue(fooReference); // 10
GetValue(barReference); // ฟังก์ชันวัตถุ "บาร์"
แล้วเราต้องได้มูลค่าที่แท้จริงของประเภทอ้างอิงเมื่อใด?
โดยทั่วไป เมื่อจำเป็นต้องกำหนดชนิดการอ้างอิง เข้าร่วมในการดำเนินการ หรือถูกเรียก จะต้องได้รับค่าจริงผ่านเมธอด GetValue (หมายเหตุ: วัตถุที่ได้รับผ่าน GetValue ไม่ใช่ประเภทอ้างอิงอีกต่อไป)
ความสัมพันธ์ระหว่างประเภทการอ้างอิงกับสิ่งนี้
ประเภทการอ้างอิงส่วนใหญ่จะเกี่ยวข้องอย่างใกล้ชิดกับจุดนี้ในบริบทของฟังก์ชัน และดูค่อนข้างแตกต่างกันในแต่ละช่วงเวลา ดังนั้นเราจึงแนะนำประเภทการอ้างอิงเพื่ออธิบายประสิทธิภาพของสิ่งนี้ในบริบทของฟังก์ชันโดยเฉพาะ
กฎทั่วไปสำหรับการกำหนดค่าของสิ่งนี้ในบริบทของฟังก์ชันมีดังนี้:
ในบริบทของฟังก์ชัน ข้อมูลนี้จะถูกจัดเตรียมโดยผู้เรียก และถูกกำหนดโดยวิธีการเรียกใช้ฟังก์ชัน หากด้านซ้ายของวงเล็บเรียก () เป็นค่าประเภทการอ้างอิง ค่านี้จะถูกตั้งค่าเป็นอ็อบเจ็กต์ฐานของค่าประเภทอ้างอิง ในกรณีอื่นๆ (คุณสมบัติอื่นใดที่แตกต่างจากประเภทอ้างอิง) ค่านี้จะเป็นโมฆะ . อย่างไรก็ตาม ไม่มีสถานการณ์จริงที่ค่าของสิ่งนี้เป็นโมฆะ เนื่องจากเมื่อค่าของสิ่งนี้เป็นโมฆะ ค่าของมันจะถูกแปลงเป็นอ็อบเจ็กต์โกลบอลโดยปริยาย หมายเหตุ: ใน ECMAScript ฉบับที่ 5 การแปลงเป็นตัวแปรร่วมจะไม่ถูกบังคับอีกต่อไป แต่ถูกกำหนดเป็นไม่ได้กำหนด
ด้านล่างเราจะพูดถึงสามสถานการณ์ตามความแตกต่างทางด้านซ้ายของวงเล็บเรียก:
(1) ด้านซ้ายของวงเล็บเรียกคือค่าของประเภทอ้างอิง
สิ่งนี้ไม่ต้องการการวิเคราะห์มากเกินไป วัตถุฐานคือค่าของสิ่งนี้ หากมีการประกาศภายใต้ตัวแปรโกลบอล มันจะชี้ไปที่อ็อบเจ็กต์โกลบอล
คัดลอกรหัสรหัสดังต่อไปนี้:
var myObject = {
ฟู : function(){
console.log(นี่);
-
-
myObject.foo(); //ไม่ต้องสงสัยเลยว่าฐานของ foo คือ myObject ดังนั้นในเมธอด foo จึงชี้ไปที่ myObject
(2) ด้านซ้ายของวงเล็บเรียกเป็นค่าประเภทอ้างอิง แต่ค่านี้เป็นค่าว่าง
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่น myFunction() {
var foo = ฟังก์ชั่น(){
console.log(นี่);
-
foo(); //AO.foo() => null.foo()
-
myFunction(); //เอาต์พุต: หน้าต่าง {ด้านบน: หน้าต่าง, หน้าต่าง: หน้าต่าง...}
เมื่อเรียกใช้ฟังก์ชันภายใน ฐานของฟังก์ชันภายในควรเป็นวัตถุที่ใช้งานอยู่ (OA) ในบริบทการดำเนินการปัจจุบัน อย่างไรก็ตาม เมื่อใช้งาน OA เป็นฐาน จะถือว่า JavaScript ไม่ถือเป็นโมฆะอย่างแน่นอน อนุญาตให้สิ่งนี้เป็นโมฆะ ฐานทั้งหมดถูกตั้งค่าเป็นวัตถุโกลบอล (นี่คือที่มาของข้อผิดพลาดการออกแบบในรูปแบบการเรียกฟังก์ชันก่อนหน้านี้) ดังนั้นในกรณีนี้ สิ่งนี้ชี้ไปที่วัตถุโกลบอล
(3) เรียกค่าทางด้านซ้ายของวงเล็บที่ไม่ใช่ประเภทอ้างอิง
คัดลอกรหัสรหัสดังต่อไปนี้:
// ตัวอย่างง่ายๆ
(การทำงาน () {
console.log(นี่); // null => global
-
//ตัวอย่างที่ซับซ้อนมากขึ้น
วาร์ฟู = {
บาร์: ฟังก์ชั่น () {
console.log(นี่);
-
-
foo.bar(); // อ้างอิง, ตกลง => foo
(foo.bar)(); // อ้างอิง, ตกลง => foo
(foo.bar = foo.bar)(); // global
(เท็จ || foo.bar)(); // global
(foo.bar, foo.bar)(); // global
เมื่อด้านซ้ายของวงเล็บเรียกไม่ใช่ประเภทอ้างอิง แต่เป็นประเภทอื่น สิ่งนี้จะถูกตั้งค่าเป็น null โดยอัตโนมัติ และผลลัพธ์จะเป็นอ็อบเจ็กต์โกลบอล
ในตัวอย่างแรก ฟังก์ชันทันทีมีนิพจน์ทางด้านซ้ายของวงเล็บการเรียกฟังก์ชัน ไม่ใช่การอ้างอิง
ตัวอย่างที่สองนั้นซับซ้อนกว่ามาก มาวิเคราะห์ทีละรายการ:
foo.bar() ไม่ต้องสงสัยเลยเกี่ยวกับเรื่องนี้ ฐานคือ foo และนี่ชี้ไปที่ foo
(foo.bar)() วงเล็บถูกใช้ที่นี่ ซึ่งทำหน้าที่เป็นสัญลักษณ์การจัดกลุ่ม กล่าวคือ ไม่ได้บังคับให้ประเภทการอ้างอิงดำเนินการเมธอด GetValue และผลลัพธ์ของการดำเนินการจะเหมือนกับข้างต้นทุกประการ
ในวงเล็บสามตัวถัดมาคือการดำเนินการมอบหมาย หรือการดำเนินการและการดำเนินการด้วยเครื่องหมายจุลภาค โดยทั้งหมดจะบังคับให้ประเภทการอ้างอิงดำเนินการเมธอด GetValue ดังนั้นจึงส่งคืนอ็อบเจ็กต์ฟังก์ชัน ด้วยวิธีนี้ ด้านซ้ายของวงเล็บการเรียกฟังก์ชันจะไม่ใช่ประเภทอ้างอิงอีกต่อไป ดังนั้นสิ่งนี้จะชี้ไปที่อ็อบเจ็กต์ร่วม
สรุป
เกี่ยวกับประเภทการอ้างอิง จริงๆ แล้วฉันไม่ค่อยรู้เรื่องนี้มากนัก ฉันเพิ่งเห็นบทเกี่ยวกับเรื่องนี้ในบล็อกของลุงทอม เพื่อที่จะอธิบายหลักการของสิ่งนี้ในโหมดการเรียกใช้ฟังก์ชัน ฉันได้ทำการวิเคราะห์พิเศษ น่าทึ่งมาก ฉันคิดมาโดยตลอดว่าควรมีความสัมพันธ์บางอย่างระหว่างประเภทการอ้างอิงและการอ้างอิงโดยค่า โดยไม่คาดคิด จะใช้ในรูปแบบ Bolg เพื่อช่วยในการทำความเข้าใจเท่านั้น ส่วนว่าเมื่อก่อนเคยมีความสัมพันธ์กันหรือไม่ และหากมีความสัมพันธ์กัน ความสัมพันธ์จะเป็นแบบไหน ก็ยังต้องศึกษาค้นคว้าต่อไป
ฉันหวังว่าคุณจะสามารถสื่อสารได้มากขึ้น ฉันอยากจะขอบคุณลุงทอมสำหรับสิ่งนี้