Подтвердить что ты не робот

Функции стрелок и

Я пытаюсь использовать 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. Что я делаю неправильно?

4b9b3361

Ответ 1

Короткий ответ: 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);
  }
};

Ответ 2

Согласовано с @Sean Vieira - в этом случае 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"

Ответ 3

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

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

Ответ 4

Принятый ответ превосходный, лаконичный и ясный, но я подробно расскажу о том, что сказал Шон Виейра:

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

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

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

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

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

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

Ответ 5

Проблема заключается в том, что (MDN)

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

Функции стрелок фиксируют это значение окружающего контекста.

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

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

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