การทำความเข้าใจ JavaScript คำหลักนี้
หากคุณต้องการเป็นโปรแกรมเมอร์ ไม่ว่าคุณจะเลือกสาขาใดโดยเฉพาะ คุณจะต้องจัดการกับ JavaScript อย่างแน่นอน มันมีวิวัฒนาการจากจุดเริ่มต้นที่ต่ำต้อยไปสู่โรงไฟฟ้าที่แท้จริง ตอนนี้ครอบคลุมทั้งส่วนหน้า แบ็กเอนด์ อุปกรณ์เคลื่อนที่ เกม แอปเดสก์ท็อป และแม้แต่การเรียนรู้ของเครื่อง!
ก่อนที่คุณจะเป็นผู้เชี่ยวชาญ JavaScript และแตกแขนงออกไป คุณต้องเรียนรู้พื้นฐาน สิ่งนี้ คีย์เวิร์ดน่าจะเป็นอันดับหนึ่งในรายการการเรียนรู้ของคุณ
จริงๆ แล้ว นี่คืออะไร
พูดง่ายๆ ว่า นี่ เป็นตัวชี้ ซึ่งเป็นวิธีการอ้างอิงว่าอ็อบเจกต์ใดที่เรียกว่าฟังก์ชันหรือเมธอดในโค้ด JavaScript ในแง่ฆราวาส นี่ คือสิ่งที่อยู่ทางซ้ายของจุด
มีการใช้งานหลักสองประการ มาสำรวจกันด้วยตัวอย่าง
การสร้างวัตถุด้วย สิ่งนี้
function Book(title, author, genre) { this.title = title; this.author = author; this.genre = genre; } const book1 = new Book("Lord Of The Rings", "J.R.R. Tolkien", "Fantasy"); const book2 = new Book("Tools Of Titans", "Tim Ferriss", "Self-help"); console.log(book1); console.log(book2);
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้:
ในที่นี้ เรากำหนดฟังก์ชันคอนสตรัคเตอร์ซึ่งเราสร้างวัตถุหนังสือที่ใช้ชื่อ ผู้แต่ง และประเภทเป็นพารามิเตอร์
ฟังก์ชันคอนสตรัคเตอร์คือฟังก์ชัน "พิมพ์เขียว" ของอ็อบเจ็กต์ที่เราสามารถสร้างออบเจ็กต์ตามชื่อที่ระบุได้ (ในกรณีของเรา)
81% ของผู้เข้าร่วมกล่าวว่าพวกเขารู้สึกมั่นใจมากขึ้นเกี่ยวกับโอกาสในการทำงานด้านเทคโนโลยีหลังจากเข้าร่วม bootcamp จับคู่กับ Bootcamp วันนี้
ผู้สำเร็จการศึกษาจากหลักสูตร bootcamp โดยเฉลี่ยใช้เวลาน้อยกว่าหกเดือนในการเปลี่ยนอาชีพ ตั้งแต่เริ่มต้น bootcamp ไปจนถึงหางานแรก
เราสร้างวัตถุที่เรียกว่า myBook และส่งผ่านพารามิเตอร์ที่จำเป็น (เรียกว่าอาร์กิวเมนต์เมื่อเราเรียกหรือเรียกใช้ฟังก์ชัน ซึ่งต่างจากพารามิเตอร์เมื่อเรากำหนด)
ในตอนท้าย เราบันทึก myBook และได้วัตถุกลับมาพร้อมกับคุณสมบัติที่เกี่ยวข้อง ด้วยวิธีนี้ ออบเจ็กต์หนังสือใหม่แต่ละเล่มที่เราสร้างจะได้รับค่าที่ส่งผ่านซึ่งกำหนดให้กับมัน
การเข้าถึงคุณสมบัติด้วย สิ่งนี้ :
const girl = { name: "Sarah", age: 26, introduce() { console.log( "Hi! " + "I'm " + this.name + " and I'm " + this.age + " years old." ); }, };
ในที่นี้ เรากำหนดตัวแปรที่เรียกว่า girl ซึ่งเก็บอ็อบเจกต์ที่มีคุณสมบัติชื่อและอายุ และฟังก์ชันแนะนำ
ฟังก์ชันจะบันทึกประโยคเกริ่นนำโดยใช้คุณสมบัติของอ็อบเจ็กต์ เข้าถึงได้ด้วยนี่ .wanted_property.
นี่ และขอบเขตใน JavaScript
โดยค่าเริ่มต้น เมื่อใช้ในขอบเขตส่วนกลาง หมายถึง ไม่อยู่ภายในฟังก์ชันหรือวัตถุที่กำหนดไว้ นี้ จะอ้างถึงวัตถุสากล ในเบราว์เซอร์ window เป็นอ็อบเจ็กต์ส่วนกลาง
เมื่อคุณประกาศข้อมูลพื้นฐานบางอย่าง (สตริง ตัวเลข บูลีน…) อ็อบเจ็กต์ หรือฟังก์ชันใน JavaScript ข้อมูลทั้งหมดจะแนบไปกับอ็อบเจ็กต์โกลบอล (หน้าต่าง)
สิ่งที่คุณเขียน "ในที่โล่ง" คุณสามารถอ่านราวกับว่ามีหน้าต่าง ที่เขียนไว้ก่อนหน้านั้น มาดูข้อมูลโค้ดนี้กัน:
function returnThis() { return this; }
ขั้นแรก เรากำหนดฟังก์ชันที่เรียกว่า returnThis ในขอบเขตสากลที่คืนค่า this . จากนั้นเราเรียกมันว่าโดยการเขียน returnThis()
.
เนื่องจากเป็นการกำหนดขอบเขตทั่วโลก เราจึงมองว่าเป็น window.returnThis()
ซึ่งจะย้อนกลับมาที่เราทางซ้ายของจุด
ฟังก์ชันอ็อบเจ็กต์หรือเมธอด
หากตอนนี้เรากำหนดวัตถุใหม่ที่มีฟังก์ชันเดียวกันอยู่ภายใน (เรียกว่าวิธีการของวัตถุ) และเราเรียกมันอีกครั้ง เราจะได้รับวัตถุนั้น (แสดงโดยวงเล็บปีกกา) กลับมาหาเรา
const object = { returnThis() { return this; }, }; object.returnThis();
gotcha ของ สิ่งนี้ และนี่คือสามวิธีแก้ปัญหา
หากฟังก์ชันไม่ได้เชื่อมโยงโดยตรงกับอ็อบเจ็กต์ นี่ ภายในฟังก์ชันจะอ้างถึงวัตถุส่วนกลาง
const weirdBehaviorObject = { directlyTiedFunction() { return this; }, directlyTiedOuterFunction() { return function indirectNestedFunction() { return this; }; }, };
เรียกใช้สิ่งนี้ในเบราว์เซอร์และดูว่าเราได้รับอะไร:
เรากำหนดวัตถุที่มีหนึ่งฟังก์ชันส่งคืน สิ่งนี้ อีกครั้ง และอีกอันหนึ่งที่คืนค่าฟังก์ชันภายใน ซึ่งจะคืนค่า นี่ .
เมื่อเราต้องการเรียก indirectNestedFunction ให้เขียน ()
. ก่อน หนึ่งครั้งเพื่อเรียกฟังก์ชันภายนอกซึ่งส่งกลับค่าภายใน
แล้วเรียกชั้นในด้วย ()
. อีกอัน ซึ่งส่งคืนหน้าต่าง
นี่เป็นหนึ่งในพฤติกรรมลึกลับของ JavaScript และทำให้เกิดความประหลาดใจที่ไม่คาดคิดและไม่ต้องการ
โชคดีที่มีวิธีแก้ไขปัญหานี้ อย่างแรกคือการปิดซึ่งเป็นวิธีการก่อน ES6 วิธีที่สองคือการใช้ฟังก์ชันลูกศร และวิธีที่สามคือการใช้วิธีการผูกซึ่งสัมพันธ์กันอย่างใกล้ชิดกับการเรียกและใช้วิธี
#1 กำลังแก้ไข สิ่งนี้ มีฝาปิด
การปิดเป็นที่เก็บหน่วยความจำถาวร ซึ่งหมายความว่าตัวแปรจะไม่หายไปเมื่อฟังก์ชันดำเนินการเสร็จสิ้น มันถูกสร้างขึ้นโดยเอ็นจิ้น JavaScript เมื่อฟังก์ชันที่ซ้อนกันอ้างอิงถึงตัวแปรที่กำหนดไว้ในฟังก์ชันภายนอก ดังนั้นจึงสามารถเข้าถึงได้แม้ว่าฟังก์ชันภายนอกจะทำงานเสร็จก็ตาม นี่คือสิ่งที่ดูเหมือนกับสิ่งนี้ .ของเรา ตัวอย่าง:
const objectWithClosure = { closureFunction() { const self = this; return function enclosedFunction() { return self; }; }, };
เรากำหนดวัตถุด้วย closureFunction ซึ่งเรากำหนดตัวแปรที่เรียกว่า self เพื่อเก็บ สิ่งนี้ ของเรา ค่า. เนื่องจาก closureFunction เชื่อมโยงโดยตรงกับวัตถุที่มี ค่าของ this หมายถึงมัน ตอนนี้ในฟังก์ชันที่แนบมาของเรา นี่ มักจะอ้างถึงวัตถุหน้าต่าง เนื่องจากเราใช้การปิดเพื่อเข้าถึง สิ่งนี้ จากฟังก์ชันที่บรรจุ เราสามารถรักษาวัตถุที่เรียกได้ตามค่าของมัน
#2 กำลังแก้ไข สิ่งนี้ พร้อมฟังก์ชั่นลูกศร
วิธีที่สองคือการใช้หนึ่งในคุณสมบัติที่ดีที่สุดที่มาพร้อมกับ ES6 ซึ่งเป็นฟังก์ชันลูกศร
ฟังก์ชันลูกศรแสดงถึงไวยากรณ์ที่กระชับมากขึ้นสำหรับการเขียนฟังก์ชัน นอกจากนั้น พวกเขาจะมองหาระดับหนึ่งขึ้นไปในขอบเขตเพื่อค้นหาสิ่งนี้ ความหมายในฟังก์ชันที่มีอยู่
ดังนั้นหากเรากำหนดวัตถุของเราดังนี้:
const arrowFunctionObject = { outerFunc() { return () => this; }, };
เราจะเห็นว่าฟังก์ชันลูกศรส่งคืนวัตถุจริงไม่ใช่หน้าต่าง
นั่นเป็นเพราะมันมองขึ้นไปที่ฟังก์ชั่นภายนอกที่เรียกมันว่าโดยที่ นี่ อ้างถึง arrowFunctionObject ดังนั้น ฟังก์ชันลูกศรจึงมีฝาปิดในตัว
ฟังก์ชันลูกศรที่ซ้อนกัน
แน่นอนว่านี่คือ JavaScript ดังนั้นนี่คือ gotcha อีกอัน เป็นสิ่งที่คุณอาจไม่เคยพบมาก่อนนอกการสัมภาษณ์ทางเทคนิค แต่นั่นเป็นเหตุผลเพียงพอที่จะรู้
จะเกิดอะไรขึ้นหากเราซ้อนฟังก์ชันลูกศรภายในฟังก์ชันปกติ และอีกครั้งภายในฟังก์ชันอื่น ดูเหมือนว่านี้:
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }; }, };
อ็อบเจ็กต์ของเรามี outerFunction ซึ่งเมื่อถูกเรียก จะคืนค่า inner ว่า RegularFunction
จากนั้นเราเรียก RegularFunction และมันจะส่งคืนฟังก์ชันลูกศรที่อยู่ด้านในสุด
ตอนนี้เมื่อเรียกมันกลับวัตถุหน้าต่าง
ฟังก์ชันลูกศรจะค้นหา เท่านั้น 1 ระดับ อยู่ในขอบเขต เนื่องจาก RegularFunction ที่มีอยู่ไม่ได้ผูกโดยตรงกับวัตถุของเรา หน้าต่างจึงถูกส่งกลับแทน
อย่างไรก็ตาม หากเราซ้อนฟังก์ชันลูกศรไว้ภายในฟังก์ชันลูกศร ภายในฟังก์ชันปกติ เราก็จะได้ผลลัพธ์ที่คาดไว้ ซึ่งเป็นวัตถุที่มีอยู่จริง
const nestedArrowFunctionObject = { outerFunction() { return () => { return () => this; }; }, };
ในกรณีนี้ ฟังก์ชันลูกศรด้านในจะมองขึ้นไปที่ด้านนอก ด้านนอกเป็นฟังก์ชันลูกศรเพื่อให้มองขึ้นไปอีกระดับหนึ่ง outerFunction ปกติเชื่อมโยงโดยตรงกับการโทร
วัตถุ และเป็นผลให้วัตถุคือสิ่งที่ได้รับกลับมาเป็น นี้
#3 กำลังแก้ไข สิ่งนี้ ด้วยวิธีการผูก
สุดท้าย วิธีที่สามคือการใช้วิธีผูก วิธีการผูกจะใช้เพื่อประกาศอย่างชัดเจนว่า สิ่งนี้ ควรอ้างอิงถึง รับวัตถุที่ส่งผ่านเป็นอาร์กิวเมนต์ และผูกเข้ากับฟังก์ชัน this คำสำคัญ.
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }.bind(arrowNestedInRegularFunctionObject); }, };
ในตัวอย่างนี้ เราผูกมัดกับฟังก์ชันที่ปกติจะคืนค่าวัตถุหน้าต่างเป็น นี่ . เราส่งต่อวัตถุที่เราต้องการอ้างอิงเป็น สิ่งนี้ เป็นข้อโต้แย้ง และปัญหาของเราได้รับการแก้ไข
นี่ ไม่ยากเมื่อคุณเข้าใจ JavaScript
วุ้ย นั่นค่อนข้างเป็นการดำน้ำ ตอนนี้ คุณอาจจะถามว่าทำไมถึงยุ่งยากและสับสนกับสิ่งนี้ ?
เหตุผลก็คือ นี่ . ไม่เหมือนอย่างอื่นใน JavaScript มีการกำหนดขอบเขตแบบไดนามิก นั่นหมายความว่าเอ็นจิ้น JavaScript กำหนดว่า สิ่งนี้ แสดงถึงขณะรันไทม์เมื่อรันโค้ด โดยดูจากตำแหน่งและใครเป็นผู้เรียกใช้
ในทางตรงกันข้าม อย่างอื่นใน JavaScript มีการกำหนดขอบเขตศัพท์ หมายความว่าค่าของมันถูกกำหนดในตำแหน่งที่ตัวแปรถูกกำหนด เมื่อเขียนโค้ด
ขอบคุณ สิ่งนี้ เราสามารถสร้าง "พิมพ์เขียว" ของอ็อบเจ็กต์ได้หนึ่งครั้ง และสร้างออบเจ็กต์ที่มีค่าคุณสมบัติต่างกันแบบไดนามิกดังที่เราเห็นในตัวอย่างหนังสือของเรา
นอกจากนี้เรายังสามารถสร้างวิธีการที่เปิดเผยและจัดการคุณสมบัติของวัตถุด้วยสิ่งนี้ .wanted_property
เราสามารถแก้ไขนิสัยใจคอของ JavaScript และสั่งการพฤติกรรมอย่างมั่นใจ และสร้างผลลัพธ์ที่คาดหวัง
เมื่อคุณเข้าใจ สิ่งนี้ ใน JavaScript รวมถึงแนวคิดพื้นฐานอื่นๆ อีกสองสามข้อ คุณสามารถไปทดลอง ฝึกฝน และทำตามขั้นตอนอย่างมั่นใจมากขึ้นเพื่อไปสู่ความเชี่ยวชาญด้าน JavaScript
คุณได้รับ สิ่งนี้ !