การโฆษณา

บ้าน - แอนติไวรัส
ฟังก์ชั่นลูกศรใน ES6 อีเอส6

อัพเดทล่าสุด: 09.04.2018

ฟังก์ชันลูกศรเป็นเวอร์ชันย่อของฟังก์ชันปกติ ฟังก์ชันลูกศรถูกสร้างขึ้นโดยใช้เครื่องหมายลูกศร (=>) นำหน้าด้วยพารามิเตอร์ฟังก์ชันในวงเล็บ และตามด้วยตัวฟังก์ชันเอง ตัวอย่างเช่น:

ให้ผลรวม = (x, y) => x + y; ให้ a = ผลรวม (4, 5); // 9 ให้ b = ผลรวม (10, 5); // 15

ในกรณีนี้ ฟังก์ชัน (x, y) => x + y บวกตัวเลขสองตัวและกำหนดให้กับผลรวมของตัวแปร ฟังก์ชั่นรับพารามิเตอร์สองตัว - x และ y ร่างกายของเธอคือผลรวมของค่าของพารามิเตอร์เหล่านี้ และเนื่องจากหลังจากลูกศรแล้ว จริงๆ แล้วมีค่าเฉพาะที่แสดงถึงผลรวมของตัวเลข ฟังก์ชันจึงส่งกลับค่านี้ และเราสามารถเรียกผ่านตัวแปรผลรวมได้ ฟังก์ชั่นนี้และได้ผลลัพธ์เป็นตัวแปร a และ b

ถ้าลูกศรตามด้วยการดำเนินการหรือนิพจน์ที่ส่งกลับค่า ค่านั้นจะถูกส่งกลับจากฟังก์ชันลูกศร แต่นิพจน์ที่ไม่ส่งคืนสิ่งใดและเพียงดำเนินการบางอย่างก็สามารถใช้เป็นเนื้อความของฟังก์ชันได้:

ให้ sum = (x, y) => console.log(x + y); ผลรวม(4, 5); // 9 ผลรวม (10, 5); // 15

ในกรณีนี้ ฟังก์ชัน console.log() จะไม่ส่งคืนสิ่งใด ดังนั้นฟังก์ชัน sum จึงไม่ส่งคืนผลลัพธ์ใดๆ เช่นกัน

หากฟังก์ชันใช้พารามิเตอร์ตัวเดียว วงเล็บที่อยู่รอบๆ ก็สามารถละเว้นได้:

วาร์สแควร์ = n => n * n; console.log(สี่เหลี่ยม(5)); // 25 console.log(สี่เหลี่ยม(6)); // 36 console.log(สี่เหลี่ยม(-7)); // 49

หากเนื้อความของฟังก์ชันแสดงถึงชุดของนิพจน์ นิพจน์เหล่านั้นจะอยู่ในเครื่องหมายปีกกา:

Var square = n => ( ให้ผลลัพธ์ = n * n; return result; ) console.log(square(5)); // 25

ในกรณีนี้ คำสั่ง return มาตรฐานใช้เพื่อส่งคืนผลลัพธ์จากฟังก์ชัน

ควรให้ความสนใจเป็นพิเศษกับกรณีที่ฟังก์ชันลูกศรส่งคืนวัตถุ:

ให้ผู้ใช้ = (ชื่อผู้ใช้, userAge) => ((ชื่อ: ชื่อผู้ใช้, อายุ: userAge)); ให้ tom = user("Tom", 34); ให้ Bob = user("Bob", 25); console.log(tom.name, tom.age); // "ทอม", 34 console.log(bob.name, bob.age); // "บ๊อบ", 25

วัตถุยังถูกกำหนดโดยใช้เครื่องหมายปีกกา แต่จะอยู่ในวงเล็บ

หากฟังก์ชันลูกศรไม่ใช้พารามิเตอร์ใด ๆ วงเล็บว่างจะถูกวาง:

Var hello = ()=> console.log("สวัสดีชาวโลก"); สวัสดี(); // สวัสดีชาวโลก สวัสดี(); //สวัสดีชาวโลก

พวกเขากลายเป็นแฟชั่นมากเราเห็นพวกเขาในบทความใหม่ทั้งหมด และถ้าคุณไม่คุ้นเคยกับมัน คุณจะมีปัญหาในการทำความเข้าใจโค้ดสมัยใหม่ (ES6) ที่มีฟังก์ชันลูกศร

บทความนี้ไม่ได้มีวัตถุประสงค์เพื่อบอกคุณว่าจะใช้เมื่อใดหรืออย่างไร ฉันจะพยายามอธิบายไวยากรณ์ใหม่สำหรับผู้ที่เห็นเป็นครั้งแรก ไม่ว่าคุณจะใช้มันหรือไม่นั้นไม่สำคัญ แต่ไม่ช้าก็เร็วคุณก็ยังต้องเผชิญกับมันที่ไหนสักแห่ง ดังนั้นจึงเป็นการดีกว่าที่จะเข้าใจกลไกของไวยากรณ์ใหม่นี้

นี่เป็นตัวอย่างเล็กๆ น้อยๆ:

Const addOne = function(n) ( ส่งคืน n + 1; )

โค้ดด้านบนสามารถเขียนได้ดังนี้:

Const addOne = (n) => ( ส่งคืน n + 1; )

หรือในกรณีนี้ให้สั้นกว่านั้น:

Const addOne = (n) => n + 1;

ตัวอย่างที่สองใช้เครื่องหมายปีกกา ( ... ) แต่เนื่องจากโค้ดเป็นเพียงบรรทัดเดียว คุณจึงสามารถละเว้นเครื่องหมายปีกกาและส่งคืนได้ ดังที่เห็นในตัวอย่างที่สาม

หนึ่งพารามิเตอร์

เมื่อฟังก์ชันลูกศรมีพารามิเตอร์ตัวเดียว คุณสามารถละเว้นวงเล็บได้:

// เคยเป็น: someCallBack((ผลลัพธ์) => ( ... )) // ตอนนี้: someCallBack(ผลลัพธ์ => ( ... ))

แต่หากไม่มีพารามิเตอร์ คุณต้องใช้วงเล็บเปิดและปิด:

SomeCallBack(() => ( ... ))

ฟังก์ชั่นการโทรกลับ

ลูกศรฟังก์ชันมีประโยชน์อย่างยิ่งสำหรับการโทรกลับ ผู้ที่คุ้นเคยกับ JavaScript จะคุ้นเคยกับขอบเขตคำศัพท์ซึ่งค่อนข้างเรียบร้อย แต่สามารถใช้เทคนิคเช่นนี้ได้ ( นี้):

Var_this = นี่; someCallBack(ฟังก์ชั่น() ( _this.accessOuterScope(); ))

"_this" นี้มีหลายรูปแบบ (เช่น "self" หรือ "that") แต่แนวคิดก็เหมือนกัน ในฟังก์ชันการโทรกลับ เราจำเป็นต้องเข้าถึงเวอร์ชันขอบเขตภายนอก แต่แนวคิดก็เหมือนกัน ในฟังก์ชันการโทรกลับ เราจำเป็นต้องเข้าถึงเวอร์ชันของขอบเขตภายนอกของ this ซึ่งแตกต่างจากเมื่อก่อนเนื่องจากเรากำลังพูดถึงฟังก์ชันการโทรกลับ

โดยการใช้ ฟังก์ชั่นลูกศรเราได้รับ "ขอบเขตบล็อก" และ "สิ่งนี้" ซึ่งเหมือนกัน "สิ่งนี้" ในทั้งสองกรณี ซึ่งหมายความว่าโค้ดด้านบนสามารถเขียนใหม่ได้โดยไม่ต้อง _this = this:

SomeCallBack(() => ( this.accessOuterScope(); ))

"กระดาษห่อ"

ลองนึกภาพสถานการณ์เหมือนใน React ว่าเหตุการณ์ไหน บนคลิกควรเรียก doSomething() , () แต่ควรส่งผ่านข้อโต้แย้งไปยัง doSomething() (เช่น ID) ตัวอย่างนี้ใช้ไม่ได้จริง:

ผู้ใช้บางคน) ))

โค้ดจะทำงาน แต่ในทางเทคนิคแล้วจะเรียก doSomething() ทันทีเมื่อโหลดหน้าเว็บ เพื่อแก้ไขปัญหานี้ นักพัฒนาบางคนอ้างถึงฟังก์ชัน wrapper:

ผู้ใช้ Const = React.createClass(function() ( render: function() ( return ผู้ใช้บางคน), onClick: function() ( doSomething(this.props.userId); ) ))

