ECMA 5 referansının açıklığa kavuşturulması gerekiyor.
ECMA-262 Edition 5 anlamına geldiğini varsayıyorum. ECMA-262'nin (diğer adıyla ECMAScript veya daha az doğru olarak Javascript) İnternet Tarayıcılarında uygulanan genel bir komut dosyası dili olduğu unutulmamalıdır . Sürüm 5.1 standardından:
Aşağıdaki adımlar, denetim F işlev nesnesinde bulunan işlev kodu için yürütme bağlamına girdiğinde, thisArg sağlanan bir çağırıcı ve argumentsList sağlayan bir çağırıcı tarafından gerçekleştirilir:
- İşlev kodu katı kodsa, ThisBinding'i thisArg olarak ayarlayın.
- ThisArg null veya undefined ise, ThisBinding'i genel nesneye ayarlayın.
- Aksi takdirde, Type (thisArg) Object değilse, ThisBinding'i ToObject (thisArg) olarak ayarlayın.
- Else ThisBinding'i thisArg olarak ayarlayın
- ... ("bu" hakkında değil)
"Global nesne" terimi, kapsam zincirinin tepesindeki nesneyi ifade eder. Tarayıcılar için bu "pencere" nesnesi olabilir, ancak bu bir uygulama seçeneğidir (Windows Komut Dosyası Ana Bilgisayarı görünmez bir genel nesneye sahiptir ancak katı modu yoktur, bu nedenle niteliksiz referanslar özelliklerine erişir ve genel "kendilik" yoktur). Ayrıca, "katı mod" açıkça etkinleştirilmelidir, aksi takdirde aktif değildir (standardın 14.1 bölümü). Bu nedenle, tanımlanmamış bir "bu", katı mod etkin olmayan "ECMA 5 "'teki genel nesneye (pencere) hala çözümlenecektir.
Yani sorunun cevabı şu:
"bu" her zaman işlevi çağıran nesneyi ifade eder. İşlev bir nesne tarafından çağrılmadıysa (yani bir yöntem çağrısı değil), "bu" (işleve iletildiği şekliyle) "tanımsız" dır. Bununla birlikte, katı modu KULLANMAZSA, global nesne olarak tanımlanmamış bir "bu" ayarlanır (yukarıdaki kural 2).
"ben" in özel bir sözdizimsel anlamı yoktur, sadece bir tanımlayıcıdır. Tarayıcılar window.self (yalnızca global pencere nesnesinin bir özelliği) = window tanımlama eğilimindedir. Bu, "kendilik" ifadesinin, "pencere" DEĞİL "öz" ile aynı olan niteliksiz referansların, kapsayıcı bir kapsam dahilinde yeniden tanımlanmasına neden olur (yukarıdaki "var self = this;" tarafından olduğu gibi. "Bunu" yeniden tanımlarken iyi şanslar.)
Yani yukarıdaki örneğin tam açıklaması şu şekildedir:
outer func: this.foo = bar
// "this" refers to the invoking object "myObject"
outer func: self.foo = bar
// "self" resolves to the variable in the local scope which has been set to "this" so it is also "myObject"
inner func: this.foo = undefined
// "this" refers to the invoking object (none) and so is replaced by the global object (strict mode must be off). "window" has no foo property so its "value" is undefined.
inner func: self.foo = bar
// self resolves to the variable in the enclosing scope which is still "myObject"
Örneğin ilginç bir varyasyonu, iç işleve bir referans döndürerek bir kapanış yaratır.
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
return function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
};
}
};
var yourObject = {
foo: "blat",
func: myObject.func() // function call not function object
};
console.log("----");
yourObject.func();
üreten
outer func: this.foo = bar
outer func: self.foo = bar
----
inner func: this.foo = blat
inner func: self.foo = bar
YourObject tarafından çağrılana kadar iç işlevin nasıl çağrılmadığına dikkat edin. Yani this.foo artık yourObject.foo'dur, ancak self hala kapsama alanındaki değişkene çözümlenir, bu değişken iç işlev nesnesi döndürüldüğünde (ve sonuçta sonuçta hala myObject'tir). Dolayısıyla, iç işlev içinde, "bu" iç işlevi çağıran nesneyi ifade ederken, "öz", iç işleve referans oluşturmak için dış işlevi çağıran nesneyi ifade eder.
Özetin özetini özetlemek gerekirse, "bu" dil standardı tarafından tanımlanır, "öz" onu tanımlayan kişi tarafından tanımlanır (çalışma zamanı uygulayıcısı veya son programlayıcı).