ES6 Функция стрелки: почему «this» указывает по-разному при использовании в конструкторе и литерале объекта? - PullRequest
0 голосов
/ 19 апреля 2020

Я знаю, что функции стрелок наследуют this от включающей области видимости. Тем не менее, до сих пор не могу понять, почему this в функции стрелки, определенной в литерале объекта, указывает на глобальный объект, а в конструкторе - на созданный объект. Рассмотрим следующий код:

function Obj() {
  this.show = () => {
    console.log(this);
  };
}
const o = new Obj();
const o2 = {
  show: () => {
    console.log(this);
  }
}

o.show(); // o
o2.show() // window || undefinded

Ответы [ 3 ]

1 голос
/ 19 апреля 2020

Это потому, что во время объявления Object еще не инициализировано. Вы можете принудительно инициализировать с помощью выражения, вызываемого немедленно ( IIFFE ), или использовать Object.create. Что-то вроде:

// IIFE
const x = (() => ({a: 1, b: 2, sum() {return this.a + this.b}}))();
console.log(`x.sum() => ${x.sum()}`);
// Object.create
const y = Object.create({a:1, b:2, sum() {return this.a + this.b}});
console.log(`y.sum() => ${y.sum()}`);
1 голос
/ 19 апреля 2020
function Obj() {
  this.show = () => {
    console.log(this);
  };
}
const o = new Obj();
o.show(); 

Здесь «this» работает на основе правил ключевого слова «new», указывая на новый объект со структурой, определенной внутри Obj () (новый объект является контекстом). Дополнительная информация по адресу: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

const o2 = {
  show: () => {
    console.log(this);
  }
}
o2.show() // window || undefinded

Здесь «this» получает свое значение во время выполнения, и поскольку ни лямбда-функции, ни литералы объектов не определяют контекст, остающийся контекст является глобальным и именно поэтому вы получаете это значение.

1 голос
/ 19 апреля 2020

Хорошо, нашёл ответ, как сказано в «Секретах javascript ниндзя»:

Функции стрелок не имеют своего собственного контекста. Вместо этого контекст наследуется от функции, в которой они определены.

Так внутри функции конструктора this === {}. В то время как при определении объекта литерал this по-прежнему указывает на глобальный объект или undefined в строгом режиме.

...