--- title: Arrow functions slug: Web/JavaScript/Reference/Functions/Arrow_functions translation_of: Web/JavaScript/Reference/Functions/Arrow_functions ---
this
, arguments, super, ya da new.target erişimine sahip değildir. Bu fonksiyon tanımlaması özellikle methodsuz fonksiyonlar için çok uygundur. Constructor olarak kullanılamaz. (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 }
// 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 parametre listesi içinde de desteklenir let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
Şunu da inceleyin "ES6 In Depth: Arrow functions" on hacks.mozilla.org.
Arrow fonksiyonlarının iki dikkat çekici özelliği vardır: daha kısa fonksiyonlara ihtiyaç ve this
anahtar kelimesinin kullanımı.
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]
this
Arrow fonksiyonlara kadar, her yeni fonksiyon nasıl çağrıldığına bağlı olarak kendi this değerini belirlerdi:
Constructor durumunda yeni bir nesne.
Strict mode fonksiyon çağrılması durumunda undefined.
Eğer fonksiyon "nesne metodu" olarak çağrılmışsa temel nesne.
etc.
Bu kullanım nesne-yönelimli programla içerisinde ideal kullanım değildi.
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();
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.
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
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
Çoğu durumda rest parametreleri, arguments
nesnesinin iyi bir alternatifidir.
function foo(n) { var f = (...args) => args[0] + n; return f(10); } foo(1); // 11
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 {{jsxref("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' } });
new
operatörü kullanımı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
prototype
özelliği kullanımıArrow fonksiyonlarının prototype
özelliği yoktur.
var Foo = () => {}; console.log(Foo.prototype); // undefined
yield
anahtarının kullanımı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.
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
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});
An arrow function cannot contain a line break between its parameters and its arrow.
var func = () => 1; // SyntaxError: expected expression, got '=>'
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
// 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);
Specification | Status | Comment |
---|---|---|
{{SpecName('ES2015', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}} | {{Spec2('ES2015')}} | Initial definition. |
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.functions.arrow_functions")}}