Soru JavaScript'te “undefined” nasıl kontrol edilir? [çift]


Bu sorunun zaten bir cevabı var:

JavaScript'te bir değişken tanımlanmamışsa test etmenin en uygun yolu nedir? Birkaç olası yol gördüm:

if (window.myVariable)

Veya

if (typeof(myVariable) != "undefined")

Veya

if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?

1875
2017-08-02 17:53


Menşei


Kontrol etmek istermisin bir tek  undefinedveya null yanı sıra? - Nick Craver♦
şuna göz at stackoverflow.com/questions/27509/... - Amr Badawy
@Robert - bu sorunun cevapları yanlış olduğu kanıtlanmış bir cevabı var. - Daniel Schaffer
Görmek: Javascript'te undefined için nasıl kontrol edilir?, ve bir değişkenin tanımsız olup olmadığı ve Javascript'te "undefined" nasıl işlenir? - Shog9♦
Bu "yinelenen" nesne özellikleriyle ilgilidir, bu yüzden bazı cevaplar bu soruya çok iyi başvurmaz, değişkenler hakkında sorular sorar. - DCShannon


Cevaplar:


Bir değişkenin değerinden bağımsız olarak beyan edilip edilmediğini öğrenmek istiyorsanız, o zaman in Operatör gitmenin en güvenli yoludur. Bu örneği düşünün.

// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"

Ancak bu, bazı durumlar için amaçlanan sonuç olmayabilir, çünkü değişken veya özellik beyan edildi, ancak henüz başlatılmadı. Kullan in Daha sağlam bir kontrol için operatör.

"theFu" in window; // true
"theFoo" in window; // false

Değişkenin beyan edilip edilmediğini veya değeri olup olmadığını bilmek istiyorsanız undefinedsonra kullanın typeof Şebeke.

if (typeof myVar != 'undefined')

typeof operatörün bir dizi döndürmesi garanti edilir. Doğrudan karşılaştırmalar undefined gibi zahmetli undefined üzerine yazılabilir.

window.undefined = "omg";
"omg" == undefined // true

@CMS'nin işaret ettiği gibi, bu durum ECMAScript 5. baskıda ve undefined yazılabilir değil.

if (window.myVar) Bu falsi değerleri de içerecektir, bu yüzden çok sağlam değildir:

yanlış
0
""
NaN
boş
Tanımsız

Üçüncü vakanıza işaret etmek için @CMS'ye teşekkürler - if (myVariable) iki durumda da bir hata verebilir. Birincisi, değişkenin tanımlanmadığı zaman tanımlanmasıdır. ReferenceError.

// abc was never declared.
if (abc) {
    // ReferenceError: abc is not defined
} 

Diğer durum, değişkenin tanımlandığı, ancak çağrıldığında bir hata veren bir alıcı fonksiyonuna sahip olmasıdır. Örneğin,

// or it's a property that can throw an error
Object.defineProperty(window, "myVariable", { 
    get: function() { throw new Error("W00t?"); }, 
    set: undefined 
});
if (myVariable) {
    // Error: W00t?
}

2158
2017-08-02 17:58



@Anurag, üçüncü dava atar ReferenceError Eğer myVariable değil beyan... - CMS
@Anurag, rica ederim, çünkü ES5'ten bahsediyorsunuz, belki de undefined şimdi yazılabilir olmayan, yapılandırılamaz ve sayılmaz olarak tanımlanmıştır. Yani, window.undefined = "omg"; sessizce başarısız olur veya sıkı modda atılır. - CMS
"Typeof" yeniden tanımlanabilir mi? - CHI Coder 007
typeof bir dil ifadesidir, / else / while / for / function vb. - MooGoo
undefined içinde değişmez modern tarayıcılar. Ayar window.undefined hiç birşey yapmıyor. - Paul S.


Ben şahsen kullanıyorum

myVar === undefined

Uyarı: unutmayın ki === bitti == ve şu myVar daha önce beyan (değil tanımlanmış).


hoşlanmıyorum typeof myVar === "undefined". Bence uzun sarılmış ve gereksiz. (Aynı şeyi daha az kod ile yapabilirim.)

Şimdi bazı insanlar bunu okuduğunda acı çektiklerini söyleyerek bağırıyor: "Bekle! WAAITTT !!! undefined yeniden tanımlanabilir! "

Güzel. Bunu biliyorum. Sonra tekrar, Javascript'teki çoğu değişken yeniden tanımlanabilir. Hiçbir zaman yeniden tanımlanabilecek yerleşik bir tanımlayıcı kullanmamalısınız?

Bu kuralı takip ederseniz, sizin için iyi: ikiyüzlü değilsiniz.

Sorun şu ki, JS'de çok sayıda gerçek iş yapmak için, geliştiricilerin ne oldukları için yeniden tanımlanabilir tanımlayıcılara güvenmeleri gerekiyor. İnsanların beni kullanmamam gerektiğini söylediğini duymuyorum setTimeout çünkü birisi

