Sıkı kullanılırken neden anonim bir işlevdeki "bu" tanımsızdır?


86

Javascript katı modda kullanılırken bu neden anonim bir işlevde tanımsızdır? Bunun neden mantıklı olduğunu anlıyorum ama somut bir cevap bulamadım.

Misal:

(function () {
    "use strict";

    this.foo = "bar"; // *this* is undefined, why?
}());

Bir kemanla test edin : http://jsfiddle.net/Pyr5g/1/ Logger'a (firebug) göz atın.


4
Bunun anonim işlevlerle ilgisi olmadığını, çağrı yöntemiyle ilgisi olduğunu unutmayın. Bu değiştirilmiş kemana bakın (konsol günlüğüne bakın).
Phrogz

@Phrogz: Bu, karışıklığın bir kısmının geldiği yer olabilir. Bunu belirttiğiniz için teşekkürler.
T. Junghans

Yanıtlar:


102

Çünkü, ECMAscript 262 sürüm 5'e kadar constructor pattern, newanahtar kelimeyi nerede kullandığını unutan kişilerin büyük bir kafa karışıklığı vardı . newES3'te bir yapıcı işlevi çağırırken kullanmayı unutursanız this, genel nesneye ( windowbir tarayıcıda) başvurursanız ve küresel nesneyi değişkenlerle bozarsınız.

Bu korkunç davranış ve ECMA insanlar karar, sadece sete thisiçin undefined.

Misal:

function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance     = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance  = myConstructor(); // oh my gosh, we just created a, and b on the window object

Son satır, ES5 katı'da bir hata atar

"TypeError: this is undefined"

(bu çok daha iyi bir davranış)


4
Bu mantıklı. İfadeyi destekleyecek bir referansınız var mı?
Rob W

1
@RobW: Kendimi araştırmam gerekirdi, ama Douglas Crockford'u birkaç kez duydum, bu kararın nedeni buydu.
jAndy

1
JavaScript'te bahsedilmiştir: Crockford tarafından The Good Parts. Ayrıntılı olarak anlatılmıştır. Yine de ECMA'nın kararı hakkında değil.
madr

1
Katı modun varsayılan olarak bunu tanımsız olarak ayarlamasının mantıksal nedeni budur. Diğer mantıksal neden verimliliktir, diğer mantıksal neden this === windowise kafa karıştırıcı ve küresel kapsamı bir belirteç olarak işlevlere
sızdırmasıdır

2
@jAndy: Cevap için teşekkürler. Bu mantıklı. Ayrıca değişikliklerin kompakt bir açıklama buldum bu üzerinde javascriptweblog.wordpress.com/2011/05/03/... : "İlk argüman arayabilir veya uygulamak için eğer En önemlisi, null veya çağrılan fonksiyonun tanımsız, bu değer genel nesneye dönüştürülmeyecektir. "
T.Junghans

15

thisÇağrılan işlevin bağlamına girmeden önce nesneyi saran veya değiştiren "kutu" adlı bir mekanizma vardır . Sizin durumunuzda, değerithisundefined , işlevi bir nesnenin yöntemi olarak çağırmadığınız için olmalıdır . Katı olmayan mod ise, bu durumda, bunun yerini windownesne alır. In strictmodunda o var, bu yüzden her zaman değişmeden var undefinedburada.

Daha fazla bilgiyi https://developer.mozilla.org/en/JavaScript/Strict_mode adresinde bulabilirsiniz.


@samuel öyleyse katı modda pencere nesnesine nasıl değişken atayabiliriz ??
Null Pointer

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.