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:
thisBir İşlev Çağrıldığında Neler İfade Edilir
Formun bir işlevini çağırırken foo.bar.baz(), nesneye foo.baralı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.addValuesve faynı 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 thisolması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 thisbelirtir) 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 fve obj.addValuesaynı 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 thishiçbir zaman olamaz nullveya undefinedbir işlev çağrıldığında. Tüm nullveya undefinedalı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, valuegenel 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.
aBağımsız değişken dizisi için geçerli ve bağımsız değişkencsütunları için çağrıda düşünün .