window.setTimeout = function () {
    alert("Got you now!");
};

Alt satırda, ham kullanmamak için "yeniden tanımlanabilir" argümanı === undefined bogus

(Eğer hala korkuyorsan undefined Yeniden tanımlanmak, neden test edilmemiş kütüphane kodunu kod tabanına körü körüne entegre ediyorsun? Veya daha da basit: bir linting aracı.)


Ayrıca, typeof yaklaşım, bu teknik beyan edilmemiş değişkenleri "tespit edebilir":

if (window.someVar === undefined) {
    doSomething();
}

Ama her iki teknik de soyutlamalarında sızıyor. Bunu kullanmamanı tavsiye ederim hatta

if (typeof myVar !== "undefined") {
    doSomething();
}

Düşünmek:

var iAmUndefined;

Bu değişkenin bildirilip bildirilmediğini öğrenmek için in Şebeke. (Çoğu durumda, sadece O_o kodunu okuyabilirsiniz).

if ("myVar" in window) {
    doSomething();
}

Fakat bekle! Fazlası var! Ya bazı prototip zincir büyüsü oluyorsa…? Şimdi bile üstün in operatör yeterli değildir. (Tamam, bu bölüm hakkında, işin% 99’u için olduğunu söylemek dışında bitirdim. === undefined (ve **** öksürük **** typeof) gayet iyi çalışıyor. Gerçekten önemsiyorsanız, bu konu hakkında kendi başınıza okuyabilirsiniz.)


888
2017-08-02 18:26



Marjinal olarak daha muhtemel undefined Yeniden tanımlanabilir, çünkü insanlar böyle çekler için kullanırlar. Bazı insanlar sürekli olarak böyle kontroller yaparken sol tarafa sabitler: if (undefined == someVariable). Sadece sessizce yeniden tanımlamak için bir yazım hatası gerekiyor undefined: if (undefined = someVariable). - Tim Down
Bende hiç kod yazmam undefined LHS'de. Yapsam bile, kullanmam gerçeği === yerine == yazım hatası oldukça olasıdır. Ama aslında == yanlış bir endişe daha fazladır. Her durumda, böyle bir hata bulmak genellikle kolaydır. Bu böcek gibi bir şey: typeof x == "undefned". - Thomas Eding
Bu nasıl 41 kez ayrılabilir, sadece işe yaramıyor. Eğer myVar gerçekten tanımlanmamış bir kod hata atacaktır ve test etmek kolay - jsfiddle.net/WcM5g Doğru yol typeof myVar === 'undefined'. - this.lau_
@Laurent: Şaka mı? Bu, değişkenin bir şekilde ya da diğeriyle beyan edildiği varsayılmaktadır. var anahtar kelime veya bir işlev parametresi. Ruhumu satmadan önce, (herhangi bir şekilde) beyan edilmemiş değişkenler üzerinde harekete geçen kodu yazdım. Unutmayın, tanımlanmamış ve tanımlanmamış JS'deki iki farklı kavramdır. - Thomas Eding
@Andy In C (ve C ++), yazım hatalarından kaçınmak için işlenenleri tersine çevirmek için hem yaygın hem de iyi bir uygulamadır. if (NULL = myVar) derleme başarısız olur ve anında yakalanır if (myVar = NULL) etrafında başka kodun ne olduğuna bağlı olarak izlenmesi zor olabilecek bir hata oluşturur. Modern derleyiciler size bir uyarı vermelidir, ancak birçok deneyimli C programcısı siparişi değiştirmeyi alışkanlık haline getirmiştir. - GrandOpener


kullanma typeof benim tercihim. Herhangi bir karşılaştırma ile karşılaştırıldığında, değişken hiçbir zaman bildirilmediğinde çalışacaktır. == veya === operatörler veya kullanarak zorlama yazın if. (undefinedaksine nullAyrıca, ECMAScript 3 ortamlarında yeniden tanımlanabilir, bu da karşılaştırma için güvenilmez hale gelir, ancak neredeyse tüm ortak ortamlar artık ECMAScript 5 veya üstü ile uyumludur).

if (typeof someUndeclaredVariable == "undefined") {
    // Works
}

if (someUndeclaredVariable === undefined) { 
    // Throws an error
}

149
2017-08-02 18:05



