Closure: The Definitive Guide'dan Michael Bolin'den bir alıntı izliyor . Biraz uzun görünebilir, ancak çok fazla içgörü ile doyurulur. "Ek B. Sık Yanlış Anlaşılan JavaScript Kavramları" ndan:
this
Bir İşlev Çağrıldığında Neler İfade Edilir
Formun bir işlevini çağırırken foo.bar.baz()
, nesneye foo.bar
alıcı denir. İşlev çağrıldığında, aşağıdakiler için değer olarak kullanılan alıcıdır this
:
var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {
for (var i = 0; i < arguments.length; i++) {
this.value += arguments[i];
}
return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);
Bir işlev çağrıldığında açık alıcı yoksa, global nesne alıcı olur. "Goog.global" sayfa 47 bölümünde açıklandığı gibi, bir web tarayıcısında JavaScript yürütüldüğünde pencere genel nesnedir. Bu bazı şaşırtıcı davranışlara yol açar:
var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN
Olsa obj.addValues
ve f
aynı işleve bakın onlar alıcısının değeri her çağrısında farklı olduğu için çağrıldığında farklı davranır. Bu nedenle, atıfta bulunan bir işlevi çağırırken , çağrıldığında doğru değere sahip this
olmasını sağlamak önemlidir this
. Açıkça söylemek gerekirse this
, işlev gövdesinde referans verilmemişse, davranışı f(20)
ve obj.addValues(20)
aynı olacaktır.
İşlevler JavaScript'te birinci sınıf nesneler olduğu için kendi yöntemlerine sahip olabilirler. Tüm fonksiyonlar yöntemler vardır call()
ve apply()
bu mümkün (yani, nesne alıcı yeniden tanımlama için yapmak this
belirtir) işlevini çağıran zaman. Yöntem imzaları aşağıdaki gibidir:
/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;
Not arasındaki tek fark, call()
ve apply()
ki call()
, oysa tek tek, bağımsız değişken olarak işlev parametreleri alır apply()
tek bir dizi olarak alır:
// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);
Aşağıdaki çağrılar eşdeğerdir f
ve obj.addValues
aynı işleve başvurur:
obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);
Bununla birlikte, belirtilmediğinde alıcı argümanının yerini almak için kendi alıcısının değerini ne call()
de ne de apply()
kullandığından, aşağıdakiler çalışmaz:
// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);
Değeri this
hiçbir zaman olamaz null
veya undefined
bir işlev çağrıldığında. Tüm null
veya undefined
alıcıdan olarak temin edilir call()
ya da apply()
küresel bir amacı yerine alıcı değeri olarak kullanılır. Bu nedenle, önceki kod, value
genel nesneye adlı bir özellik eklemek için aynı istenmeyen yan etkiye sahiptir .
Bir fonksiyonun, kendisine atanan değişken hakkında hiçbir bilgiye sahip olmadığını düşünmek yararlı olabilir. Bu, işlev tanımlandığından ziyade işlev çağrıldığında bunun değerinin bağlanacağı fikrinin güçlendirilmesine yardımcı olur.
Ekstraktın sonu.
a
Bağımsız değişken dizisi için geçerli ve bağımsız değişkenc
sütunları için çağrıda düşünün .