This translation is incomplete. Please help translate this article from English.
this
, arguments, super, yada new.target erişimine sahip değildir. Bu fonksiyon tanımlaması özellikle methodsuz fonksiyonlar için çok uygundur. Constructor olarak kullanılamaz.Söz Dizimi
Temel Söz Dizimi
(param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression // buna eşittir: (param1, param2, …, paramN) => { return expression; } // Eğer tek parametre var ise parantezsiz kullanılabilir: (singleParam) => { statements } singleParam => { statements } singleParam => expression // Parametre beklenmeyen durumlarda parantez çifti kullanılmalıdır () => { statements }
İleri Düzey Söz Dizimi
// Parantez çifti kullanılarak obje tipi veri dönüşü yapılır. params => ({foo: bar}) // Rest parameters ve default parameters desteklenmektedir (param1, param2, ...rest) => { statements } (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } // Destructuring within the parameter list is also supported let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
Description
See also "ES6 In Depth: Arrow functions" on hacks.mozilla.org.
Arrow fonksiyonlarının iki dikkat çekici özelliği vardır. Kısa elden kullanımı ve this
bağlamını içermemesi.
Kısa fonksiyonlar
var materials = [ 'Hydrogen', 'Helium', 'Lithium', 'Beryllium' ]; materials.map(function(material) { return material.length; }); // [8, 6, 7, 9] materials.map((material) => { return material.length; }); // [8, 6, 7, 9] materials.map(({length}) => length); // [8, 6, 7, 9]
No separate this
Arrow fonksiyonlara kadar her yeni fonksiyonlar kendi this
değerini tanımlardı (constructor durumda yeni nesne, strict mode kullanımda undefined, objeye ait metot olarak tanımlanırsa temel nesne, vs). Bu yapı nesne yönelimli programlama tarzına uygun olmadığını kanıtladı.
function Person() { // The Person() fonksiyonu kendini temsil eden this değerini oluşturuyor this.age = 0; setInterval(function growUp() { // non-strict modda, growUp() fonksiyonuda her fonksiyon gibi // kendi this değerini tanımlar // bu sayede bir üstteki this değerine artık ulaşamıyor oluruz this.age++; //bu işlem Person() fonksiyonundaki age değerine işlemez. }, 1000); } var p = new Person();
ECMAScript 3/5'te bu this
sorunu this değerinin başka bir değişkene atanarak aşılabilmekteydi.
function Person() { var that = this; that.age = 0; setInterval(function growUp() { // 'that' bir üstteki this değerine etki eder. that.age++; }, 1000); }
Alternatif olarak, bound function tanımlaması yaparak önceden atanmış this
değeri growUp()
fonksiyonuna bu işlevi kazandırabilir.
Fakat arrow fonksiyonlar kendi this
değerine sahip değildir; kapsayıcı yürütme fonksiyonunun this
değeri kullanılır. Böylelikle aşağıdaki örnekte olduğu gibi setInterval
'e atanmış arrow fonksiyon kendi this
değeri olmadığı için Person()
fonksiyonunun this değerine etki eder.
function Person(){ this.age = 0; setInterval(() => { this.age++; // |this| person objesine atıfta bulunur }, 1000); } var p = new Person();
Strict mode ile ilişkisi
Kapsayıcı sözcüksel bağlamından gelen this
değeri, strict mode kuralları uygulandığında görmezden gelinir
var f = () => { 'use strict'; return this; }; f() === window; // or the global object
Diğer strict mode kuralları normal olarak geçerlidir.
Invoked through call or apply
Arrow fonksiyonların this
değeri olmadığı için, call()
ve apply()
methotları sadece parametre verilebilir. thisArg
görmezden gelinir.
var adder = { base: 1, add: function(a) { var f = v => v + this.base; return f(a); }, addThruCall: function(a) { var f = v => v + this.base; var b = { base: 2 }; return f.call(b, a); } }; console.log(adder.add(1)); // This would log to 2 console.log(adder.addThruCall(1)); // This would log to 2 still
No binding of arguments
Arrow functions do not have their own arguments
object. Thus, in this example, arguments
is simply a reference to the the arguments of the enclosing scope:
var arguments = [1, 2, 3]; var arr = () => arguments[0]; arr(); // 1 function foo(n) { var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n return f(10); } foo(1); // 2
In most cases, using rest parameters is a good alternative to using an arguments
object.
function foo(n) { var f = (...args) => args[0] + n; return f(10); } foo(1); // 11
Arrow functions used as methods
As stated previously, arrow function expressions are best suited for non-method functions. Let's see what happens when we try to use them as methods:
'use strict'; var obj = { 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 {...}
Arrow functions do not have their own this
. Another example involving Object.defineProperty()
:
'use strict'; var obj = { a: 10 }; Object.defineProperty(obj, 'b', { get: () => { console.log(this.a, typeof this.a, this); return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined' } });
Use of the new
operator
Arrow functions cannot be used as constructors and will throw an error when used with new
.
var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor
Use of prototype
property
Arrow functions do not have a prototype
property.
var Foo = () => {}; console.log(Foo.prototype); // undefined
Use of the yield
keyword
The yield
keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.
Function body
Arrow functions can have either a "concise body" or the usual "block body".
In a concise body, only an expression is specified, which becomes the explicit return value. In a block body, you must use an explicit return
statement.
var func = x => x * x; // concise body syntax, implied "return" var func = (x, y) => { return x + y; }; // with block body, explicit "return" needed
Returning object literals
Keep in mind that returning object literals using the concise body syntax params => {object:literal}
will not work as expected.
var func = () => { foo: 1 }; // Calling func() returns undefined! var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name
This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo
is treated like a label, not a key in an object literal).
Remember to wrap the object literal in parentheses.
var func = () => ({foo: 1});
Line breaks
An arrow function cannot contain a line break between its parameters and its arrow.
var func = () => 1; // SyntaxError: expected expression, got '=>'
Parsing order
Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.
let callback; callback = callback || function() {}; // ok callback = callback || () => {}; // SyntaxError: invalid arrow-function arguments callback = callback || (() => {}); // ok
More examples
// An empty arrow function returns undefined let empty = () => {}; (() => 'foobar')(); // Returns "foobar" // (this is an Immediately Invoked Function Expression // see 'IIFE' in glossary) var simple = a => a > 15 ? 15 : a; simple(16); // 15 simple(10); // 10 let max = (a, b) => a > b ? a : b; // Easy array filtering, mapping, ... var arr = [5, 6, 13, 0, 1, 18, 23]; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] // More concise promise chains promise.then(a => { // ... }).then(b => { // ... }); // Parameterless arrow functions that are visually easier to parse setTimeout( () => { console.log('I happen sooner'); setTimeout( () => { // deeper code console.log('I happen later'); }, 1); }, 1);
Specifications
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Arrow Function Definitions' in that specification. |
Standard | Initial definition. |
ECMAScript Latest Draft (ECMA-262) The definition of 'Arrow Function Definitions' in that specification. |
Draft |
Browser compatibility
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 45 | Yes | 221 2 | No | 32 | 10 |
Trailing comma in parameters | 58 | ? | 52 | No | 45 | ? |
Feature | Android webview | Chrome for Android | Edge mobile | Firefox for Android | Opera Android | iOS Safari | Samsung Internet |
---|---|---|---|---|---|---|---|
Basic support | 45 | 45 | Yes | 221 2 | 32 | 10 | 5.0 |
Trailing comma in parameters | 58 | 58 | ? | 52 | 45 | ? | 7.0 |
1. The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of 'use strict';
is now required.
2. Prior to Firefox 39, a line terminator (\n
) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like () \n => {}
will now throw a SyntaxError
in this and later versions.