นิพจน์ของฟังก์ชัน

นิพจน์ของฟังก์ชันคือฟังก์ชันที่สร้างขึ้นในตำแหน่งที่ต้องการให้แสดงนิพจน์ ที่มักจะพบนิพจน์ฟังก์ชันคือ ค่าที่กําหนดให้กับตัวแปร แม้ว่าการประกาศฟังก์ชันจะกำหนดให้ต้องมีชื่อเสมอ แต่คุณสามารถใช้นิพจน์ฟังก์ชันเพื่อสร้างฟังก์ชันที่ไม่ระบุตัวตนได้โดยละเว้นตัวระบุและตามด้วยคีย์เวิร์ด 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 เพื่อป้องกันมลพิษที่เกิดขึ้นโดยไม่ตั้งใจของขอบเขตรวมทั้งหมด

ทดสอบความเข้าใจ

คุณเรียกนิพจน์ฟังก์ชันที่มีชื่อตามชื่อที่อยู่นอกฟังก์ชันได้ไหม

ไม่ได้
ใช่