Автор оригинала: Dario Garcia Moya.
Этот пост подразумевается в качестве второй части понимания «это» в JavaScript.
Мы пройдемся через те же примеры, но мы будем использовать функции стрелки, чтобы сравнить выходы.
Мотивация этого второго поста о объеме есть, несмотря на функции стрелки, являются мощным дополнением к ES6, они не должны быть использованы или злоупотреблены.
По умолчанию «Это» контекст
Функции стрелки не связывают свои собственные это
Вместо этого они наследуют один из родительской области, который называется «лексическим навесом». Это делает функции стрелки, чтобы быть отличным выбором в некоторых сценариях, но очень плохого в других
Если мы посмотрим на первый пример, но используя функции стрелки
// define a function const myFunction = () => { console.log(this); }; // call it myFunction();
Что мы можем ожидать это
Быть? …. Точно так же, как с нормальными функциями, окно или глобальный
объект. Тот же результат, но не та же причина. С нормальными функциями, находящимися на фоне глобального по умолчанию, стрелки функционируют, как я уже говорил, не имеют своего собственного это
Но они наследуют его от родительской области, в этом случае глобальный.
Что произойдет, если мы добавим «Используйте Strict»
? Ничего, это будет тот же результат, поскольку объем происходит от родительского.
Стрелка функционирует как методы
const myObject = { myMethod: () => { console.log(this); } };
Как насчет сейчас?
В этом случае можно сказать, что это действительно зависит от того, как называется метод, такой же, как обычные функции, но это не так здесь, давайте посмотрим …
myObject.myMethod() // this === window or global object const myMethod = myObject.myMethod; myMethod() // this === window or global object
Странно справа? Ну, помните, что функции стрелки не связывают свои собственные возможности, но наследуют его от родителя, который в этом случае является окном или глобальным объектом.
Давайте изменим пример немного
const myObject = { myArrowFunction: null, myMethod: function () { this.myArrowFunction = () => { console.log(this) }; } };
Нам нужно позвонить myobject.mymethod ()
инициализировать myobject.myarrowfunction
а затем давайте посмотрим, что будет выработка
myObject.myMethod() // this === myObject myObject.myArrowFunction() // this === myObject const myArrowFunction = myObject.myArrowFunction; myArrowFunction() // this === myObject
Яснее сейчас? Когда мы называем myobject.mymethod ()
мы инициализируем myobject.myarrowfunction
С функцией стрелки, которая находится внутри метода MyMethod
Так что это наследует свой объем. Мы можем четко видеть идеальный выбор корпуса, закрытия.
Явная, твердая и новая привязка
Что произойдет, когда мы стараемся связывать масштаб с любым из
Посмотрим…
const myMethod = () => { console.log(this); }; const myObject = {};
Явная связывание
myMethod.call(myObject, args1, args2, ...) // this === window or global object myMethod.apply(myObject, [array of args]) // this === window or global object
Твердая связывание
const myMethodBound = myMethod.bind(myObject); myMethodBound(); // this === window or global object
Новое обязательство
new myMethod(); // Uncaught TypeError: myMethod is not a constructor
Как видите, не имеет значения, как мы пытаемся связать область, оно никогда не будет работать. Кроме того, функции стрелок не конструкторы, поэтому вы не можете использовать новые с ними.
API звонки
Эта часть интересна. Функции arrow – хороший выбор для вызовов API (асинхронный код), только если мы используем замыкание, давайте посмотрим на это …
myObject = { myMethod: function () { helperObject.doSomethingAsync('superCool', () => { console.log(this); // this === myObject }); }, };
Это идеальный пример, мы просим сделать что-то Async, мы ждем ответа, чтобы выполнить некоторые действия, и нам не нужно беспокоиться о прицелах, с которыми мы работали.
Но что бы произошло, если по какой-либо причине мы рефикторуем код и извлеките, что функционируют, например, для использования повторно используются?
Посмотрим…
const reusabledCallback = () => { console.log(this); // this === window or global object }; myObject = { myMethod: function () { helperObject.doSomethingAsync('superCool', reusabledCallback); }, };
Если мы сделаем это, мы нарушили текущий рабочий код, и, помните, не имеет значения, как мы пытаемся связать масштаб, это не будет работать. Поэтому, если вы решите сделать это, вы должны использовать нормальные функции и привязывать объем вручную. Например
const reusabledCallback = function () { console.log(this); }; myObject = { myMethod: function () { helperObject.doSomethingAsync('superCool', reusabledCallback.bind(myObject)); }, };
Выводы
Функции arrow – это мощное дополнение к ES6, но мы должны быть осторожны и мудрым, когда и как их использовать. Я постоянно нахожу места, где функции со стрелками не используются, и это может заставить трудно отслеживать ошибки, особенно если мы не понимаем, как они действительно работают.
На мой взгляд, функции стрелки являются лучшим выбором при работе с закрытиями или обратными вызовами, но не хорошим выбором при работе с методами или конструкторами класса/объекта.
Снимание Есть и другие много интересных особенностей функций стрелки, как Аргументы
или Прототип
, но тема этого поста – это область или это
Отказ Для получения дополнительной информации посмотрите на Mozilla Web Docs Отказ