ค่าของคีย์เวิร์ด `this` ของฟังก์ชันนี้คืนมาจาก getter


15

ฉันพบค่าที่ไม่คาดคิดของคำค้นหานี้ในตัวอย่างต่อไปนี้

let x = {
    z : 10 ,
    get func1() {
        return function(v) {
            console.log(this === v);
        }
    }
}


x.func1(x)

ค่าของคีย์เวิร์ดนี้คือ object xราวกับว่ามันถูกเรียกใช้จากอ็อบเจกต์นั้นฉันคาดหวังเฉพาะฟังก์ชัน getที่มีคีย์เวิร์ดนี้เท่ากับการเรียก object x

ตัวอย่างนี้แสดงให้เราเห็นถึงความแตกต่าง

let x = {
    func2() {
        return function(v) {
            console.log(this === v);
        }
    }
}

x.func2()(x);

ในตัวอย่างทั้งสองfunc1ซึ่งเป็นฟังก์ชั่น getter และfunc2ซึ่งเป็นวิธีการของวัตถุจะถูกดำเนินการจากวัตถุxและจากนั้นฟังก์ชั่นที่ส่งคืนจะถูกดำเนินการ ดังนั้นทำไมนี้คุ้มค่าในตัวอย่างแรกไม่เท่ากับวัตถุโลกแทนของวัตถุx


3
คำถามที่น่าสนใจจริงๆ ฉันไม่เคยคิดว่าจะมีริ้วรอยนี้มาก่อน
TJ Crowder

1
" ราวกับว่ามันถูกเรียกใช้จากวัตถุนั้น " - แต่ถูกดำเนินการบนวัตถุนั้นอยู่ที่นั่น: x.func1().
Bergi

คำตอบ:


13

นั่นเป็นคำถามที่น่าสนใจมาก

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

let x = {
    get func1() {
        return function(v) {
            console.log(this === v);
        };
    },
    func2(v) {
        console.log(this === v);
    }
};

x.func1(x);
x.func2(x);

ในทั้งสองกรณี:

  1. อ่านค่าของคุณสมบัติแล้วส่งผลให้เกิดการอ้างอิงฟังก์ชัน
  2. ฟังก์ชันนั้นถูกดำเนินการโดยเป็นส่วนหนึ่งของนิพจน์การเข้าถึงคุณสมบัติเดียวกัน

ความจริงที่ว่าfunc1เป็นคุณสมบัติ accessor และfunc2เป็นคุณสมบัติของข้อมูลไม่สำคัญ มันเป็นวิธีการที่คุณค่าที่เกิดจากการอ่านคุณสมบัติที่มีความสำคัญ


1
ฉันคิดว่าการแสดงออกทั้งหมดจะถูกประเมินเป็นวัตถุฟังก์ชั่นแล้วดำเนินการ ขอบคุณเข้าใจ
Kirollos Nasr

1
@KirollosNasr ใช่มันเป็น แต่ในการแสดงออก x.func1มันเก็บการอ้างอิงถึงxเป็นบริบทสำหรับการโทรที่ตามมาในทางตรงกันข้ามกับx.func2()(จากคำถามของคุณ) ซึ่งประเมินไปยังฟังก์ชั่นเช่นกัน แต่ไม่ได้แสดงออกการเข้าถึงสมาชิก
Bergi

1
@Bergi - ฉันคิดว่าคุณหมายถึงx.func2()(x);อะไร
TJ Crowder

1
@TJCrowder ใช่ฉันหมายถึงการแสดงออกภายในx.func1(x)และx.func2()(x)
Bergi

1
@Bergi ใช่มันมีส่วนที่ยุ่งยาก แต่ตอนนี้มันชัดเจนมากขึ้นขอบคุณ TJ Crowder และคุณ
Kirollos Nasr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.