Функция в JavaScript считается объектом первого класса. Причина такого обозначения в том, что мы можем объявить функцию, можем присвоить ее переменной и мы можем передать функцию в качестве аргумента другой функции. Как разработчики сценариев Java, мы видели несколько вариантов функций, некоторые из которых, а именно, функции обратного вызова, немедленное выполнение функций (IIFE), замыкания и т. д. называется Функция стрелки.
В основном все о стрелочной функции:
Ее синтаксис и несколько характеристик поведения, таких как:
- Как «это» ключевое слово ведет себя в контексте стрелочной функции?
- Вызов, привязка, применение с функциями стрелок
- Стрелочные функции с конструктором.
- Стрелочные функции с прототипом.
Простое выражение функции регистратора в стиле ванильного JavaScript можно записать так:
var foo= function(){ console.log("I am a traditional function"); }
Теперь давайте посмотрим на очень простую реализацию функции Arrow. Эти функции представляют собой компактную форму традиционных функций. Он захватил умы разработчиков JavaScript новой эры. Без дальнейших церемоний, давайте перейдем к синтаксису.
var foo1 = () => { console.log("Arrow function");}
Здесь мы можем наблюдать, что ключевое слово function удалено и введена стрелка. Достаточно просто и справедливо. Теперь давайте посмотрим на другой синтаксический пример функций и стрелочных функций с точки зрения сравнения.
the traditional function: var foo2= function(a,b,c){ return a+b+c; }
преобразовано в стрелку как:
var foo3= (a,b,c)=> a+b+c;
Здесь ключевое слово function удалено, оператор return удален, так как есть только один оператор, мы также можем избавиться от круглых скобок.
Если у нас есть один параметр, мы можем избавиться и от круглых скобок:
var foo= a=> a+2;
Приведенная выше функция вернет +2. Просто такой хрустящий. Вы только что заметили компактность, которую мы здесь получаем.
Важное примечание.
Если нам нужно вернуть объект, нам нужно связать его в круглых скобках. Чтобы объяснить вам, давайте посмотрим на пример:
var foo= ()=> ({name:"bhanu", age: 10});
Если мы не привяжем его в скобках-() , то получим ошибку:
Uncaught Syntax Error: Unexpected token ‘:’
Дайте нам знать больше об этих милых приятелях:
Есть несколько вещей, которые отличают стрелочные функции от традиционных:
- оператор «этот» имеет контекст, в котором определена функция стрелки.
Здесь сначала у нас есть традиционная функция с именем innerFunc, определенная внутри функции — sayName.
Оператор «This» для традиционной функции внутри функции будет указывать на «Window».
function Person() { this.name = 'Jack', this.age = 25, this.sayName = function () { // this is accessible console.log(this.age); function innerFunc() { // this refers to the global object console.log(this.age); console.log(this); } innerFunc(); } } let x = new Person(); x.sayName();
Вывод:
//25
//не определено
//Окно {}
Теперь мы видим поведение оператора this для стрелочной функции. innerFunc — это функция, определенная внутри sayName() — внешняя функция и стрелочная функция, которые мы добавляем в innerFunc, означает, что стрелочная функция будет принимать контекст innerFunc (не глобальный).
function Person() { this.name = 'Jack', this.age = 25, this.sayName = function () { console.log(this.age); let innerFunc = () => { console.log(this.age); } innerFunc(); } } const x = new Person(); x.sayName();
Вывод:
//25
//25
В методах this в стрелочных функциях принимает глобальный контекст:
Мы приводим простые примеры, чтобы показать то же самое:
var obj = { // does not create a new scope i: 10, b: () => console.log(this.i, this), c: function() { console.log(this.i, this); } } obj.b(); // prints undefined, Window {...} (or the global object) obj.c(); // prints 10, Object {...}
Другой пример в том же контексте:
'use strict'; var obj = { a: 10 }; Object.defineProperty(obj, 'b', { get: () => { console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object) return this.a + 10; // represents global object 'Window', therefore 'this.a' returns //'undefined' } }); console.log(obj.b);
Еще один простой пример, приведенный для поведения ключевого слова this в стрелочной функции как методе:
У нас есть камера объекта с ключами как цена, вес, описание — это стрелочная функция, принимающая цену и вес как строковый литерал внутри себя.
Но здесь вы увидите, что цена и вес не определены.
Почему так ?
Ключевое слово «это» здесь относится к объекту окна, и у нас нет цены и веса, определенных как часть окна, из-за чего оно принимает this.price и this.weight как неопределенные.
const cameras={ price: 200, weight:2000, description: ()=> { return `the price of camera is ${this.price}$ and weight is ${this.weight}pounds`} } console.log( cameras.description());
Вывод:
// цена камеры не определена в долларах, а вес не определен в фунтах
2. Ключевое слово this в Call-Bind и Apply — для традиционной функции показано на примере ниже:
var obj = { num: 100 } // Setting "num" on the window to show how it is NOT used. window.num = 2020; // yikes! // A simple traditional function to operate on "this" var add = function (a, b, c) { return this.num + a + b + c; } // call var result = add.call(obj, 1, 2, 3) // establishing the scope as "obj" console.log(result) // result 106 // apply const arr = [1, 2, 3] var result = add.apply(obj, arr) // establishing the scope as "obj" console.log(result) // result 106 // bind var result = add.bind(obj) // establishing the scope as "obj" console.log(result(1, 2, 3)) // result 106
ключевое слово «this» в Call-Bind и Apply — для функции стрелки показано в примере ниже:
var obj = { num: 100 } // Setting "num" on the window to show how it gets picked up. window.num = 2020; // yikes! // Arrow Function var add = (a, b, c) => this.num + a + b + c; // call console.log(add.call(obj, 1, 2, 3)) // result 2026 // apply const arr = [1, 2, 3] console.log(add.apply(obj, arr)) // result 2026 // bind const bound = add.bind(obj) console.log(bound(1, 2, 3)) // result 2026
3) Стрелочные функции нельзя использовать в качестве конструкторов.
var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor
4) Стрелочные функции не имеют свойства prototype.
var Foo = () => {}; console.log(Foo.prototype); // undefined
Это краткое введение в функции стрелок для начинающих. Опытные читатели могут ознакомиться с официальной документацией Mozilla по функциям стрелок.