นิพจน์ของฟังก์ชันคือฟังก์ชันที่สร้างขึ้นในตำแหน่งที่ต้องการให้แสดงนิพจน์ ที่มักจะพบนิพจน์ฟังก์ชันคือ
ค่าที่กําหนดให้กับตัวแปร แม้ว่าการประกาศฟังก์ชันจะกำหนดให้ต้องมีชื่อเสมอ แต่คุณสามารถใช้นิพจน์ฟังก์ชันเพื่อสร้างฟังก์ชันที่ไม่ระบุตัวตนได้โดยละเว้นตัวระบุและตามด้วยคีย์เวิร์ด function
ที่มีวงเล็บคู่ซึ่งมีพารามิเตอร์ที่ไม่บังคับ ดังนี้
const myVariable = function() { };
จากนั้นคุณจะเรียกใช้นิพจน์ของฟังก์ชันเหล่านั้นได้โดยใช้ตัวระบุของตัวแปร ดังนี้
const myVariable = function() {
console.log( "This is my function." );
};
myVariable();
> "This is my function."
คุณยังสามารถใช้นิพจน์ฟังก์ชันเพื่อสร้างฟังก์ชันที่มีชื่อโดยใช้ไวยากรณ์ที่คล้ายกับการประกาศฟังก์ชัน ดังนี้
const myVariable = function myFunction() {
console.log( "This is my function." );
};
myVariable();
> "This is my function."
อย่างไรก็ตาม นิพจน์ฟังก์ชันที่มีชื่อจะเข้าถึงได้โดยใช้ชื่อฟังก์ชันภายในตัวฟังก์ชันเท่านั้น ซึ่งต่างจากการประกาศฟังก์ชัน ดังนี้
const myVariable = function myFunction() {
console.log( `I'm a ${ typeof myFunction }.`);
};
typeof myFunction;
> "undefined"
typeof myVariable;
> "function"
myVariable();
> "I'm a function."
ชื่อที่เชื่อมโยงกับนิพจน์ฟังก์ชันจะมีประโยชน์ต่อการแก้ไขข้อบกพร่องเป็นหลัก นิพจน์ฟังก์ชันที่มีชื่ออาจเรียกตัวเองแบบเรียกตัวเองได้เช่นกัน แม้ว่ากรณีนี้จะไม่ใช่กรณีการใช้งานที่พบได้บ่อยในการพัฒนาระบบสมัยใหม่ก็ตาม
const myVariable = function myFunction() {
console.log( "One second elapsed." );
setTimeout( myFunction, 1000 );
};
setTimeout( myVariable, 1000 );
> "One second elapsed."
> "One second elapsed."
> "One second elapsed."
…
นิพจน์ฟังก์ชันลูกศร
ใน ES6 มีการนำเสนอนิพจน์ฟังก์ชันลูกศร (มักเรียกว่า "ฟังก์ชันลูกศร" หรือที่แทบจะไม่เรียกว่า "ฟังก์ชันแลมบ์"") เพื่อให้ไวยากรณ์ที่กระชับสำหรับการสร้างนิพจน์ฟังก์ชันที่ไม่ระบุชื่อซึ่งมีลักษณะการทำงานที่ไม่ซ้ำกันบางอย่าง
คุณสามารถสร้างฟังก์ชันลูกศรได้ทุกที่ที่ต้องการนิพจน์ เช่น เป็นค่าที่กำหนดให้กับตัวแปร ในรูปแบบที่ใช้กันมากที่สุด ฟังก์ชันลูกศรประกอบด้วยวงเล็บที่ตรงกันซึ่งมีพารามิเตอร์เท่ากับ 0 ขึ้นไป ลูกศรประกอบด้วยเครื่องหมายเท่ากับเดี่ยวและอักขระมากกว่า (=>
) และวงเล็บปีกกาที่ตรงกันคู่หนึ่งซึ่งมีส่วนเนื้อหาของฟังก์ชัน ดังนี้
const myFunction = () => {};
ภายใต้เงื่อนไขบางอย่าง คุณจะทำให้ไวยากรณ์กะทัดรัดยิ่งขึ้นได้ หากใช้เพียงพารามิเตอร์เดียว ให้ปล่อยวงเล็บเริ่มต้นว่างไว้
const myFunction = myParameter => {};
เมื่อต้องการให้เนื้อหาของฟังก์ชันแสดงผลค่าของนิพจน์เดียว โดยไม่ต้องใส่ฟังก์ชันวงเล็บปีกกาหรือคีย์เวิร์ด return
ไว้ ให้ทําดังนี้
const myFunction = () => 2 + 2
myFunction()
> 4
ฟังก์ชันลูกศรมีเอกลักษณ์ตรงที่ไม่มีบริบทเป็นของตัวเองสำหรับค่า arguments
หรือ this
แต่จะรับค่าทั้ง 2 ค่าจากสภาพแวดล้อมที่ล้อมรอบด้วยพจนานุกรมของฟังก์ชันลูกศร ซึ่งเป็นฟังก์ชันที่ล้อมรอบที่สุดซึ่งให้บริบทเหล่านั้น
function myParentFunction() {
this.myProperty = true;
let myFunction = () => {
console.log( this );
}
myFunction();
};
let myInstance = new myParentFunction();
> Object { myProperty: true }
เรียกฟังก์ชันลูกศร
ฟังก์ชันลูกศรจะไม่เชื่อมโยงอาร์กิวเมนต์ในลักษณะเดียวกับฟังก์ชันประเภทอื่นๆ
ออบเจ็กต์ arguments
ในส่วนเนื้อหาของฟังก์ชันลูกศรจะรับค่ามาจากสภาพแวดล้อมที่ล้อมรอบด้วยพจนานุกรมที่ใกล้ที่สุดของฟังก์ชันลูกศรดังกล่าว
function myFunction() {
let myArrowFunction = () => {
console.log( arguments[ 0 ] );
}
myArrowFunction( true );
};
myFunction( false );
> false
ในตัวอย่างนี้ ฟังก์ชันด้านนอกที่ถูกเรียกด้วยอาร์กิวเมนต์ false
จะเรียกฟังก์ชันลูกศรภายในด้วยอาร์กิวเมนต์ true
เนื่องจากออบเจ็กต์ arguments
ภายในฟังก์ชันลูกศรแก้ไขการเชื่อมโยงในฟังก์ชันด้านนอก ฟังก์ชันภายในจะบันทึก false
ของฟังก์ชันภายนอก
หากไม่มีออบเจ็กต์ arguments
ที่จะรับค่าจากบริบทระดับบนสุด จะไม่มีการกำหนดออบเจ็กต์ arguments
ของฟังก์ชันลูกศร และการพยายามเข้าถึงจะทําให้เกิดข้อผิดพลาดดังนี้
let myArrowFunction = () => {
console.log(arguments);
};
myArrowFunction( true );
> Uncaught ReferenceError: arguments is not defined
นิพจน์ฟังก์ชันที่เรียกใช้ทันที (IIFE)
นิพจน์ของฟังก์ชันที่เรียกใช้ทันที (IIFE) หรือบางครั้งเรียกว่า "ฟังก์ชันที่ไม่ระบุตัวตนที่ดำเนินการด้วยตนเอง" เป็นนิพจน์ฟังก์ชันที่จะถูกเรียกใช้ทันทีที่มีการระบุ IIFE ใช้นิพจน์ฟังก์ชันที่สร้างโดยการรวมฟังก์ชันในโอเปอเรเตอร์การจัดกลุ่ม วงเล็บคู่ที่ 2 ที่ตรงกันจะเรียกใช้ฟังก์ชัน ไม่ว่าจะตามคำจำกัดความของฟังก์ชันเองหรือตามตัวดำเนินการการจัดกลุ่มทันที หากใช้ฟังก์ชันมาตรฐาน ทั้ง 2 วิธีจะไม่มีความแตกต่างกันในทางปฏิบัติ
(function() {
console.log( "IIFE.")
}
)();
> "IIFE."
(function() {
console.log( "IIFE.")
}
());
> "IIFE."
ตัวอย่างแรกเรียกนิพจน์ฟังก์ชันที่มีการจัดกลุ่ม ตัวอย่างที่ 2 จะเรียกการประกาศฟังก์ชันภายในโอเปอเรเตอร์การจัดกลุ่ม และจากนั้นระบบจะประเมินผลลัพธ์เป็นนิพจน์ที่จัดกลุ่มไว้ ผลลัพธ์จะเหมือนกันใน ทั้ง 2 กรณี
อย่างไรก็ตาม มีความแตกต่างเมื่อ IIFE ของคุณเป็นฟังก์ชันลูกศร ในกรณีนี้ วงเล็บที่ใช้เพื่อเรียกใช้ฟังก์ชันต้องอยู่นอกโอเปอเรเตอร์การจัดกลุ่ม เนื่องจากฟังก์ชันลูกศรในตัวเองนั้นไม่ใช่นิพจน์ แต่จะต้องสร้างในบริบทที่ควรมีนิพจน์ การพยายามเรียกฟังก์ชันลูกศรจากภายในขอบเขตของโอเปอเรเตอร์การจัดกลุ่มจะหมายถึงการเรียกฟังก์ชันลูกศรที่ยังไม่ได้สร้างขึ้นในบริบทของนิพจน์ ดังนี้
( () => {
console.log( "IIFE." );
}() );
> Uncaught SyntaxError: missing ) in parenthetical
เนื่องจากโอเปอเรเตอร์การจัดกลุ่มคาดหวังนิพจน์ จึงมีการกำหนดฟังก์ชันลูกศรภายในเครื่องหมายเหล่านี้ โดยให้วงเล็บที่ตามมาเรียกนิพจน์ที่จัดกลุ่มไว้ ดังนี้
( () => {
console.log( "IIFE." );
} )();
> "IIFE."
แอปพลิเคชันเดิมที่ใช้บ่อย IIFE ในการจัดการขอบเขต โดยเฉพาะเพื่อหลีกเลี่ยงมลพิษในขอบเขตรวมด้วยตัวแปรที่กำหนดขอบเขตระดับฟังก์ชันและการประกาศฟังก์ชัน ก่อนที่จะเปิดตัวการกำหนดขอบเขตการบล็อกใน ES6 เป็นเรื่องปกติที่จะต้องรวมสคริปต์ทั้งหมดใน IIFE เพื่อป้องกันมลพิษที่เกิดขึ้นโดยไม่ตั้งใจของขอบเขตรวมทั้งหมด
ทดสอบความเข้าใจ
คุณเรียกนิพจน์ฟังก์ชันที่มีชื่อตามชื่อที่อยู่นอกฟังก์ชันได้ไหม