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

Что означает "this" в функциях стрелок в ES6?

В нескольких местах я читал, что ключевым отличием является то, что "this лексически привязана к функциям стрелки". Это все хорошо и хорошо, но я на самом деле не знаю, что это значит.

Я знаю, что это означает, что он уникален в пределах фигурных скобок, определяющих тело функции, но я не мог сказать вам результат следующего кода, потому что я понятия не имею, к чему относится this, если только он ссылаясь на тучную функцию стрелки.... что не кажется полезным.

var testFunction = () => { console.log(this) };
testFunction();
4b9b3361

Ответ 1

Функции стрелок захватывают значение this окружающего контекста

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

Итак, чтобы прямо ответить на ваш вопрос, this внутри вашей функции стрелки будет иметь то же значение, что и раньше, прежде чем назначить функцию стрелки.

Ответ 2

Чтобы представить большую картину, я собираюсь объяснить как динамическую, так и лексическую привязку.

Связывание динамического имени

this относится к объекту, на который вызывается метод. Это регулярно читаемое предложение на SO. Но это все еще только фраза, довольно абстрактная. Есть ли соответствующий шаблон кода для этого предложения?

Да, есть:

const o = {
  m() { console.log(this) }
}

// the important patterns: applying methods

o.m(); // logs o
o["m"](); // logs o

m - это метод, потому что он полагается на this. o.m() или o["m"]() означает m применяется к o. Эти шаблоны - это перевод Javascript на нашу знаменитую фразу.

Существует еще один важный шаблон кода, на который вы должны обратить внимание:

"use strict";

const o = {
  m() { console.log(this) }
}

// m is passed to f as a callback
function f(m) { m() }

// another important pattern: passing methods

f(o.m); // logs undefined
f(o["m"]); // logs undefined

Он очень похож на предыдущий шаблон, только скобки отсутствуют. Но последствия значительны: когда вы передаете m функции f, вы вытаскиваете m своего объекта/контекста o. Теперь он выкорчеван и this ничего не означает (предполагается строгий режим).

Лексическая (или статическая) привязка имени

Функции стрелок не имеют привязки this/super/arguments. Они наследуют их от родительской лексической области:

const toString = Object.prototype.toString;

const o = {
  foo: () => console.log("window", toString.call(this)),
      
  bar() {
    const baz = () => console.log("o", toString.call(this));
    baz();
  }
}

o.foo() // logs window [object Window]
o.bar() // logs o [object Object]

Ответ 3

Надеюсь, что это показание кода может дать вам более четкую идею. В принципе, 'this' в функции стрелок есть текущая версия контекста 'this'. Смотрите код:

// 'this' in normal function & arrow function
var this1 = {
    number: 123,
    logFunction: function () { console.log(this); },
    logArrow: () => console.log(this)
};
this1.logFunction(); // Object { number: 123}
this1.logArrow(); // Window 

Ответ 4

Функция стрелки this указывает на окружающий родительский элемент в Es6, означает, что он не имеет области видимости, как анонимные функции в ES5...

Это очень полезный способ избежать присвоения var self этому, который широко используется в ES5...

Посмотрите пример ниже, назначив функцию внутри объекта:

var checkThis = {
  normalFunction: function () { console.log(this); },
  arrowFunction: () => console.log(this)
};

checkThis.normalFunction(); //Object {}
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}

Ответ 5

Вы можете попытаться понять это, следуя ниже.

// whatever here it is, function or fat arrow or literally object declare
// in short, a pair of curly braces should be appeared here, eg:
function f() {
  // the 'this' here is the 'this' in fat arrow function below, they are
  // bind together right here
  // if 'this' is meaningful here, eg. this === awesomeObject is true
  console.log(this) // [object awesomeObject]
  let a = (...param) => {
    // 'this is meaningful here too.
    console.log(this) // [object awesomeObject]
}

поэтому 'this' в функции стрелки жира не привязана, значит вы не можете сделать что-либо привязанным к 'this' здесь,.apply не будет,.call не будет,.bind не будет. 'this' в функции жирной стрелки привязывается при записи текста кода в текстовом редакторе. 'this' в функции толстой стрелки здесь буквально значима. Что ваш код писать здесь, в текстовом редакторе, то, что ваше приложение работает там в repl. Что 'this' связанное с оберткой жира никогда не изменится, если вы не измените его в текстовом редакторе. Извините за мой пул English...

Ответ 6

В другом примере, если вы нажмете кнопку возраста ниже

<script>
var person = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: function() {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

var person2 = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: () => {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

</script>



<input type=button onClick="alert(person2.age());" value="Age">

это вызовет исключение, подобное этому

× Ошибка JavaScript: Uncaught TypeError: Невозможно прочитать свойство 'getFullYear' с неопределенным значением в строке 18

Но если вы измените person2 эту строку

return new Date().getFullYear() - this.dob.getFullYear(); 

в

return new Date().getFullYear() - person2.dob.getFullYear();

это будет работать, потому что эта область изменилась в person2