В чем разница между стрелочными функциями и обычными функциями?

JavaScript

предисловие

Стрелочная функция — это часто встречающийся тестовый сайт на фронтенд-интервью. Стрелочная функция — это API ES6. Я думаю, многие знают, что, поскольку ее синтаксис более лаконичен, чем у обычных функций, она очень любима всеми. Это API, который мы использовали в нашей повседневной разработке, но большинство студентов не понимают его достаточно хорошо.Давайте подробнее рассмотрим базовый синтаксис стрелочных функций и разницу между стрелочными функциями и обычными функциями.

1. Базовая грамматика

[1.1] Определение функции

Определение стрелочных функций намного лаконичнее, чем обычные функции с точки зрения синтаксиса чисел, и стрелки разрешены в ES6.

=>
Чтобы определить стрелочные функции, стрелочные функции опускают ключевое слово function, а параметры функции помещаются в=>В предыдущих скобках тело функции следует=>после фигурных скобок.

// 箭头函数
let fun = (name) => {
    return `Hello ${name} !`;
};

// 普通函数
let fun = function (name) {
    return `Hello ${name} !`;
};

[1.2] Параметры стрелочных функций

Если стрелочная функция не имеет параметров, просто напишите пустую скобку.

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

Если стрелочная функция имеет несколько параметров, разделите параметры запятыми (,) и заключите их в круглые скобки.

// 没有参数
let fun1 = () => {
    console.log('dingFY');
};

// 只有一个参数,可以省去参数括号
let fun2 = name => {
    console.log(`Hello ${name} !`)
};

// 有多个参数,逗号分隔
let fun3 = (val1, val2, val3) => {
    return [val1, val2, val3];
};

[1.3] Тело функции стрелочной функции

Если тело функции стрелочной функции имеет только одну строку кода, она просто возвращает переменную или возвращает простое выражение JS, а фигурные скобки { } в теле функции можно опустить.

let fun = val => val;
// 等同于
let fun = function (val) { return val };

let sum = (num1, num2) => num1 + num2;
// 等同于
let sum = function(num1, num2) {
  return num1 + num2;
};

Если тело функции стрелочной функции имеет только одну строку кода, она возвращает объект, который можно записать следующим образом:

// 用小括号包裹要返回的对象,不报错
let getTempItem = id => ({ id: id, name: "Temp" });

// 但绝不能这样写,会报错,因为对象的大括号会被解释为函数体的大括号
let getTempItem = id => { id: id, name: "Temp" };

Если тело функции стрелочной функции имеет только один оператор и не требует возврата значения (чаще всего это вызов функции), вы можете добавить ключевое слово void перед оператором.

let fun = () => void doesNotReturn();

Во-вторых, разница между стрелочными функциями и обычными функциями

[2.1] Грамматика стала более лаконичной и понятной

Как видно из приведенного выше примера базового синтаксиса стрелочной функции, определение стрелочной функции намного проще, понятнее и быстрее, чем определение обычной функции.

[2.2] Стрелочные функции не имеют прототипа, поэтому и сама стрелочная функция не имеет этого​​​​​​​​​

// 箭头函数
let a = () => {};
console.log(a.prototype); // undefined

// 普通函数
function a() {};
console.log(a.prototype); // {constructor:f}

[2.3] Стрелочные функции не создают свои собственные this

У стрелочной функции нет собственного this, this стрелочной функции указывает на определение (Уведомление:Он наследуется от this первой обычной функции внешнего слоя, когда она определена, а не когда вызывается). Итак, в стрелочной функцииthis Указатель на определяется, когда он определен, и никогда не изменяется после этого.

let obj = {
  a: 10,
  b: () => {
    console.log(this.a); // undefined
    console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
  },
  c: function() {
    console.log(this.a); // 10
    console.log(this); // {a: 10, b: ƒ, c: ƒ}
  }
}
obj.b(); 
obj.c();

[2.4] call | apply | bind не может изменить точку this в стрелочных функциях

call | apply | bindЭтот метод можно использовать для динамического изменения указателя this при выполнении функции, но поскольку определение this стрелочной функции было определено и никогда не изменится. Таким образом, использование этих методов никогда не изменит функцию стрелки.thisуказывает на.

var id = 10;
let fun = () => {
    console.log(this.id)
};
fun();     // 10
fun.call({ id: 20 });     // 10
fun.apply({ id: 20 });    // 10
fun.bind({ id: 20 })();   // 10

[2.5] Стрелочные функции нельзя использовать в качестве конструкторов

Давайте сначала разберемся, что делает новый конструктор конструктора? Проще говоря, он разделен на четыре шага: ① Сначала объект будет сгенерирован внутри JS; ② Затем укажите this в функции на объект; ③ Затем выполните оператор в конструкторе; ④ Наконец, верните экземпляр объекта.

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

let Fun = (name, age) => {
    this.name = name;
    this.age = age;
};

// 报错
let p = new Fun('dingFY', 24);

[2.6] Стрелочные функции не связывают аргументы, а вместо этого используют остальные параметры... вместо объекта arguments для доступа к списку параметров стрелочных функций.

Стрелочные функции не имеют собственныхargumentsобъект. доступ в стрелочной функцииargumentsНа самом деле получается значение во внешней локальной (функции) среде выполнения.

// 普通函数
function A(a){
  console.log(arguments);
}
A(1,2,3,4,5,8);  //  [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]

// 箭头函数
let B = (b)=>{
  console.log(arguments);
}
B(2,92,32,32);   // Uncaught ReferenceError: arguments is not defined

// rest参数...
let C = (...c) => {
  console.log(c);
}
C(3,82,32,11323);  // [3, 82, 32, 11323]

[2.7] Стрелочные функции нельзя использовать в качестве функций-генераторов, а ключевое слово yield нельзя использовать.


Статья постоянно обновляется каждую неделю, вы можете искать в WeChat "Особенности интерфейса"Прочтите это в первый раз, ответьте [видео】【книги】 Получите 200 ГБ видеоматериалов и 30 книг в формате PDF.