Функции стрелок и это [дубликаты]

На этот вопрос уже есть ответ:

Методы в объектах ES6: использование функций стрелок 4 ответа

Я пробую ES6 и хочу добавить свойство в мою функцию, например, так

var person = {
  name: "jason",

  shout: () => console.log("my name is ", this.name)
}

person.shout() // Should print out my name is jason

Однако когда я запускаю этот код, консоль только записывает в журналmy name is. Что я делаю не так

 jason32801 мар. 2015 г., 20:59

Ответы на вопрос(5)

где функция стрелки определена, а не тем, где она используется.

Такthis ссылается на глобальный / оконный объект, если не заключен в другое пространство имен

MDN)

Выражение функции стрелки [...] лексически связывает значение this.

ункции @Arrow фиксируют значение this окружающего контекста.

Поэтому значениеthis в этой функции будет значениеthis где вы создаете литерал объекта. Возможно, это будетwindow в нестрогом режиме иundefined в строгом режиме.

Чтобы исправить это, вы должны использовать обычную функцию:

var person = {
  name: "jason",
  shout: function(){ console.log("my name is ", this.name) }
}
person.shout();

лаконичен и ясен, но я немного поясню, что сказал Шон Виейра:

ункции @Arrow вообще не имеют этих аргументов или других специальных имен.

Потому что функция стрелки не имеет «this», она использует родительское «this». «this» всегда указывает на родителя, а родителем объекта person является Window (если вы находитесь в браузере).

Чтобы доказать это, запустите это в своей консоли:

var person = {
    name: "Jason",
    anotherKey: this
}
console.log(person.anotherKey)

Вы получите объект Window.

Я считаю, что это действительно полезный способ думать об этом. Это не совсем полная история, поскольку то, что является «этим» литерала объекта, является другим обсуждением.

 yehonatan yehezkel25 июн. 2018 г., 19:04
Brilliant - я пытаюсь понять, почему это происходит так много времени !!!!
Решение Вопроса

this указывает на ближайшую границуthis - в предоставленном кодеthis находится во вложенной области видимости.

Более длинный ответ: функции стрелок связать ихthis когда они будут созданы не имеюthis, arguments или другие специальные имена, связанныевообщ - когда объект создается, имяthis находится в области видимости, а неperson объект. Вы можете увидеть это более четко, переместив объявление:

var person = {
  name: "Jason"
};
person.shout = () => console.log("Hi, my name is", this);

И еще яснее при переводе в смутное приближение синтаксиса стрелок в ES5:

var person = {
  name: "Jason"
};
var shout = function() {
  console.log("Hi, my name is", this.name);
}.bind(this);
person.shout = shout;

В обоих случаях,this (для функции крика) указывает на ту же область, что иperson определяется в, а не в новой области, к которой присоединяется функция при добавлении вperson объект.

Выне могу заставить функции стрелок работать таким образом, но, как указывает @kamituel в его ответ, тыможе воспользуйтесь более коротким шаблоном объявления метода в ES6, чтобы получить аналогичную экономию пространства:

var person = {
  name: "Jason",
  // ES6 "method" declaration - leave off the ":" and the "function"
  shout() {
    console.log("Hi, my name is", this.name);
  }
};
 jason32801 мар. 2015 г., 21:09
Благодарность. Теперь я понимаю проблему!
 Mickey Perlstein04 авг. 2016 г., 14:42
arrow функции называются лямбда-выражениями
 zowers29 мая 2017 г., 12:50
сылка @getify неактивна, ее можно посмотреть по адресу Web.archive.org / веб / 20160625172303 / HTTP: //blog.getify.com/..

this привязан к глобальному объекту (или, как указано в комментарии, в более общем смысле к ограждающей области видимости).

Если вы хотите использовать более короткий синтаксис, есть еще один вариант - расширенные объектные литералы поддерживают короткий синтаксис для функций свойств.this будет связан, как вы ожидаете там. Видетьshout3():

window.name = "global";

var person = {
    name: "jason",

    shout: function () {
        console.log("my name is ", this.name);
    },
    shout2: () => {
        console.log("my name is ", this.name);
    },
    // Shorter syntax
    shout3() {
        console.log("my name is ", this.name);
    }
};

person.shout();  // "jason"
person.shout2(); // "global"
person.shout3(); // "jason"
 Oriol01 мар. 2015 г., 21:11
Подтверждено, но обратите вниманиеthis не обязательно будет глобальным объектом.
 kamituel01 мар. 2015 г., 21:15
@ Oriol true, отметил - я предположил, что это код верхнего уровня. Благодарность
 A.B01 мар. 2015 г., 21:15
отличный (Y) @ камитуэль

Ваш ответ на вопрос