Стрелочная функция это синтаксический сахар?
Т.к. стрелочная функция была добавлена из-за двух вещей:
- Более короткий синтаксис
- Лексика this
А .bind(this) работает идентично стрелочной функции, то стрелочная функция это синтаксический сахар?
const logSeparator = function() {
console.log(this.separator);
}
const enumeration = function(el) {
console.log(this.group + ': ' + el);
logSeparator.call(this)
};
const obj = {
group: 'Garvard',
separator: '-----------------',
names: ['Pavel', 'John', 'Oleg'],
func: function() {
this.names.forEach(enumeration.bind(this));
},
};
obj.func();
Ответы (1 шт):
Краткий ответ - нет. Стрелочная функция не является синтаксическим сахаром.
Подробный ответ - посмотрите определение синтаксического сахара в википедии.
Синтаксический сахар (англ. syntactic sugar) в языке программирования — это синтаксические возможности, применение которых не влияет на поведение программы, но делает использование языка более удобным для человека. Это может быть любой элемент синтаксиса, который даёт программисту альтернативный способ записи уже имеющейся в языке синтаксической конструкции, и при этом является более удобным, или более кратким, или похожим на другой распространённый способ записи, или помогает писать программы в хорошем стиле.
В нем четко написано, что синтаксические конструкции не влияют на поведение программы. Но в случаи с стрелочными функциями это не так. Стрелочная функция имеет ряд отличий и соответственно является отдельным элементом языка, а не сахаром.
- Поведение this внутри стрелочной функции отличается от поведения this внутри обычной функции. Внутри обыкновенной функции значение this динамическое (в зависимости от контекста исполнения). Но значение this внутри стрелочной функции всегда эквивалентно значения this внешней функции.
- Внутри тела обыкновенной функции, существует специальный массив arguments содержащий список аргументов с которым функция была вызвана. В стрелочных функциях отсутствует специальное слово arguments. Точно так же, как и со значение this массив arguments для стрелочных функций будет браться из внешней функции.
- В отличии от обычных функций, стрелочные функции не могут быть использованы как конструктор, их нельзя использовать с new
- Стрелочные функции не могут быть использованы как function declaration, только function expresion
Стрелочная функция это лямбда выражение и соответственно это отдельная часть языка. Она существует не только в js, но в других языках.
Стоит отметить, что в самих стрелочных функциях много синтаксического сахара. Например, эти варианты описания функции являются эквивалентными.
(x) => (x);
x => x;
(x) => {
return x;
}
Более того, на уровне движка V8 эти функции имеют разную реализацию. Если запустить node с параметром --allow-natives-syntax и определить там стрелочную и обычную функции, а потом вывести информацию о них с помощью команды %DebugPrint , то можно увидеть, что обе функции имеют type: JS_FUNCTION_TYPE, но сорт(kind) у них разный: ArrowFunction и NormalFunction.
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> a = function(a) {return a;}
[Function: a]
> %DebugPrint(a)
DebugPrint: 00000230DF378041: [Function] in OldSpace
- map: 0x01423ca015e1 <Map(HOLEY_ELEMENTS)> [FastProperties]
- prototype: 0x0230df34c071 <JSFunction (sfi = 000000890BD85C11)>
- elements: 0x03b1dd341309 <FixedArray[0]> [HOLEY_ELEMENTS]
- function prototype:
- initial_map:
- shared_info: 0x030814adec99 <SharedFunctionInfo a>
- name: 0x03b1dd348f71 <String[1]: #a>
- builtin: CompileLazy
- formal_parameter_count: 1
- kind: NormalFunction
- context: 0x0230df341139 <NativeContext[256]>
- code: 0x02655ec03f01 <Code BUILTIN CompileLazy>
- source code: (a) {return a;}
- properties: 0x03b1dd341309 <FixedArray[0]>
- All own properties (excluding elements): {
000003B1DD344D41: [String] in ReadOnlySpace: #length: 0x00890bd81499 <AccessorInfo> (const accessor descriptor), location: descriptor
000003B1DD344ED1: [String] in ReadOnlySpace: #name: 0x00890bd81429 <AccessorInfo> (const accessor descriptor), location: descriptor
000003B1DD344229: [String] in ReadOnlySpace: #arguments: 0x00890bd81349 <AccessorInfo> (const accessor descriptor), location: descriptor
000003B1DD3444C9: [String] in ReadOnlySpace: #caller: 0x00890bd813b9 <AccessorInfo> (const accessor descriptor), location: descriptor
000003B1DD3451B9: [String] in ReadOnlySpace: #prototype: 0x00890bd81509 <AccessorInfo> (const accessor descriptor), location: descriptor
}
- feedback vector: feedback metadata is not available in SFI
000001423CA015E1: [Map]
- type: JS_FUNCTION_TYPE
- instance size: 64
- inobject properties: 0
- elements kind: HOLEY_ELEMENTS
- unused property fields: 0
- enum length: 0
- callable
- constructor
- has_prototype_slot
- back pointer: 0x03b1dd341599 <undefined>
- prototype_validity cell: 0x00890bd815e9 <Cell value= 1>
- instance descriptors (own) #5: 0x0230df342611 <DescriptorArray[5]>
- prototype: 0x0230df34c071 <JSFunction (sfi = 000000890BD85C11)>
- constructor: 0x03736df74471 <JSFunction Function (sfi = 0000035D0E0F9D79)>
- dependent code: 0x03b1dd341239 <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
- construction counter: 0
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> a = (x) => x
[Function: a]
> %DebugPrint(a)
DebugPrint: 000000330CFF8E61: [Function] in OldSpace
- map: 0x014e067013a1 <Map(HOLEY_ELEMENTS)> [FastProperties]
- prototype: 0x0140acd8c071 <JSFunction (sfi = 000002E5EFCC5C11)>
- elements: 0x013673781309 <FixedArray[0]> [HOLEY_ELEMENTS]
- function prototype: <no-prototype-slot>
- shared_info: 0x00330cfec789 <SharedFunctionInfo a>
- name: 0x013673788f71 <String[1]: #a>
- builtin: CompileLazy
- formal_parameter_count: 1
- kind: ArrowFunction
- context: 0x0140acd81139 <NativeContext[256]>
- code: 0x0240c9ac3f01 <Code BUILTIN CompileLazy>
- source code: (x) => x
- properties: 0x013673781309 <FixedArray[0]>
- All own properties (excluding elements): {
0000013673784D41: [String] in ReadOnlySpace: #length: 0x02e5efcc1499 <AccessorInfo> (const accessor descriptor), location: descriptor
0000013673784ED1: [String] in ReadOnlySpace: #name: 0x02e5efcc1429 <AccessorInfo> (const accessor descriptor), location: descriptor
}
- feedback vector: feedback metadata is not available in SFI
0000014E067013A1: [Map]
- type: JS_FUNCTION_TYPE
- instance size: 56
- inobject properties: 0
- elements kind: HOLEY_ELEMENTS
- unused property fields: 0
- enum length: 0
- callable
- back pointer: 0x013673781599 <undefined>
- prototype_validity cell: 0x02e5efcc15e9 <Cell value= 1>
- instance descriptors (own) #2: 0x0140acd81c51 <DescriptorArray[2]>
- transitions #2: 0x031cf20270f9 <TransitionArray[6]>Transition array #2:
000002CB726F4A29: [String] in OldSpace: #options: (transition to (const data field, attrs: [WEC]) @ Class(0000004FFC504689)) -> 0x004ffc5046d1 <Map(HOLEY_ELEMENTS)>
0x013673785df9 <Symbol: Symbol.toPrimitive>: (transition to (const data field, attrs: [WEC]) @ Any) -> 0x014e067365d9 <Map(HOLEY_ELEMENTS)>
- prototype: 0x0140acd8c071 <JSFunction (sfi = 000002E5EFCC5C11)>
- constructor: 0x013673781319 <null>
- dependent code: 0x013673781239 <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
- construction counter: 0