Значення ключового слова `this` функції, поверненого від геттера


15

Я знайшов несподіване значення цього ключового слова в наступному прикладі:

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


x.func1(x)

Значення цього ключового слова - це об'єкт x, як ніби він виконаний з цього об’єкта, я очікую, що лише функція get , у якої це ключове слово, дорівнює виклику об'єкта 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().
Бергі

Відповіді:


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є власністю доступу та func2є властивістю даних, не має значення. Важливим є те, як використовується значення, отримане при читанні властивості.


1
Я думав, що весь вираз буде оцінено об'єктом функції і потім виконаний. Спасибі отримали
Кіроллос Наср

1
@KirollosNasr Так, але в виразі x.func1він зберігає посилання на xконтекст для наступного виклику, на відміну від x.func2()(з вашого запитання), який також оцінює функцію, але не є виразом доступу до члена.
Бергі

1
@Bergi - я думаю, ти мав на увазі x.func2()(x);?
TJ Crowder

1
@TJCrowder Так, я посилаюся на вирази всередині x.func1(x)іx.func2()(x)
Бергі

1
@Bergi так, це складна частина. Але тепер це зрозуміліше Завдяки TJ Crowder і вам
Кіроллос Наср
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.