обзор
Давайте начнем с обзора основного синтаксиса функции стрелки вниз.
ES6 добавляет стрелочные функции:
let func = value => value;
эквивалентно:
let func = function (value) {
return value;
};
Если вам нужно передать несколько параметров в функцию:
let func = (value, num) => value * num;
Если блок кода функции требует нескольких операторов:
let func = (value, num) => {
return value * num
};
Если вам нужно вернуть объект напрямую:
let func = (value, num) => ({total: value * num});
В сочетании с переменной деструктуризацией:
let func = ({value, num}) => ({total: value * num})
// 使用
var result = func({
value: 10,
num: 10
})
console.log(result); // {total: 100}
Много раз вы можете не подумать об использовании этого, поэтому давайте возьмем пример.Например, при техническом выборе React и Immutable мы будем делать это при работе с событием:
handleEvent = () => {
this.setState({
data: this.state.data.set("key", "value")
})
};
На самом деле, это можно упростить до:
handleEvent = () => {
this.setState(({data}) => ({
data: data.set("key", "value")
}))
};
сравнивать
В этой статье мы сосредоточимся на сравнении стрелочных функций и обычных функций.
Ключевые отличия включают в себя:
1. без этого
В стрелочных функциях этого нет, поэтому его значение нужно определять, просматривая цепочку областей видимости.
Это означает, что если стрелочная функция содержится в нестрелочной функции, она привязывается к this ближайшей нестрелочной функции.
Чтобы смоделировать реальный пример разработки:
Наше требование — нажать кнопку и изменить цвет фона кнопки.
Чтобы облегчить разработку, мы извлекаем компонент Button, а когда его нужно использовать, напрямую:
// 传入元素 id 值即可绑定该元素点击时改变背景色的事件
new Button("button")
HTML-код выглядит следующим образом:
<button id="button">点击变色</button>
Код JavaScript выглядит следующим образом:
function Button(id) {
this.element = document.querySelector("#" + id);
this.bindEvent();
}
Button.prototype.bindEvent = function() {
this.element.addEventListener("click", this.setBgColor, false);
};
Button.prototype.setBgColor = function() {
this.element.style.backgroundColor = '#1abc9c'
};
var button = new Button("button");
Вроде проблем нет, но результат - ошибкаUncaught TypeError: Cannot read property 'style' of undefined
Это связано с тем, что при регистрации события для элемента с помощью addEventListener() значение this в функции события является ссылкой на элемент.
Итак, если мы находимся в setBgColorconsole.log(this)
, это указывает на элемент кнопки, тогда this.element не определен, и естественно сообщить об ошибке.
Вы можете спросить, поскольку все это указывает на элемент кнопки, тогда мы напрямую изменим функцию setBgColor на:
Button.prototype.setBgColor = function() {
this.style.backgroundColor = '#1abc9c'
};
Не можете решить эту проблему?
Это действительно возможно сделать, но в реальной разработке мы можем вызывать другие функции в setBgColor, например, написав это:
Button.prototype.setBgColor = function() {
this.setElementColor();
this.setOtherElementColor();
};
Так что мы все еще надеемся, что this в setBgColor указывает на объект экземпляра, чтобы можно было вызывать другие функции.
С ES5 мы обычно делаем это:
Button.prototype.bindEvent = function() {
this.element.addEventListener("click", this.setBgColor.bind(this), false);
};
Чтобы избежать влияния addEventListener, используйте привязку, чтобы заставить this из setBgColor() быть объектом экземпляра.
С ES6 мы можем решить эту проблему лучше:
Button.prototype.bindEvent = function() {
this.element.addEventListener("click", event => this.setBgColor(event), false);
};
Так как у стрелочной функции this нет, то она будет искать значение this во внешнем слое, то есть this в bindEvent.В это время this указывает на объект экземпляра, поэтому метод this.setBgColor может быть вызван корректно , и this в this.setBgColor также будет правильно указывать на экземпляр объекта.
Здесь следует упомянуть еще одну вещь: bindEvent и setBgColor используют здесь форму обычных функций, а не стрелочных функций.Если мы перейдем к стрелочным функциям, это приведет к тому, что this в функции будет указывать на объект окна (в Режим).
Наконец, поскольку в стрелочных функциях этого нет, вы не можете использовать call(), apply(), bind(), чтобы изменить точку this. Вы можете увидеть пример:
var value = 1;
var result = (() => this.value).bind({value: 2})();
console.log(result); // 1
2. Никаких аргументов
Стрелочные функции не имеют собственного объекта arguments, что не обязательно плохо, поскольку стрелочные функции имеют доступ к объекту arguments включающей функции:
function constant() {
return () => arguments[0]
}
var result = constant(1);
console.log(result()); // 1
Что, если мы просто хотим получить доступ к параметрам стрелочной функции?
Вы можете получить доступ к параметрам как к именованным параметрам или остальным параметрам:
let nums = (...nums) => nums;
3. Нельзя вызывать с новым ключевым словом
Функции JavaScript имеют два внутренних метода: [[Call]] и [[Construct]].
Когда функция вызывается через new, выполняется метод [[Construct]], создается объект экземпляра, а затем выполняется тело функции, привязывая его к экземпляру.
При прямом вызове выполняется метод [[Call]] и тело функции.
Стрелочные функции не имеют метода [[Construct]], поэтому их нельзя использовать в качестве конструкторов, при вызове через new будет выдано сообщение об ошибке.
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
4. Нет новой.цели
Также нет значения new.target, так как его нельзя вызвать с помощью new.
Для new.target вы можете обратиться кГолодание 6. Жуань Ифэн.com/#docs/class…
5. Нет прототипа
Поскольку вы не можете использовать new для вызова стрелочных функций, нет необходимости создавать прототипы, поэтому стрелочные функции не имеют свойства прототипа.
var Foo = () => {};
console.log(Foo.prototype); // undefined
6. Нет супер
Прототипа нет, и естественно через super нельзя обратиться к свойствам прототипа, поэтому у стрелочных функций тоже нет super, а вот так, аргументы, и new.target, эти значения определяются ближайшим не стрелочным функционировать на периферии.
Суммировать
Наконец, о стрелочных функциях, введение в MDN:
An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.
Это переводится как:
Выражения стрелочных функций имеют более короткий синтаксис, чем выражения функций, и не связывают собственные this, arguments, super или new.target. Эти функциональные выражения лучше всего использовать для функций, не являющихся методами, и их нельзя использовать в качестве конструкторов.
Так что же такое функции, не являющиеся методами?
Давайте сначала посмотрим на определение метода:
A method is a function which is a property of an object.
Функции в свойствах объекта называются методами, поэтому не-метод относится к функциям, которые не используются в качестве свойств объекта, но почему стрелочная функция больше подходит для не-метода?
Давайте посмотрим на пример, чтобы понять:
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log( this.i, this)
}
}
obj.b();
// undefined Window
obj.c();
// 10, Object {...}
самовыполняющаяся функция
Форма самовыполняющейся функции:
(function(){
console.log(1)
})()
или
(function(){
console.log(1)
}())
Используйте стрелки для упрощения написания самовыполняющихся функций:
(() => {
console.log(1)
})()
Но обратите внимание: использование следующего способа написания сообщит об ошибке:
(() => {
console.log(1)
}())
Почему он сообщает об ошибке? Привет, если знаешь, дай мне знать~
серия ES6
Адрес каталога серии ES6:GitHub.com/ в настоящее время имеет бриз…
Ожидается, что в серии ES6 будет написано около 20 статей, направленных на углубление понимания некоторых точек знаний ES6, с упором на область действия на уровне блоков, шаблоны меток, функции стрелок, реализацию моделирования символов, наборов, карт и обещаний, схему загрузки модулей, асинхронность. обработка и т.п. содержание.
Если есть какие-либо ошибки или неточности, пожалуйста, поправьте меня, большое спасибо. Если вам нравится или у вас есть вдохновение, добро пожаловать в звезду, что также является поощрением для автора.