การไม่มีวงเล็บใน this.onClick หมายความว่าเป็นเพียงการอ้างอิงฟังก์ชัน ไม่ใช่การเรียกใช้ฟังก์ชัน

ตอนนี้ฟังก์ชัน onClick() กลายเป็นสิ่งห่อหุ้มสำหรับ doSomething() ด้วยฟังก์ชันลูกศร คุณสามารถสร้าง "ตัวห่อ" ประเภทนี้ได้:

ผู้ใช้ Const = React.createClass(function() ( render: function() ( return doSomething(this.props.userId))>ผู้ใช้บางคน ) ))

อีกทางเลือกหนึ่ง เรายังสามารถใช้ .bind() ซึ่งไม่ต้องใช้ wrappers ใด ๆ (ฟังก์ชันลูกศรหรืออะไรก็ตาม):

ผู้ใช้ Const = React.createClass(function() ( render: function() ( return some user ) ))

รองรับเบราว์เซอร์สำหรับฟังก์ชั่นลูกศร

หากคุณต้องการการสนับสนุนสำหรับเบราว์เซอร์อื่นที่ไม่ใช่เวอร์ชันล่าสุด โครเมียมและ ไฟร์ฟอกซ์, ใช้ บาเบล ทรานสปิเลอร์เพื่อแปลงโค้ด ES6 ที่คุณเขียนเป็น ES5

เกี่ยวกับคำหลัก JavaScript “นี้”: คุณลักษณะการใช้งานพร้อมคำอธิบาย

ความลึกลับของสิ่งนี้

เป็นเวลานานแล้วที่คำหลักนี้ยังคงเป็นปริศนาสำหรับฉัน นี้ เครื่องมืออันทรงพลังแต่มันไม่ง่ายเลยที่จะเข้าใจ

จากมุมมองของ Java, PHP หรือภาษาปกติอื่นๆ สิ่งนี้ถือเป็นอินสแตนซ์ของอ็อบเจ็กต์ปัจจุบันในเมธอดคลาส ไม่มีอะไรมากหรือน้อยไปกว่านั้น ส่วนใหญ่มักจะไม่สามารถใช้นอกวิธีการได้ และวิธีนี้ก็ไม่ได้ถูกเข้าใจผิด

ใน JavaScript นี่คือบริบทการดำเนินการปัจจุบันของฟังก์ชัน เนื่องจากสามารถเรียกใช้ฟังก์ชันได้สี่วิธี:

  • การเรียกใช้ฟังก์ชัน: alert("Hello World!") ,
  • การเรียกเมธอด: console.log("Hello World!"),
  • การเรียกคอนสตรัคเตอร์: new RegExp("\\d") ,
  • การโทรทางอ้อม: alert.call(unknown, "Hello World!") ,

และแต่ละอันก็กำหนดบริบทของตัวเอง พฤติกรรมนี้ไม่สอดคล้องกับสิ่งที่นักพัฒนามือใหม่คาดหวังเล็กน้อย นอกจากนี้ โหมดเข้มงวดยังส่งผลต่อบริบทการดำเนินการอีกด้วย

กุญแจสำคัญในการทำความเข้าใจคำสำคัญนี้คือการทำความเข้าใจวิธีการเรียกฟังก์ชันและผลกระทบต่อบริบทอย่างไร บทความนี้ครอบคลุมถึงการเรียกใช้ฟังก์ชัน ผลกระทบของการโทรในเรื่องนี้ และข้อผิดพลาดทั่วไปเมื่อระบุบริบท