Bir işlev parçasını temsil eden belirli bir global değişkenin önceden tanımlanmış olup olmadığını kontrol etmek isteyebilirsiniz. Örneğin, kütüphane kodu kütüphanenin önceden dahil edilmediğini kontrol etmek isteyebilir. - Tim Down
Pencerede 'xyz' veya kendisinde 'xyz' çok daha iyi - Jamie Pate
@JamiePate: Açık olmak gerekirse, buna katılmıyorum 'xyz' in window daha iyi bir cevaptır typeof xyz == "undefined" çünkü yanlış şeyi test ediyor. in operatör, bir mülkün varlığını, değeri ne olursa olsun kontrol eder, soru en azından bir değişkenin değerinin test edilip edilmediğini sormak ister. undefined. Belki benim seçmem için daha iyi bir örnek olurdu var foo; "foo" in window; bu süre true foo kesinlikle tanımlanmamıştır. - Tim Down
@JamiePate: Neden xyz === undefined daha iyi typeof xyz == "undefined"? Globals hakkında anlaştık, ancak ikimizin sadece özelliklerini kontrol etmeyi önerdiniz window. - Tim Down
Çoğu durumda gereksizdir (ve daha az okunabilir). Eğer xyz'nin bildirilmiş bir değişken olduğunu biliyorsanız, neden fazladan dertte geçsin? Bazı tarayıcılarda yazım denetimi ve dize karşılaştırması çok daha yavaştır, bu yüzden sıkı bir döngüde çok yaparsanız performansınızı kaybedersiniz. jsperf.com/type-of-undefined-vs-undefined/6 - Jamie Pate


Kullanmalısın typeof .

if (typeof something != "undefined") {
    // ...
}

51
2018-06-06 20:22



Ya da sadece something !== undefined, zaten yapmış olduğunuzu varsayarak var undefinedÖnceden dikkatle. - James
Şimdi tırnakları eklediğini görmek güzel. Ancak, belirtildiği gibi cevabım, katı karşılaştırmaya dikkat edin (!==bu durumda gerekli değildir typeof her zaman bir dize döndürür. - Mathias Bynens
Mathias: Burada sıkı ya da katı olmayan karşılaştırma yapmak kişisel bir zevk meselesi. Her ikisi de her zaman çalışır ve daha doğru değildir. Varsayılan konumunuzun, özellikle tip zorlama (örneğin Crockford tarafından önerildiği gibi) gerektirmedikçe veya katılık gerekmedikçe katı olmayan karşılaştırmayı kullanmayı tercih edip etmediğinize bağlı olarak her zaman sıkı karşılaştırma kullanıp kullanmayacağına bağlı olabilir. - Tim Down


Tanımlanmamışsa, dize tanımlanmamış olarak "undefined" karakterlerini içeren bir dizgeye eşit olmaz.

Değişkenin türünü kontrol edebilirsiniz:

if (typeof(something) != "undefined") ...

Bazen türü kontrol etmek zorunda bile değilsiniz. Değişkenin değeri ayarlandığında false olarak değerlendirilemezse (örneğin bir işlevse), değişkeni değerlendirebilirsiniz. Örnek:

if (something) {
  something(param);
}

20
2018-06-06 20:23



Parantezlere gerek yok: typeof operatör değil, bir işlevdir. - Tim Down
@Tim - Her iki şekilde de kullanılabilir. - Nick Craver♦
@ Tim: @Nick doğrudur. Görmek developer.mozilla.org/en/Core_Javascript_1.5_Reference/... - Mathias Bynens
Evet, bunu biliyorum Eserleri Parantez ile birlikte, parantezler burada işleneni basitçe değerlendiren ve döndüren gruplama operatörünü oluşturur. Sadece gereksiz olduklarını söyledim. - Tim Down


Çeşitli cevapların sonuçlarını gösteren bazı senaryolar: http://jsfiddle.net/drzaus/UVjM4/

(Kullanımının unutmayın var için in Kapsamlı bir sarmalayıcıda testler fark yaratır.)

Referans için kod:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

Ve sonuçları:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined

17
2018-01-13 15:39



kullanımı not undefined bir kapsam sarıcı içinde; Bu sadece (olağandışı) "oh undefined yeniden tanımlanabilir '' ama aynı zamanda 'küçültme' ile yardımcı olur. - drzaus


if (typeof foo == 'undefined') {
 // Do something
};

Katı karşılaştırmaya dikkat edin (!==bu durumda gerekli değildir typeof her zaman bir dize döndürür.


16
2018-06-06 20:26



Yarı-kolonda ne var?};)? - James
@ J-P: kapanış ayracı sonra noktalı virgül sadece boş bir ifadedir. - Gumbo
@Gumbo, üzgünüm, sormak istediğim şuydu: "Yarı kolonun amacı nedir?" - James
İşlenemeyen bir minörle karşılaşmadım if(){} olmadan ; ... Hangi minyatürleri kastediyorsunuz? Her diğer ifadeyi nasıl bitirdiğini söylüyorsun ... Bu doğru sanırım. Ancak, bir blok cümlesi {} zaten kendi başına bir ifadedir. Ekleme ; teknik olarak iki ifade yapar. Sözdizimsel, gereksiz. Otomatik yarı-kolon ekleme bile, orada bir yarım kolon eklemez ... - James
@ J-P: Sanırım okumadan yıllar önce yapmaya başladım. Packer belgeleri. Packer sonra noktalı virgül bekliyor function() {} beyanları. Haklısın - görünüşe göre gerekli değil. if ifadeler, ama bir şekilde hala mantıklı olduğunu düşünüyorum. - Mathias Bynens