İşlev çağrıları
İşlevler yalnızca bir Nesne türüdür.
Tüm Function nesneleri, çağrıldıkları Function nesnesini yürüten çağrı ve uygulama yöntemlerine sahiptir.
Çağrıldığında, bu yöntemlerin ilk bağımsız değişkeni this, İşlevin yürütülmesi sırasında anahtar sözcük tarafından başvurulacak olan nesneyi belirtir - eğer , nullya undefinedda genel nesne window, için kullanılır this.
Böylece, bir Fonksiyon çağırmak ...
whereAmI = "window";
function foo()
{
return "this is " + this.whereAmI + " with " + arguments.length + " + arguments";
}
... parantez ile - foo()- eşdeğerdir foo.call(undefined)ya foo.apply(undefined)olan etkili bir aynı foo.call(window)veya foo.apply(window).
>>> foo()
"this is window with 0 arguments"
>>> foo.call()
"this is window with 0 arguments"
Ek bağımsız calldeğişkenler işlev çağrısına bağımsız değişken olarak iletilirken, tek bir ek bağımsız applydeğişken işlev çağrısının bağımsız değişkenlerini Array benzeri bir nesne olarak belirtebilir.
Böylece, veya foo(1, 2, 3)ile eşdeğerdir .foo.call(null, 1, 2, 3)foo.apply(null, [1, 2, 3])
>>> foo(1, 2, 3)
"this is window with 3 arguments"
>>> foo.apply(null, [1, 2, 3])
"this is window with 3 arguments"
Bir işlev bir nesnenin özelliğiyse ...
var obj =
{
whereAmI: "obj",
foo: foo
};
... işleve bir referansa nesne üzerinden erişmek ve onu parantez ile çağırmak - obj.foo()- foo.call(obj)veya ile eşdeğerdir foo.apply(obj).
Ancak, nesnelerin özellikleri olarak tutulan işlevler bu nesnelere "bağlı" değildir. Yukarıdaki tanımda görebileceğiniz objgibi, İşlevler yalnızca bir Nesne türü olduğundan, bunlara başvurulabilir (ve bu nedenle bir İşlev çağrısına başvurularak iletilebilir veya bir İşlev çağrısından başvuru ile döndürülebilir). Bir Fonksiyon için bir başvuru geçirilen zaman, kabul edildi hakkında ek bilgiler dan olduğunu onunla yapılır, şu olur nedenleri:
>>> baz = obj.foo;
>>> baz();
"this is window with 0 arguments"
İşlev referansımıza bazyapılan çağrı, çağrı için herhangi bir bağlam sağlamaz, bu nedenle etkili bir şekilde aynıdır baz.call(undefined), bu nedenle thisreferans alır window. Eğer bazait olduğunu bilmek istiyorsak obj, bir şekilde bazçağrıldığında bu bilgiyi sağlamalıyız ki bu ilk argüman callveya applykapanışların devreye girdiği yerdir .
Kapsam zincirleri
function bind(func, context)
{
return function()
{
func.apply(context, arguments);
};
}
Bir İşlev yürütüldüğünde, yeni bir kapsam oluşturur ve herhangi bir kapalı kapsama referans verir. Yukarıdaki örnekte anonim işlev oluşturulduğunda, oluşturulduğu kapsama, yani kapsamına bir referansı vardır bind. Bu "kapatma" olarak bilinir.
[global scope (window)] - whereAmI, foo, obj, baz
|
[bind scope] - func, context
|
[anonymous scope]
Bir değişkene erişmeye çalıştığınızda, bu "kapsam zinciri" belirtilen ada sahip bir değişken bulmak için yürür - geçerli kapsam değişkeni içermiyorsa, zincirdeki bir sonraki kapsama bakarsınız ve küresel kapsam. Anonim işlev döndürüldüğünde ve bindyürütmeyi tamamladığında, anonim işlev hala bindkapsamının başvurusuna sahiptir , bu nedenle bindkapsamı "kaybolmaz".
Yukarıdakilerin tümü göz önüne alındığında, şimdi aşağıdaki örnekte kapsamın nasıl çalıştığını ve "ön sınır" ın etrafında belirli bir değere sahip bir işlevi geçirme tekniğinin neden thisiş denildiğinde sahip olacağını anlayabilmeniz gerekir:
>>> baz = bind(obj.foo, obj);
>>> baz(1, 2);
"this is obj with 2 arguments"
var signup = { onLoadHandler:function(){ console.log(this); return Type.createDelegate(this,this._onLoad); }, _onLoad: function (s, a) { console.log("this",this); }};