ก่อนที่เราจะเริ่มต้น เรามาทำความรู้จักกับคำศัพท์สองสามคำกันก่อน:

  • การโทรคือการดำเนินการของโค้ดเนื้อหาของฟังก์ชัน ตัวอย่างเช่น การเรียกฟังก์ชัน parseInt จะเป็น parseInt("15")
  • บริบทการโทรคือค่านี้ในเนื้อหาของฟังก์ชัน
  • ขอบเขตของฟังก์ชันคือชุดของตัวแปร ออบเจ็กต์ และฟังก์ชันที่สามารถเข้าถึงได้จากภายในเนื้อหาของฟังก์ชัน

  • 2.1.
    2.2.
    2.3.

  • 3.1.
    3.2.

  • 4.1.
    4.2.

  • 5.1.
  • กับ
    6.1.

  • 7.1.
    7.2.
  • การเรียกใช้ฟังก์ชัน

    การเรียกใช้ฟังก์ชันเกิดขึ้นเมื่อนิพจน์ที่เป็นวัตถุฟังก์ชันตามด้วยวงเล็บเปิด (รายการอาร์กิวเมนต์ที่คั่นด้วยเครื่องหมายจุลภาค และวงเล็บปิด) เช่น parseInt("18") นิพจน์ไม่สามารถเป็นตัวเข้าถึง myObject.myFunction ที่ทำให้การเรียกใช้เมธอด ตัวอย่างเช่น .join(",") ไม่ใช่การเรียกใช้ฟังก์ชัน แต่เป็นการเรียกใช้เมธอด

    ตัวอย่างง่ายๆ ของการเรียกใช้ฟังก์ชัน:

    ฟังก์ชั่น สวัสดี(ชื่อ) ( return "Hello " + name + "!"; ) // การเรียกใช้ฟังก์ชัน var message = hello("World"); console.log(ข้อความ); // => "สวัสดีชาวโลก!"

    hello("World") เป็นการเรียกใช้ฟังก์ชัน: hello ถือเป็นวัตถุฟังก์ชันตามด้วยอาร์กิวเมนต์ "World" ในวงเล็บ

    ข้อความ Var = (function(name) ( return "Hello " + name + "!"; ))("World"); console.log(ข้อความ); // => "สวัสดีชาวโลก!"

    นี่เป็นการเรียกใช้ฟังก์ชันด้วย: วงเล็บคู่แรก (function(name) (...)) ถือเป็นวัตถุฟังก์ชัน ตามด้วยอาร์กิวเมนต์ในวงเล็บ: ("World")

    สิ่งนี้เมื่อเรียกใช้ฟังก์ชัน

    นี่คือวัตถุโกลบอลเมื่อเรียกใช้ฟังก์ชัน

    วัตถุส่วนกลางถูกกำหนดโดยสภาพแวดล้อมรันไทม์ ในเว็บเบราว์เซอร์ นี่คือวัตถุหน้าต่าง

    ในการเรียกใช้ฟังก์ชัน บริบทการดำเนินการคือวัตถุส่วนกลาง ลองตรวจสอบบริบทของฟังก์ชันต่อไปนี้:

    ฟังก์ชั่น sum(a, b) ( console.log(this === window); // => true this.myNumber = 20; // เพิ่มคุณสมบัติ "myNumber" ให้กับ global object return a + b; ) // sum( ) ถูกเรียกใช้เป็นฟังก์ชัน // this in sum() is a global object (window) console.log(sum(15, 16)); // => 31 console.log(window.myNumber); // => 20

    เมื่อเรียกผลรวม (15, 16) JavaScript จะเริ่มต้นสิ่งนี้โดยอัตโนมัติเป็นอ็อบเจ็กต์โกลบอล ซึ่งก็คือหน้าต่างในเบราว์เซอร์

    เมื่อสิ่งนี้ถูกใช้นอกขอบเขตของฟังก์ชันใด ๆ (ขอบเขตภายนอกสุด: บริบทการดำเนินการทั่วโลก) มันยังอ้างถึงอ็อบเจ็กต์ส่วนกลางด้วย:

    Console.log (หน้าต่าง === นี้); // => true this.myString = "สวัสดีชาวโลก!"; console.log(window.myString); // => "สวัสดีชาวโลก!"

    console.log (หน้าต่าง === นี้); // => จริง

    สิ่งนี้เมื่อเรียกใช้ฟังก์ชันในโหมดเข้มงวด

    นี่ไม่ได้กำหนดไว้เมื่อเรียกใช้ฟังก์ชันในโหมดเข้มงวด

    /* jshint esnext: true */ class City ( ตัวสร้าง (ชื่อ, เดินทางแล้ว) ( this.name = name; this.traveled = false; ) travel() ( this.traveled = true; ) ) // การเรียกใช้ตัวสร้าง var paris = เมืองใหม่("ปารีส", เท็จ); ปารีส.ทราเวล();

    new City("Paris") เป็นการเรียกคอนสตรัคเตอร์ การเริ่มต้นวัตถุถูกควบคุมโดยวิธีคลาสพิเศษ: ตัวสร้าง ซึ่งนี่คือวัตถุที่สร้างขึ้นใหม่

    การเรียก Constructor จะสร้างอ็อบเจ็กต์ว่างใหม่ที่สืบทอดคุณสมบัติจากต้นแบบของ Constructor บทบาทของฟังก์ชัน Constructor คือการเริ่มต้นวัตถุ ดังที่คุณทราบแล้วว่าบริบทของการโทรประเภทนี้เรียกว่าอินสแตนซ์ นี่คือหัวข้อของบทถัดไป

    เมื่อตัวเข้าถึง myObject.myFunction นำหน้าด้วยคีย์เวิร์ดใหม่ JavaScript จะทำการเรียกคอนสตรัคเตอร์ แทนที่จะเรียกเมธอด ลองใช้ myObject.myFunction() ใหม่เป็นตัวอย่าง: ขั้นแรก โดยใช้ตัวเข้าถึง extractedFunction = myObject.myFunction ฟังก์ชันจะถูกแตกออกมา จากนั้นจึงเรียกว่าเป็นตัวสร้างเพื่อสร้างวัตถุใหม่: new extractedFunction()

    สิ่งนี้ในการเรียกคอนสตรัคเตอร์

    นี่คือวัตถุที่สร้างขึ้นใหม่

    บริบทของการเรียกตัวสร้างเป็นวัตถุที่สร้างขึ้นใหม่ มันถูกใช้เพื่อเริ่มต้นวัตถุด้วยข้อมูลจากอาร์กิวเมนต์ฟังก์ชันคอนสตรัคเตอร์

    ลองตรวจสอบบริบทในตัวอย่างต่อไปนี้:

    new Foo() ทำการเรียก Constructor ด้วยบริบท fooInstance วัตถุถูกเตรียมใช้งานภายใน Foo: this.property ถูกตั้งค่าเป็นค่าเริ่มต้น

    สิ่งเดียวกันนี้เกิดขึ้นเมื่อใช้ class เฉพาะการเริ่มต้นเท่านั้นที่เกิดขึ้นในเมธอด Constructor:

    /* jshint esnext: true */ class Bar ( Constructor() ( console.log(this instanceof Bar); // => true this.property = "Default Value"; ) ) // การเรียกใช้ Constructor var barInstance = new Bar( ); console.log(barInstance.property); // => "ค่าเริ่มต้น"

    เมื่อ new Bar() ถูกดำเนินการ JavaScript จะสร้างอ็อบเจ็กต์ว่างและทำให้เป็นบริบทของเมธอด Constructor ตอนนี้คุณสามารถเพิ่มคุณสมบัติโดยใช้สิ่งนี้: this.property = "Default Value"

    กับดัก: วิธีที่จะไม่ลืมสิ่งใหม่

    ฟังก์ชัน JavaScript บางตัวจะสร้างอินสแตนซ์เมื่อไม่เพียงแต่เรียกว่า Constructor เท่านั้น แต่ยังเรียกเป็นฟังก์ชันด้วย ตัวอย่างเช่น RegExp:

    Var reg1 = RegExp ใหม่("\\w+"); var reg2 = RegExp("\\w+"); console.log (อินสแตนซ์ reg1 ของ RegExp); // => true console.log (อินสแตนซ์ reg2 ของ RegExp); // => true console.log(reg1.source === reg2.source); // => จริง

    เมื่อมีการดำเนินการ RegExp("\\w+") และ RegExp("\\w+") ใหม่ JavaScript จะสร้างออบเจ็กต์นิพจน์ทั่วไปที่เทียบเท่ากัน

    การใช้การเรียกฟังก์ชันเพื่อสร้างวัตถุอาจเป็นอันตรายได้ (หากคุณละเว้นวิธีการแบบโรงงาน) เนื่องจากตัวสร้างบางตัวอาจไม่เริ่มต้นวัตถุหากไม่มีคีย์เวิร์ดใหม่

    ตัวอย่างต่อไปนี้แสดงให้เห็นถึงปัญหา:

    ฟังก์ชั่น Vehicle(type, wheelCount) ( this.type = type; this.wheelsCount = wheelCount; return this; ) // การเรียกใช้ฟังก์ชัน var car = Vehicle("Car", 4); console.log (ประเภทรถ); // => "รถยนต์" console.log(car.wheelsCount); // => 4 console.log (รถยนต์ === หน้าต่าง); // => จริง

    Vehicle เป็นฟังก์ชันที่ตั้งค่าประเภทและคุณสมบัติ wheelCount ของวัตถุบริบท เมื่อดำเนินการ Vehicle("Car", 4) มันจะส่งคืนวัตถุ car ที่มีคุณสมบัติที่ถูกต้อง: car.type เท่ากับ "Car" และ car.wheelsCount คือ 4 เป็นเรื่องง่ายที่จะคิดว่าทุกอย่างทำงานได้ตามที่ควรจะเป็น

    อย่างไรก็ตามนี่คือ วัตถุหน้าต่างเมื่อเรียกใช้ฟังก์ชัน และ Vehicle("Car", 4) จะตั้งค่าคุณสมบัติของวัตถุหน้าต่าง - โอ๊ะโอ มีบางอย่างผิดพลาด ไม่ได้สร้างวัตถุใหม่

    อย่าลืมใช้โอเปอเรเตอร์ใหม่เมื่อคาดว่าจะมีการเรียกคอนสตรัคเตอร์:

    ฟังก์ชั่น ยานพาหนะ (ประเภท, ล้อนับ) ( ถ้า (! (อินสแตนซ์ของยานพาหนะนี้)) ( โยนข้อผิดพลาด ("ข้อผิดพลาด: การเรียกใช้ไม่ถูกต้อง"); ) this.type = type; this.wheelsCount = ล้อนับ; คืนสิ่งนี้; ) // การเรียกใช้ตัวสร้าง var car = ยานพาหนะใหม่ ("รถยนต์", 4); console.log (ประเภทรถ); // => "รถยนต์" console.log(car.wheelsCount); // => 4 console.log (ตัวอย่างรถยนต์ของยานพาหนะ); // => true // การเรียกใช้ฟังก์ชัน ทำให้เกิดข้อผิดพลาด var BrokenCar = ยานพาหนะ ("รถเสีย", 3);

    ยานพาหนะใหม่ ("รถยนต์", 4) ทำงานอย่างถูกต้อง: วัตถุใหม่สร้างและเริ่มต้นเนื่องจากมีคำว่าใหม่อยู่

    เพิ่มการตรวจสอบการเรียกใช้ฟังก์ชัน: อินสแตนซ์ของยานพาหนะนี้เพื่อให้แน่ใจว่าบริบทการดำเนินการมีประเภทวัตถุที่ถูกต้อง หากนี่ไม่ใช่ยานพาหนะ จะเกิดข้อผิดพลาดขึ้น ดังนั้น หาก Vehicle("Broken Car", 3) ถูกดำเนินการ (โดยไม่มีสิ่งใหม่) ข้อยกเว้นจะเกิดขึ้น: Error: Incorrect invocation

    โทรทางอ้อม

    การเรียกทางอ้อมเกิดขึ้นเมื่อฟังก์ชันถูกเรียกใช้โดยเมธอด .call() หรือ .apply()

    /* jshint esnext: true */ var sumArguments = (...args) => ( console.log(typeof arguments); // => "unknown" return args.reduce((result, item) => result + item ); console.log(sumArguments.ชื่อ); // => "" console.log(sumArguments(5, 5, 6)); // => 16

    สิ่งนี้อยู่ในฟังก์ชันลูกศร

    นี่คือบริบทที่กำหนดฟังก์ชันลูกศร

    ฟังก์ชันลูกศรไม่ได้สร้างบริบทการดำเนินการของตัวเอง แต่ยืมสิ่งนี้จากฟังก์ชันภายนอกที่กำหนดไว้

    ตัวอย่างต่อไปนี้แสดงความโปร่งใสของบริบท:

    /* jshint esnext: true */ class Point ( ตัวสร้าง (x, y) ( this.x = x; this.y = y; ) log() ( console.log(this === myPoint); setTimeout(() => ( console.log(this === myPoint); // => true console.log(this.x + /// + this.y); // => "95:165" ), 1,000); ) ) var myPoint = จุดใหม่ (95, 165); myPoint.log();

    setTimeout เรียกใช้ฟังก์ชันลูกศรในบริบทเดียวกัน (เมธอด myPoint) เป็นเมธอด log() ดังที่เราเห็น ฟังก์ชันลูกศร "สืบทอด" บริบทของฟังก์ชันที่ถูกกำหนดไว้

    หากคุณพยายามใช้ฟังก์ชันปกติในตัวอย่างนี้ ฟังก์ชั่นจะสร้างบริบทของตัวเอง (หน้าต่างหรือไม่ได้กำหนด) ดังนั้น เพื่อให้โค้ดทำงานได้อย่างถูกต้อง คุณจะต้องผูกบริบทด้วยตนเอง: setTimeout(function() (...).bind(this)) วิธีนี้ยุ่งยาก ดังนั้นจึงใช้ฟังก์ชันลูกศรได้ง่ายกว่า

    หากมีการกำหนดฟังก์ชันลูกศรไว้นอกฟังก์ชันทั้งหมด บริบทของฟังก์ชันจะเป็นวัตถุโกลบอล:

    /* jshint esnext: true */ var getContext = () => ( console.log(this === window); // => true ส่งคืนสิ่งนี้; ); console.log(getContext() === หน้าต่าง); // => จริง

    ฟังก์ชันลูกศรเชื่อมโยงกับบริบทของคำศัพท์ทุกครั้ง สิ่งนี้ไม่สามารถเปลี่ยนแปลงได้แม้จะใช้วิธีการเปลี่ยนบริบท:

    /* jshint esnext: true */ var number = ; (function() ( var get = () => ( return this; ); console.log(this ===ตัวเลข); // => true console.log(get()); // => // ใช้ ฟังก์ชั่นลูกศรด้วย .apply() และ .call() console.log(get.call()); // => console.log(get.apply()); .bind()()); )).โทร(หมายเลข);

    ฟังก์ชันที่ถูกเรียกทางอ้อมโดยใช้ .call(numbers) จะตั้งค่านี้เป็นค่าของตัวเลข ฟังก์ชันลูกศร get ยังได้รับตัวเลขเช่นนี้เนื่องจากใช้บริบทตามคำศัพท์ ไม่ว่าจะเรียก get อย่างไร บริบทของมันจะเป็นตัวเลขเสมอ การโทรทางอ้อมด้วยบริบทอื่น (โดยใช้ .call() หรือ .apply()) การเชื่อมโยงใหม่ (โดยใช้ .bind()) จะไม่มีผลใดๆ

    ไม่สามารถใช้ฟังก์ชันลูกศรเป็นตัวสร้างได้ หากคุณเรียก new get() JavaScript จะส่งข้อผิดพลาด: TypeError: get is not a Constructor

    หลุมพราง: การกำหนดวิธีการด้วยฟังก์ชันลูกศร

    คุณอาจต้องการใช้ฟังก์ชันลูกศรเพื่อประกาศวิธีการ ยุติธรรมเพียงพอ: การประกาศของพวกเขาสั้นกว่ามากเมื่อเทียบกับนิพจน์ปกติ: แทน (param) => (...) function(param) (..)

    ตัวอย่างนี้แสดงให้เห็นถึงการกำหนดรูปแบบ () วิธีการของคลาสระยะเวลาโดยใช้ฟังก์ชันลูกศร:

    /* jshint esnext: true */ ฟังก์ชั่น ระยะเวลา (ชั่วโมง นาที) ( this.hours = ชั่วโมง; this.นาที = นาที; ) Period.prototype.format = () => ( console.log (หน้าต่าง === นี้) ; // =>

    เนื่องจากรูปแบบเป็นฟังก์ชันลูกศรที่กำหนดไว้ในบริบทส่วนกลาง นี่คือวัตถุหน้าต่าง แม้ว่ารูปแบบจะถูกดำเนินการเป็นวิธีการของอ็อบเจ็กต์ walkPeriod.format() หน้าต่างก็ยังคงเป็นบริบทการโทร สิ่งนี้เกิดขึ้นเนื่องจากฟังก์ชันลูกศรมีบริบทคงที่ซึ่งไม่ได้รับการแก้ไขโดยการเรียกประเภทอื่น

    นี่คือ window ดังนั้น this.hours และ this. minutes จึงกลายเป็นไม่ได้กำหนด วิธีการส่งกลับสตริง "ชั่วโมงที่ไม่ได้กำหนดและนาทีที่ไม่ได้กำหนด" ซึ่งไม่ใช่ผลลัพธ์ที่ต้องการ

    นิพจน์ฟังก์ชันช่วยแก้ปัญหาได้เนื่องจากฟังก์ชันปกติจะเปลี่ยนบริบทขึ้นอยู่กับการเรียก:

    ระยะเวลาของฟังก์ชัน (ชั่วโมง นาที) ( this.hours = hours; this. minutes = minutes; ) Period.prototype.format = function() ( console.log(this === walkPeriod); // => true ส่งคืนสิ่งนี้ ชั่วโมง + "ชั่วโมง และ" + this. minutes + "นาที" ); var walkPeriod = ระยะเวลาใหม่ (2, 30); console.log(walkPeriod.format());

    walkPeriod.format() เป็นการเรียกเมธอดพร้อมกับบริบทของ walkPeriod this.hours รับค่า 2 และ this. minutes รับค่า 30 ดังนั้นเมธอดจึงส่งคืนผลลัพธ์ที่ถูกต้อง: "2 hour and 30 minutes"

    บทสรุป

    เนื่องจากการเรียกใช้ฟังก์ชันมีผลกระทบมากที่สุดต่อสิ่งนี้ จากนี้ไปอย่าถาม:

    สิ่งนี้มาจากไหน?

    และถาม:

    ฟังก์ชันนี้เรียกว่าอย่างไร?

    และในกรณีของฟังก์ชันลูกศร ให้ถามว่า:

    นี่คืออะไรที่มีการประกาศฟังก์ชันลูกศร?

    วิธีนี้จะช่วยให้คุณไม่ต้องปวดหัวโดยไม่จำเป็น

    อย่าสับสนในบริบท!

    12 คำตอบ

    นี่คืออะไร

    นี่คือฟังก์ชันลูกศร

    ฟังก์ชันลูกศรเป็นไวยากรณ์สั้นๆ ที่ใช้ใน ECMAscript 6 ซึ่งสามารถใช้ได้ในลักษณะเดียวกันกับวิธีที่คุณใช้นิพจน์ฟังก์ชัน กล่าวอีกนัยหนึ่ง คุณมักจะใช้แทนสำนวนต่างๆ เช่น function (foo) (...) ได้ แต่พวกเขามีความแตกต่างที่สำคัญบางประการ ตัวอย่างเช่น พวกเขาไม่ได้ผูกมัดค่านี้ของตนเอง (ดูการสนทนาด้านล่าง)

    ฟังก์ชันลูกศรเป็นส่วนหนึ่งของข้อกำหนด ECMAscript 6 ฟังก์ชันเหล่านี้ยังไม่รองรับในเบราว์เซอร์ทั้งหมด แต่ได้รับการรองรับบางส่วนหรือทั้งหมดใน Node v 4.0+ และในเบราว์เซอร์สมัยใหม่ส่วนใหญ่ที่ใช้งานในปี 2018 (ด้านล่างคือรายการเบราว์เซอร์ที่รองรับบางส่วน)

    จากเอกสารของ Mozilla:

    นิพจน์ฟังก์ชันลูกศร (หรือเรียกอีกอย่างว่าฟังก์ชันลูกศรอ้วน) มีไวยากรณ์ที่สั้นกว่านิพจน์ฟังก์ชัน และผูกคำศัพท์กับค่านี้ (ไม่ผูกค่า this , arguments , super หรือ new.target ของตัวเอง) ฟังก์ชันลูกศรจะไม่ระบุชื่อเสมอ นิพจน์ฟังก์ชันเหล่านี้เหมาะที่สุดสำหรับฟังก์ชันที่ไม่ใช่เมธอด และไม่สามารถใช้เป็นตัวสร้างได้

    หมายเหตุเกี่ยวกับวิธีการทำงานในฟังก์ชันลูกศร

    หนึ่งในคุณสมบัติที่สะดวกที่สุดของฟังก์ชั่นลูกศรถูกซ่อนอยู่ในข้อความด้านบน:

    กล่าวง่ายๆ ก็คือ ฟังก์ชันลูกศรจะเก็บค่านี้จากบริบทของมัน และไม่มีค่า this ของตัวเอง ฟังก์ชันดั้งเดิมอาจผูกค่านี้ด้วยตัวมันเอง ขึ้นอยู่กับวิธีการกำหนดและเรียกใช้ อาจต้องใช้ยิมนาสติกมาก เช่น self = this; ฯลฯ เพื่อเข้าถึงหรือจัดการสิ่งนี้จากฟังก์ชันหนึ่งภายในฟังก์ชันอื่น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้ โปรดดูคำอธิบายและตัวอย่างในเอกสารประกอบของ Mozilla

    รหัสตัวอย่าง

    ตัวอย่าง (จากเอกสารด้วย):

    Var a = [ "เรา" ตื่นทั้งคืน "จนพระอาทิตย์" "เรา" ตื่นทั้งคืนเพื่อกินอะไรสักอย่าง" "เรา" ตื่นทั้งคืนเพื่อความสนุกสนาน" "เรา" ตื่นทั้งคืนเพื่อจะได้กิน lucky" ]; // งานทั้งสองนี้เทียบเท่ากัน: // Old-school: var a2 = a.map(function(s)( return s.length )); // ECMAscript 6 โดยใช้ฟังก์ชันลูกศร var a3 = a.map (s => s.length); // ทั้ง a2 และ a3 จะเท่ากับ

    หมายเหตุความเข้ากันได้

    คุณสามารถใช้ฟังก์ชันลูกศรใน Node ได้ แต่การรองรับเบราว์เซอร์นั้นไม่ถูกต้องทั้งหมด

    การสนับสนุนเบราว์เซอร์สำหรับฟังก์ชันนี้ได้รับการปรับปรุงอย่างมาก แต่ก็ยังไม่แพร่หลายเพียงพอสำหรับแอปพลิเคชันที่ใช้เบราว์เซอร์ส่วนใหญ่ ณ วันที่ 12 ธันวาคม 2017 รองรับในเวอร์ชันปัจจุบัน:

    • Chrome (เทียบกับ 45+)
    • Firefox (เทียบกับ 22+)
    • Edge (เทียบกับ 12+)
    • โอเปร่า (ข้อ 32+)
    • เบราว์เซอร์ Android(เวอร์ชั่น 47+)
    • Opera Mobile (เวอร์ชัน 33+)
    • Chrome สำหรับ Android (เวอร์ชัน 47+)
    • Firefox สำหรับ Android (เวอร์ชัน 44+)
    • ซาฟารี (เวอร์ชัน 1 0+)
    • iOS ซาฟารี (เวอร์ชัน 10.2+)
    • อินเทอร์เน็ต Samsung (เวอร์ชัน 5+)
    • เบราว์เซอร์ Baidu (v. 7. 12+)

    ไม่รองรับใน:

    • IE (ก่อนข้อ 11)
    • Opera Mini (สูงสุดเวอร์ชัน 8.0)
    • เบราว์เซอร์ Blackberry (สูงสุดเวอร์ชัน 10)
    • IE Mobile (สูงสุดเวอร์ชัน 11)
    • เบราว์เซอร์ UC สำหรับ Android (สูงสุดเวอร์ชัน 11.4)
    • QQ (สูงสุดเวอร์ชัน 1.2)

    คุณสามารถค้นหาข้อมูลเพิ่มเติม (และเป็นปัจจุบัน) ได้ที่ CanIUse.com (ไม่มีส่วนเกี่ยวข้อง)

    ฟังก์ชันนี้เรียกว่าฟังก์ชันลูกศร ซึ่งเป็นส่วนหนึ่งของข้อกำหนด ECMAScript 2015...

    var foo = ["a", "ab", "abc"]; var bar = foo.map(f => f.length); console.log(บาร์); // 1,2,3

    ไวยากรณ์สั้นกว่าก่อนหน้า:

    // < ES6: var foo = ["a", "ab", "abc"]; var bar = foo.map(function(f) { return f.length; }); console.log(bar); // 1,2,3

    สิ่งที่น่าทึ่งอีกประการหนึ่งคือคำศัพท์นี้... โดยปกติแล้ว คุณจะทำสิ่งต่อไปนี้:

    ฟังก์ชั่น Foo() ( this.name = name; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( var self = this; setInterval(function() ( // นี่คือ Window ไม่ใช่ Foo () อย่างที่คุณอาจคาดหวัง console.log(this); // // ว่าเหตุใดเราจึงกำหนดสิ่งนี้ใหม่ให้กับ self ก่อน setInterval() console.log(self.count++), 1000) ) new Foo();

    แต่สามารถเขียนใหม่ได้โดยใช้ลูกศรดังนี้:

    ฟังก์ชั่น Foo() ( this.name = name; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( setInterval(() => ( console.log(this); // console.log(this.count); // 1, 2, 3 this.count++; ), 1,000) ) ใหม่ ฟู();

    นี่จะเป็น "นิพจน์ฟังก์ชันลูกศร" ที่นำมาใช้ใน ECMAScript 6

    เพื่อวัตถุประสงค์ทางประวัติศาสตร์ (หากหน้าวิกิมีการเปลี่ยนแปลงในภายหลัง) นี่คือ:

    นิพจน์ฟังก์ชันลูกศรมีไวยากรณ์ที่สั้นกว่านิพจน์ฟังก์ชันและผูกค่านั้นด้วยคำศัพท์ ฟังก์ชันลูกศรจะไม่ระบุชื่อเสมอ

    เรียกอีกอย่างว่าฟังก์ชันลูกศรอ้วน นี่เป็นวิธีที่ง่ายและชัดเจนในการเขียนนิพจน์ฟังก์ชัน เช่น function() ()

    ฟังก์ชันลูกศรสามารถขจัดความจำเป็นในการใช้ฟังก์ชัน , return และ () เมื่อกำหนดฟังก์ชัน เป็นบรรทัดเดียวที่คล้ายกับนิพจน์แลมบ์ดาใน Java หรือ Python

    ตัวอย่างที่ไม่มีพารามิเตอร์

    const Queue = ["เดฟ", "ซาราห์", "ชารอน"]; const nextCustomer = () => คิว; console.log(ลูกค้าถัดไป()); // "เดฟ"

    หากคุณต้องการทำหลายคำสั่งในฟังก์ชันลูกศรเดียวกัน ตัวอย่างนี้กำหนดให้คุณต้องใส่คิวไว้ในเครื่องหมายปีกกา () ในกรณีนี้ ไม่สามารถละเว้นคำสั่ง return ได้

    ตัวอย่างที่มี 1 พารามิเตอร์

    const Queue = ["เดฟ", "ซาราห์", "ชารอน"]; const addCustomer = name => ( Queue.push(name); ); addCustomer("โทบี้"); console.log(คิว); // ["เดฟ", "ซาราห์", "ชารอน", "โทบี้"]

    คุณสามารถละเว้น () จากด้านบนได้

    เมื่อมีพารามิเตอร์ตัวเดียว คุณสามารถละเว้นวงเล็บ () รอบพารามิเตอร์ได้

    ตัวอย่างที่มีหลายพารามิเตอร์

    const addNumbers = (x, y) => x + y console.log(addNumbers(1, 5)); // 6

    ตัวอย่างที่เป็นประโยชน์ const Fruit = [ (ชื่อ: "Apple", ราคา: 2), (ชื่อ: "Bananna", ราคา: 3), (ชื่อ: "Pear", ราคา: 1) ];

    หากเราต้องการทราบราคาของผลไม้แต่ละชนิดในอาร์เรย์เดียว ใน ES5 เราสามารถทำได้:

    Fruits.map(function(fruit) ( return fruit.price; )); -

    ใน ES6 ด้วยฟังก์ชันลูกศรใหม่ เราสามารถทำให้สิ่งนี้กระชับยิ่งขึ้น:

    Fruits.map(ผลไม้ => ผลไม้.ราคา); -

    ข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชั่นที่มีลูกศรสามารถพบได้

    ความเข้ากันได้ของเบราว์เซอร์
    • IE: ยังไม่รองรับ
    • Edge: 12+ (ทุกเวอร์ชัน)
    • ไฟร์ฟอกซ์: 22+
    • โครม: 45+
    • ซาฟารี: 10+
    • iOS ซาฟารี: 10.2+
    • เบราว์เซอร์ Android: 56+

    สำหรับข้อมูลความเข้ากันได้ของเบราว์เซอร์ที่เป็นปัจจุบันเพิ่มเติม โปรดไปที่

    อย่างที่คนอื่นๆ พูด นี่คือไวยากรณ์ใหม่สำหรับการสร้างฟังก์ชัน

    อย่างไรก็ตาม ฟังก์ชันประเภทนี้แตกต่างจากฟังก์ชันปกติ:

      พวกเขาผูกมัดคุณค่าของสิ่งนี้ ตามข้อกำหนดอธิบายว่า

      ArrowFunction ไม่ได้กำหนดการเชื่อมโยงเฉพาะสำหรับอาร์กิวเมนต์ , super , this หรือ new.target การอ้างอิงถึงข้อโต้แย้ง , super , this หรือ new.target ภายใน ArrowFunction จะช่วยแก้ไขการเชื่อมโยงในสภาพแวดล้อมของคำศัพท์ โดยปกติแล้ว นี่จะเป็นสภาพแวดล้อมการทำงานทันทีที่เป็นฟังก์ชัน

      แม้ว่า ArrowFunction อาจมีการอ้างอิงถึง super แต่ออบเจ็กต์ฟังก์ชันที่สร้างขึ้นในขั้นตอนที่ 4 จะไม่กลายเป็นวิธีการโดยการรัน MakeMethod ArrowFunction ที่อ้างอิงถึง super จะอยู่ภายในฟังก์ชันที่ไม่ใช่ลูกศรเสมอ และการใช้งาน super ที่จำเป็นสามารถเข้าถึงได้ผ่านขอบเขตที่ออบเจ็กต์ฟังก์ชัน ArrowFunction บันทึกไว้

    • พวกเขาไม่ใช่ผู้สร้าง

      ซึ่งหมายความว่าไม่มีวิธีการภายใน [] และดังนั้นจึงไม่สามารถสร้างอินสแตนซ์ได้ เป็นต้น

      วาร์ ฟ = ก => ก; ฉ(123); // 123 f ใหม่ (); // TypeError: f ไม่ใช่ตัวสร้าง

    ส่วนที่เพิ่มเข้าไป ตัวอย่างง่ายๆ CRUD พร้อมลูกศร

    //ฟังก์ชันลูกศร var ลูกค้า = [ ( ชื่อ: "Dave" ติดต่อ: "9192631770" ), ( ชื่อ: "Sarah" ติดต่อ: "9192631770" ), ( ชื่อ: "Akhil" ติดต่อ: "9928462656" )] , // ไม่มีพารามิเตอร์ READ getFirstCustomer = () => ( console.log(this); return customer; );

    console.log("ลูกค้ารายแรก "+JSON.stringify(getFirstCustomer())); // "Dave" //1 Param SEARCH getNthCustomer = index=>( if(index>customers.length) ( return "No such thing"; ) else( return customer; ) );

    ในจาวาสคริปต์ สัญลักษณ์ => คือสัญลักษณ์นิพจน์ฟังก์ชันลูกศร นิพจน์ฟังก์ชันลูกศรไม่มีการผูกข้อมูลนี้เอง ดังนั้นจึงไม่สามารถใช้เป็นฟังก์ชันคอนสตรัคเตอร์ได้ ตัวอย่างเช่น:

    var word = "สวัสดีจากวัตถุภายนอก"; ให้ obj = ( คำ: "สวัสดีจากวัตถุภายใน", talk1: () => (console.log(this.words)), talk2: function () (console.log(this.words)) ) obj.talk1( ); // ไม่มีการผูกข้อมูลนี้เอง === หน้าต่าง obj.talk2(); // มีการผูกข้อมูลนี้เอง นี่คือ obj

    กฎการใช้ฟังก์ชั่นลูกศร:
    • หากมีเพียงหนึ่งอาร์กิวเมนต์ คุณสามารถละเว้นวงเล็บอาร์กิวเมนต์ได้
    • หากคุณส่งคืนนิพจน์และทำในบรรทัดเดียวกัน คุณสามารถละเว้น () และคำสั่ง return ได้

    ตัวอย่างเช่น:

    ให้ times2 = val => val * 2; // มันอยู่ในบรรทัดเดียวกันและส่งกลับนิพจน์ ดังนั้น () จึงถูกคอมมิตและนิพจน์ส่งคืนโดยปริยาย // นอกจากนี้ยังมีอาร์กิวเมนต์เดียวเท่านั้น ดังนั้นวงเล็บรอบอาร์กิวเมนต์จะถูกละไว้ console.log(times2(3));

    ไม่พอใจกับคำตอบอื่น ๆ คำตอบที่ได้รับการโหวตมากที่สุดในวันที่ 3/2019/13 นั้นไม่ถูกต้องตามข้อเท็จจริง

    เวอร์ชันที่กระชับสั้นๆ ของ what => หมายถึงเป็นทางลัดสำหรับเขียนฟังก์ชันและเชื่อมโยงกับฟังก์ชันปัจจุบัน

    Const foo = a => a * 2;

    ทางลัดอย่างมีประสิทธิภาพสำหรับ

    Const foo = function(a) ( return a * 2; ).bind(this);

    มองเห็นของที่ตัดได้หมดครับ เราไม่ต้องการ function , return , .bind(this) , วงเล็บหรือวงเล็บ

    ตัวอย่างฟังก์ชันลูกศรที่ยาวกว่านี้เล็กน้อยอาจเป็นได้

    Const foo = (width, height) => ( const area = width * height; return area; );

    มันแสดงให้เห็นว่าหากเราต้องการอาร์กิวเมนต์ของฟังก์ชันหลายรายการ เราต้องการวงเล็บ และหากเราต้องการเขียนนิพจน์มากกว่าหนึ่งรายการ เราจำเป็นต้องมีเครื่องหมายปีกกาและ return ที่ชัดเจน

    สิ่งสำคัญคือต้องเข้าใจส่วน .bind และนี่เป็นหัวข้อใหญ่ สิ่งนี้เกี่ยวข้องกับความหมายใน JavaScript

    ฟังก์ชันทั้งหมดมีพารามิเตอร์โดยนัยที่เรียกว่าสิ่งนี้ วิธีการตั้งค่าเมื่อเรียกใช้ฟังก์ชันจะขึ้นอยู่กับวิธีการเรียกใช้ฟังก์ชัน

    ยอมรับ

    ฟังก์ชั่น foo() ( console.log(this); )

    ถ้าจะเรียกว่าโอเค

    ฟังก์ชั่น foo() ( console.log(this); ) foo();

    นี่จะเป็นวัตถุระดับโลก

    หากคุณอยู่ในโหมดเข้มงวด

    "ใช้อย่างเข้มงวด"; ฟังก์ชั่น foo() ( console.log(this); ) foo(); // หรือฟังก์ชัน foo() ( "use strict"; console.log(this); ) foo();

    จะไม่มีการกำหนด

    คุณสามารถตั้งค่านี้ได้โดยตรงโดยใช้การโทรหรือสมัคร

    ฟังก์ชั่น foo(msg) ( console.log(msg, this); ) const obj1 = (abc: 123) const obj2 = (def: 456) foo.call(obj1, "hello"); // พิมพ์ สวัสดี (abc: 123) foo.apply(obj2, ["hi"]); // พิมพ์สวัสดี (def: 456)

    คุณยังสามารถตั้งค่านี้โดยปริยายได้โดยใช้ตัวดำเนินการจุด

    ฟังก์ชั่น foo(msg) ( console.log(msg, this); ) const obj = ( abc: 123, bar: foo, ) obj.bar("Hola"); // พิมพ์ Hola (abc:123, bar: f)

    ปัญหาเกิดขึ้นเมื่อคุณต้องการใช้ฟังก์ชันเป็นตัวโทรกลับหรือตัวฟัง คุณกำลังสร้างคลาสและต้องการกำหนดฟังก์ชันเป็นการเรียกกลับที่เข้าถึงอินสแตนซ์ของคลาส

    Class ShowName ( ตัวสร้าง(ชื่อ, elem) ( this.name = name; elem.addEventListener("click", function() ( console.log(this.name); // จะไม่ทำงาน )); ) )

    โค้ดด้านบนจะไม่ทำงานเนื่องจากเมื่อองค์ประกอบทำให้เกิดเหตุการณ์และเรียกใช้ฟังก์ชัน ค่านี้จะไม่เป็นอินสแตนซ์ของคลาส

    วิธีหนึ่งที่พบบ่อยในการแก้ปัญหานี้คือการใช้ .bind

    คลาส ShowName ( ตัวสร้าง(ชื่อ, elem) ( this.name = name; elem.addEventListener("click", function() ( console.log(this.name); ).bind(this); // ( console.log (ชื่อนี้);

    ผูกมันได้อย่างมีประสิทธิภาพ คุณลักษณะใหม่- หากไม่มีการเชื่อมโยงคุณสามารถสร้างของคุณเองเช่นนี้

    ฟังก์ชั่นผูก (funcitonToBind, valueToUseForThis) ( return function(...args) ( functionToBind.call(valueToUseForThis, ...args); )

    ใน JavaScript เก่าที่ไม่มีตัวดำเนินการสเปรดจะเป็นเช่นนี้

    ฟังก์ชั่นผูก (funcitonToBind, valueToUseForThis) ( return function() ( functionToBind.apply(valueToUseForThis, arguments); )

    การทำความเข้าใจว่าโค้ดจำเป็นต้องมีความเข้าใจในการปิด แต่การผูกเวอร์ชันสั้นจะสร้างฟังก์ชันใหม่ที่เรียกใช้ฟังก์ชันดั้งเดิมโดยผูกค่านี้ไว้เสมอ ฟังก์ชั่นลูกศรทำสิ่งเดียวกันเนื่องจากเป็นทางลัดในการผูก (สิ่งนี้)

    ลูกศรฟังก์ชันซึ่งแสดงด้วยสัญลักษณ์ (=>) ช่วยคุณสร้างฟังก์ชันและวิธีการที่ไม่ระบุชื่อ ส่งผลให้ไวยากรณ์สั้นลง ตัวอย่างเช่น ด้านล่างนี้คือฟังก์ชัน Add แบบธรรมดาที่ส่งคืนการบวกตัวเลขสองตัว

    เพิ่มฟังก์ชัน(num1 , num2)( return num1 + num2; )

    ฟังก์ชั่นด้านบนจะสั้นลงโดยใช้ไวยากรณ์ลูกศรดังที่แสดงด้านล่าง

    โค้ดด้านบนประกอบด้วยสองส่วนตามที่แสดงในภาพด้านบน:

    อินพุต: - ส่วนนี้ระบุพารามิเตอร์อินพุตสำหรับฟังก์ชันที่ไม่ระบุชื่อ

    ตรรกะ: - ส่วนนี้อยู่หลังสัญลักษณ์ "=>" ส่วนนี้มีตรรกะของฟังก์ชันจริง

    นักพัฒนาหลายคนเชื่อว่าฟังก์ชันลูกศรทำให้ไวยากรณ์ของคุณสั้นลง ง่ายขึ้น และทำให้โค้ดของคุณสามารถอ่านได้

    หากคุณเชื่อประโยคข้างต้น ผมขอยืนยันว่ามันเป็นเรื่องโกหก หากคุณคิดสักครู่ ฟังก์ชั่นที่เขียนอย่างถูกต้องพร้อมชื่อจะสามารถอ่านได้ง่ายกว่าฟังก์ชั่นที่เป็นความลับที่สร้างขึ้นในบรรทัดเดียวโดยใช้สัญลักษณ์ลูกศร

    การใช้งานหลักของฟังก์ชันลูกศรคือเพื่อให้แน่ใจว่าโค้ดถูกเรียกใช้งานในบริบทของผู้โทร

    ดูโค้ดด้านล่างซึ่งกำหนดตัวแปรส่วนกลาง "บริบท" ตัวแปรส่วนกลางนี้สามารถเข้าถึงได้ภายในฟังก์ชัน "SomeOtherMethod" ซึ่งเรียกจากวิธีอื่น "SomeMethod"

    SomeMethod นี้มีตัวแปรบริบทเฉพาะที่ ขณะนี้ เนื่องจาก SomeOtherMethod ถูกเรียกจาก "SomeMethod" เราจึงคาดหวังว่าจะแสดง "บริบทท้องถิ่น" แต่จะแสดง "บริบทสากล"

    Var context = "บริบทสากล"; ฟังก์ชัน SomeOtherMethod())( alert(this.context); ) ฟังก์ชัน SomeMethod())( this.context = "บริบทท้องถิ่น"; SomeOtherMethod(); ) var instance = new SomeMethod();

    แต่ถ้าคุณแทนที่การโทรด้วยฟังก์ชันลูกศร ก็จะแสดง "บริบทท้องถิ่น"

    Var context = "บริบทสากล";

    ฟังก์ชัน SomeMethod())( this.context = "local context"; SomeOtherMethod = () => ( alert(this.context); ) SomeOtherMethod(); ) var instance = new SomeMethod();

    ฉันขอแนะนำให้คุณอ่านลิงก์นี้ (ฟังก์ชันลูกศรใน JavaScript) ซึ่งจะอธิบายสถานการณ์บริบทของจาวาสคริปต์ทั้งหมด และในกรณีนี้บริบทของผู้โทรจะไม่ได้รับความเคารพ คุณยังสามารถดูการสาธิตได้ฟังก์ชั่นลูกศรพร้อมจาวาสคริปต์ในวิดีโอ YouTube นี้

    • ซึ่งแสดงให้เห็นในทางปฏิบัติของคำว่าบริบท

    การแปล

    ฟังก์ชันลูกศรอ้วน (=>) หรือที่เรียกว่าฟังก์ชันลูกศร เป็นฟังก์ชันใหม่ทั้งหมดใน ECMAScript 2015 (เดิมชื่อ ES6) หากเชื่อข่าวลือ ECMAScript 2015 => ไวยากรณ์ก็เริ่มถูกนำมาใช้แทน –> ไวยากรณ์ภายใต้อิทธิพลของ CoffeeScript นอกจากนี้ ความคล้ายคลึงกันของบริบทยังถ่ายทอดสิ่งนี้อีกด้วย

    ไวยากรณ์ฟังก์ชันใหม่ ไวยากรณ์ฟังก์ชัน JavaScript แบบคลาสสิกนั้นเข้มงวด ไม่ว่าจะเป็นฟังก์ชันที่มีตัวแปรเดียวหรือเพจที่มีหลายฟังก์ชัน ทุกครั้งที่คุณประกาศฟังก์ชัน คุณจะต้องเขียน function()() ความจำเป็นในการใช้ไวยากรณ์ของฟังก์ชันที่กระชับมากขึ้นเป็นเหตุผลหนึ่งที่ทำให้ CoffeeScript ได้รับความนิยมอย่างมากในสมัยนั้น ความต้องการนี้ชัดเจนโดยเฉพาะอย่างยิ่งในกรณีของฟังก์ชันการโทรกลับเล็กน้อย มาดูที่ Promise chain กัน:
    ฟังก์ชั่น getVerifiedToken(selector) ( return getUsers(selector) .then(function (users) ( return users; )).then(verifyUser) .then(function (user, validToken) ( return validToken; )) .catch(function (err) ) (บันทึก(err.stack); ));
    ด้านบนนี้ คุณจะเห็นโค้ดที่ย่อยได้ไม่มากก็น้อยซึ่งเขียนโดยใช้ไวยากรณ์ของฟังก์ชันแบบคลาสสิกใน JavaScript และนี่คือลักษณะของโค้ดเดียวกัน เขียนใหม่โดยใช้ไวยากรณ์ลูกศร:
    ฟังก์ชัน getVerifiedToken(selector) ( return getUsers(selector) .then(users => users) .then(verifyUser) .then((user, validToken) => validToken) .catch(err => log(err.stack)); )
    ที่นี่คุณต้องใส่ใจกับประเด็นสำคัญหลายประการ:
    • เราสูญเสียฟังก์ชันและ () เนื่องจากฟังก์ชันการโทรกลับของเราเขียนไว้ในบรรทัดเดียว
    • เราได้ลบ () แล้ว ตอนนี้พวกเขาไม่ได้ล้อมรายการอาร์กิวเมนต์เมื่อมีอาร์กิวเมนต์เดียวเท่านั้น (อาร์กิวเมนต์อื่นผ่านเป็นข้อยกเว้น เช่น (...args) => ...)
    • เรากำจัดคีย์เวิร์ด return แล้ว ด้วยการลบ () เราอนุญาตให้ฟังก์ชันลูกศรหนึ่งบรรทัดทำการส่งคืนโดยนัย (ในภาษาอื่น ๆ ฟังก์ชันดังกล่าวมักเรียกว่าฟังก์ชันแลมบ์ดา)
    ให้เรากลับมาสนใจอีกครั้ง จุดสุดท้าย- การส่งคืนโดยนัยจะเกิดขึ้นในกรณีของฟังก์ชันลูกศรบรรทัดเดียวเท่านั้น เมื่อฟังก์ชันลูกศรถูกกำหนดด้วย () แม้ว่าจะเป็นคำสั่งแยกต่างหาก ก็ไม่มีการส่งคืนโดยนัยเกิดขึ้น
    const getVerifiedToken = selector => ( return getUsers() .then(users => users) .then(verifyUser) .then((user, validToken) => validToken) .catch(err => log(err.stack)); )
    นี่คือจุดเริ่มต้นของความสนุก เนื่องจากฟังก์ชันของเรามีโอเปอเรเตอร์เพียงตัวเดียว เราจึงสามารถลบ () ออกได้ และโค้ดจะคล้ายกับไวยากรณ์ของ CoffeeScript มาก:
    const getVerifiedToken = selector => getUsers() .then(users => users) .then(verifyUser) .then((user, validToken) => validToken) .catch(err => log(err.stack));
    แต่โค้ดด้านบนเขียนโดยใช้ไวยากรณ์ ES2015 (ฉันรู้สึกประหลาดใจเช่นกันที่คอมไพล์ได้อย่างสมบูรณ์แบบ) เมื่อเราพูดถึงฟังก์ชันลูกศรด้วยคำสั่งเดียว นี่ไม่ได้หมายความว่าคำสั่งนั้นไม่สามารถกินพื้นที่มากกว่าหนึ่งบรรทัดได้ เพื่อความสะดวกในการใช้งาน

    อย่างไรก็ตาม มีข้อเสียที่สำคัญประการหนึ่ง นั่นคือ การลบ () ออกจากฟังก์ชันลูกศร เราจะคืนวัตถุว่างได้อย่างไร เช่น เหมือนกัน ()?
    const EmptyObject = () => (); วัตถุที่ว่างเปล่า(); -
    และนี่คือลักษณะของโค้ดทั้งหมดรวมกัน:
    ฟังก์ชั่น () ( return 1; ) () => ( return 1; ) () => 1 ฟังก์ชั่น (a) ( return a * 2; ) (a) => ( return a * 2; ) (a) => a * 2 a => ฟังก์ชัน a * 2 (a, b) ( ส่งคืน a * b; ) (a, b) => ( ส่งคืน a * b; ) (a, b) => ฟังก์ชัน a * b () ( อาร์กิวเมนต์ส่งคืน; ) (...args) => args () => () // ไม่ได้กำหนด () => (()) // ()

    คำศัพท์นี้ เรื่องราวที่พวกเขาพยายามแอบเข้าไปใน JavaScript ได้ถูกปกคลุมไปด้วยฝุ่นแล้ว แต่ละฟังก์ชันใน JavaScript จะกำหนดบริบทของตัวเองสำหรับสิ่งนี้ บริบทนี้หลีกเลี่ยงได้ง่ายมาก แต่ในทางกลับกัน มันน่ารำคาญอย่างยิ่ง ในตัวอย่างด้านล่าง คุณสามารถดูโค้ดสำหรับนาฬิกาที่อัปเดตข้อมูลทุกวินาทีโดยใช้ jQuery:
    $(".current-time").each(function () ( setInterval(function () ( $(this).text(Date.now()); ), 1000); ));
    เมื่อพยายามอ้างอิงสิ่งนี้ องค์ประกอบ DOMที่ระบุผ่านแต่ละรายการในการโทรกลับ setInterval น่าเสียดายที่เราได้รับสิ่งนี้ที่แตกต่างไปจากเดิมอย่างสิ้นเชิง - อันที่เป็นของการโทรกลับ คุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยการตั้งค่าตัวแปรนั้นหรือตนเอง:
    $(".current-time").each(function () ( var self = this; setInterval(function () ( $(self).text(Date.now()); ), 1000); ));
    ฟังก์ชัน Fat arrow สามารถช่วยแก้ปัญหานี้ได้เนื่องจากไม่มี:
    $(".current-time").each(function () ( setInterval(() => $(this).text(Date.now()), 1000); ));
    แล้วข้อโต้แย้งล่ะ? ข้อเสียอย่างหนึ่งของฟังก์ชันลูกศรคือไม่มีตัวแปรอาร์กิวเมนต์ของตัวเอง เหมือนกับฟังก์ชันปกติ:
    บันทึกฟังก์ชัน(msg) ( const print = () => console.log(arguments); print(`LOG: $(msg)`); ) log("hello"); // สวัสดี
    บันทึกฟังก์ชัน(msg) ( const print = (...args) => console.log(args); print(`LOG: $(msg)`); ) log("hello"); // LOG: สวัสดี แล้วเครื่องกำเนิดไฟฟ้าล่ะ? ไม่สามารถใช้ฟังก์ชันลูกศรหนาเป็นตัวสร้างได้ ไม่มีข้อยกเว้นหรือวิธีแก้ไขปัญหาเฉพาะหน้า ฟังก์ชันลูกศรอ้วนเป็นหนึ่งในเหตุผลที่ฉันชอบ JavaScript มาก เป็นเรื่องที่น่าสนใจมากที่จะเริ่มใช้ => แทนฟังก์ชั่น ฉันเคยเห็นห้องสมุดทั้งหมดที่ใช้ตัวเลือก => เท่านั้น อย่างไรก็ตาม ฉันไม่คิดว่านี่เป็นเรื่องฉลาด ท้ายที่สุดแล้ว => มีนิสัยแปลกๆ และฟังก์ชั่นที่ซ่อนอยู่มากมาย ฉันแนะนำให้ใช้ฟังก์ชันลูกศรเฉพาะในกรณีที่คุณต้องการฟังก์ชันใหม่เท่านั้น:
    • ฟังก์ชั่นที่มีคำสั่งเดียวที่ส่งคืนทันที
    • ฟังก์ชั่นที่ต้องทำงานกับสิ่งนี้ด้วยขอบเขตหลัก
    ES6 วันนี้ แล้ววันนี้คุณใช้ประโยชน์จาก ES6 ได้ไหม? การใช้ทรานสปิเลอร์กลายเป็นเรื่องปกติในช่วงไม่กี่ปีที่ผ่านมา ทั้งนักพัฒนาทั่วไปและบริษัทขนาดใหญ่ไม่ลังเลที่จะใช้สิ่งเหล่านี้

     


    อ่าน:


    ใหม่

    วิธีฟื้นฟูรอบประจำเดือนหลังคลอดบุตร:

    วิธียกเลิกการสมัครสมาชิก Megogo บนทีวี: คำแนะนำโดยละเอียด วิธียกเลิกการสมัครสมาชิก Megogo

    วิธียกเลิกการสมัครสมาชิก Megogo บนทีวี: คำแนะนำโดยละเอียด วิธียกเลิกการสมัครสมาชิก Megogo

    ลักษณะและข้อดีของบริการ Megogo หนึ่งในบริการวิดีโอที่ใหญ่ที่สุดในยุโรปตะวันออกและ CIS คือ Megogo แค็ตตาล็อกประกอบด้วยมากกว่า 80,000...

    วิธีแบ่งพาร์ติชันดิสก์โดยติดตั้ง Windows โดยไม่สูญเสียข้อมูล แบ่งพาร์ติชันดิสก์ 7

    วิธีแบ่งพาร์ติชันดิสก์โดยติดตั้ง Windows โดยไม่สูญเสียข้อมูล แบ่งพาร์ติชันดิสก์ 7

    การแบ่งฮาร์ดไดรฟ์ออกเป็นพาร์ติชั่นโดยใช้ Windows7 การแบ่งพาร์ติชั่นไดรฟ์ C:\ ใน Win7 เมื่อซื้อคอมพิวเตอร์หรือแล็ปท็อปเครื่องใหม่ที่มี...

    เหตุใดผู้จัดพิมพ์จึงไม่สามารถแก้ไขทุกหน้าได้

    เหตุใดผู้จัดพิมพ์จึงไม่สามารถแก้ไขทุกหน้าได้

    ผู้ใช้ที่ทำงานใน Microsoft Word บ่อยครั้งอาจประสบปัญหาบางอย่างเป็นครั้งคราว เราได้หารือเกี่ยวกับวิธีแก้ปัญหากับหลายๆ คนแล้ว...

    รหัสโปรโมชั่น Pandao สำหรับคะแนน

    รหัสโปรโมชั่น Pandao สำหรับคะแนน

    บางครั้งเมื่อคุณพยายามเข้าสู่ร้านค้าอย่างเป็นทางการของยักษ์ใหญ่ดิจิทัล Play Market จะเขียนเพื่อเปิดใช้งานรหัสส่งเสริมการขาย เพื่อให้ได้ความครอบคลุม...

    ฟีดรูปภาพ อาร์เอสเอส