Soru Tanımlanmamış bir nesne özelliğini algılama


JavaScript'teki bir object özelliğinin tanımsız olup olmadığını kontrol etmenin en iyi yolu nedir?


2434
2017-08-26 07:25


Menşei




Cevaplar:


kullanın:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Bazı özelliklere sahip bir nesne değişkeni ile aynı şeyi kullanabilirsiniz:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

ECMAScript 5'ten beri undefined üzerine yazılamıyor, yani my_obj === undefined de çalışırdı, ama sadece my_obj bulunmaktadır. Bu da istenebilir çünkü siz de kullanabilirsiniz null bu semantiğe ihtiyacınız varsa (bkz. JavaScript'te null ve undefined arasındaki fark nedir?). Ancak, nesne özellikleri için, özellik var olup olmadığına bakılmaksızın çalışır.


2321
2018-01-06 12:27



Eğer bir şey boş ise, tanımlanır (null olarak), ancak çok çekleri birleştirebilirsiniz. Yukarıdaki kodun can sıkıcı detayı, kontrol etmek için bir fonksiyon tanımlayamamanızdır, iyi fonksiyon tanımlayabilirsiniz ... ama kullanmaya çalışın. - neu-rah
@ neu-rah neden bir işlev yazamıyorsun? neden böyle bir şey yapmıyor? Benim için çalışıyor gibi görünüyor. Düşünmediğim bir dava var mı? jsfiddle.net/djH9N/6 - Zack
@Zack isNullorUndefined için yaptığınız testler, NullOrUndefined (f) ve f'nin bildirilmediği (örn. "Var f" bildiriminin olmadığı durumlarda) durumu dikkate almadı. - pnkfelix
Blah, şimdi binlerce oy. Bunu yapmanın en kötü yolu budur. Umarım bu yorumu görür ve kontrol etmeye karar veririm… ahem… diğer cevapları. - Ry-♦
Sadece kullanabilirsiniz obj !== undefined şimdi. undefined eskiden olduğu gibi undefined = 1234 ilginç sonuçlara ne sebep olur. Ancak, ECmascript 5'ten sonra artık yazılabilir değil, daha basit bir sürümü kullanabiliriz. codereadability.com/how-to-check-for-undefined-in-javascript - Bruno Buccolo


Bu konuya bir takım yanlış cevaplar olduğuna inanıyorum. Ortak inanışın aksine, "tanımlanmamış" değil JavaScript’te bir anahtar kelime ve aslında ona atanmış bir değere sahip olabilir.

Doğru Kod

Bu testi gerçekleştirmenin en sağlam yolu:

if (typeof myVar === "undefined")

Bu her zaman doğru sonucu verecektir ve hatta durumu nerede ele alır myVar beyan edilmiyor.

Bozuk kod. KULLANMAYIN.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Bunlara ek olarak, myVar === undefined myVar'ın bildirilmemiş olduğu durumlarda bir hata oluşturur.


805
2017-08-23 18:03



MyVar === undefined değerinin, myVar'ın bildirilmemiş olması durumunda bir hata oluşturacağını bildiren +1 - Enrique
evet - QUOTES görünüşte hayati. benim tahminim typeof fonksiyonu bir dize (beklenen format) döndürür - jsh
Kullanılmadığı için burada verilen ilk gerekçeyi buluyorum. === undefined şaşırtıcı. Evet, atayabilirsiniz undefinedama bunu yapmak için geçerli bir sebep yok ve bunu yapmanın kodunuzu kırması öngörülebilir. C’de yapabilirsiniz #define true falseve Python’da True ve FalseAncak, insanlar bu kodları kendi dillerinde, kendi ortamlarının başka bir yerinde kasten sabote etme olasılığına karşı korunacak şekilde tasarlama gereği duymazlar. Neden atama olasılığı vardır? undefined burada düşünmeye bile değer mi? - Mark Amery
Marks yorumlarına ek olarak, bunu anlamadım: "myVar === undefined, myVar'ın bildirilmediği durumlarda bir hata oluşturacaktır." - bu neden kötü? Neden yapayım değilbeyan edilmeyen değişkenlere başvurursam bir hata mı vermek istiyorum? - eis
Modern tarayıcılarda (FF4 +, IE9 +, Chrome bilinmeyen) artık değişiklik yapmak mümkün değil undefined. MDN: tanımsız - Stijn


JavaScript'te var boş ve orada Tanımsız. Farklı anlamları var.

  • Tanımsız değişken değerinin tanımlanmadığı anlamına gelir; değerin ne olduğu bilinmemektedir.
  • boş değişken değerinin tanımlandığı ve null olarak ayarlandığı anlamına gelir (değeri yoktur).

Marijn Haverbeke, özgür, çevrimiçi kitabında şöyle demektedir:Elverişli JavaScript"(vurgu benim):

Benzer bir değer de vardır, null, anlamı 'bu değer tanımlanmıştır, fakat bir değeri yoktur'. Undefined ve null arasındaki anlam farkı çoğunlukla akademikdir ve genellikle çok ilginç değildir. Pratik programlarda, genellikle 'bir değere sahip' olup olmadığını kontrol etmek gereklidir. Bu durumlarda, == undefined ifadesi kullanılabilir; çünkü, tam olarak aynı değer olmasalar bile, null == undefined doğru olur.

Yani, bir şey undefined olup olmadığını kontrol etmenin en iyi yolu sanırım:

if (something == undefined)

Bu yardımcı olur umarım!

Düzenle: Düzenlemenize yanıt olarak, nesne özellikleri aynı şekilde çalışmalıdır.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

133
2017-08-26 07:36



eğer (bir şey == undefined) daha iyi yazılmışsa (bir şey === undefined) - Sebastian Rittau
Bunun tamamen güvenli olmadığı belirtilmelidir. undefined kullanıcı tarafından yeniden atanabilen bir değişkendir: yazma undefined = 'a'; Kodunuzun artık yaptığınızı düşündüklerini yapmasına neden olur. kullanma typeof daha iyidir ve aynı zamanda bildirilmemiş olan değişkenler (sadece özellikler değil) için de çalışır. - Gabe Moothart
Eğer bir şey tanımlanmamış global bir değişken ise, (bir şey == undefined) javascript hatası getirir. - Morgan Cheng
Buradaki problem, eğer var = null ise, o zaman == undefined, bir kesinlikle tanımlanmış olsa bile, doğru olarak değerlendirilir. - Andrew
"Eloquent Javascript" yorumunun bu yorumu geriye. Eğer gerçekten tanımlanmamış kontrol etmek istiyorsanız, önerilen kod işe yaramayacaktır (aynı zamanda tanımlanmış olan koşulu saptayacaktır fakat henüz bir değer henüz belirlenmemiştir [i.e.null]) bir boş değer. Önerilen kod "if (bir şey == undefined) ..." kontrol ediyor her ikisi de undefined ve null (no set set), yani "eğer ((bir şey tanımlanmamış) VEYA (bir şey boştur)) olarak yorumlanır." ... Yazarın söylediği şey genellikle bu Gerçekten mi istemek için kontrol etmektir her ikisi de undefined ve null. - Chuck Kollars


Diğer birçok yanıtın şiddetle tavsiye edilmesine rağmen, typeof  kötü bir seçim. Değişkenlerin değere sahip olup olmadığını kontrol etmek için asla kullanılmamalıdır. undefinedÇünkü değer için birleşik kontrol görevi görür undefined ve bir değişkenin var olup olmadığı. Vakaların büyük çoğunluğunda, bir değişkenin var olduğunu ve typeof Değişken adında veya dize değişmezinde bir yazım hatası yaparsanız sessiz bir başarısızlık olasılığını sunar 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Dolayısıyla, özellik tespiti yapmıyorsanız, belirli bir ismin kapsamda olup olmayacağı konusunda belirsizlik (kontrol etme gibi) typeof module !== 'undefined' bir CommonJS ortamına özgü kodda bir adım olarak), typeof değişkende kullanıldığında zararlı bir seçimdir ve doğru seçenek değeri doğrudan karşılaştırmaktır:

var foo = …;

if (foo === undefined) {
    ⋮
}

Bu konuda bazı yaygın yanlış kavramlar şunlardır:

  • “başlatılmamış” bir değişkenin okunması (var foo) veya parametre (function bar(foo) { … }, Olarak adlandırılan bar()) başaramayacak. Bu doğru değildir - açık başlatma olmadan değişkenler ve değerler verilmeyen parametreler her zaman undefinedve her zaman kapsam dahilindedir.

  • o undefined üzerine yazılabilir. Bunun için daha fazlası var. undefined JavaScript’te bir anahtar kelime değil. Bunun yerine, Tanımsız değeri olan genel nesnenin bir özelliğidir. Ancak, ES5'ten bu yana, bu özellik Sadece oku ve yapılandırılamayan. Modern bir tarayıcıya izin vermez undefined Mülkiyet değişecek ve 2017 yılı itibariyle bu uzun zaman oldu. Sıkı modun eksikliği etkilemez undefinedDavranışı ya da sadece undefined = 5 Atmak yerine hiçbir şey yapmayın. Ancak bir anahtar kelime olmadığından, şunları yapabilirsiniz: bildirmek isimle değişkenler undefinedve bu değişkenler değiştirilebilirdi, bu da bir kez yaygın olan deseni oluşturuyordu:

    (function (undefined) {
        // …
    })()
    

    Daha küresel kullanmaktan daha tehlikeli undefined. ES3 uyumlu olmanız gerekiyorsa, değiştirin undefined ile void 0 - başvurma typeof. (void her zaman herhangi bir işlenenin Tanımsız değerini değerlendiren tek bir operatördür.)

Değişkenler bu şekilde nasıl işlediklerinde, asıl soruyu ele alma zamanı geldi: nesne özellikleri. Hiç kullanmak için bir sebep yok typeof nesne özellikleri için. Özellik algılama ile ilgili daha önceki istisna burada geçerli değildir - typeof yalnızca değişkenler üzerinde özel davranışı ve nesne özelliklerine referans veren ifadelerin değişken olmadığını belirtir.

Bu:

if (typeof foo.bar === 'undefined') {
    ⋮
}

olduğu her zaman tam olarak eşdeğer Buna:

if (foo.bar === undefined) {
    ⋮
}

ve okuyucuyu neden kullandığınız konusunda kafa karıştırmamak için yukarıdaki tavsiyeyi dikkate alarak typeofÇünkü kullanımı en mantıklı === Eşitliği kontrol etmek, çünkü bir değişkenin değerini daha sonra kontrol etmek için tekrar gözden geçirilebildiğinden ve sadece daha iyi göründüğünden her zaman kullanmalısın === undefined³ burada da.

Nesne özelliklerine geldiğinde dikkat etmeniz gereken başka bir şey gerçekten kontrol etmek isteyip istemediğinizdir. undefined hiç Bir nesne üzerinde belirli bir özellik adı yok olabilir (değeri üreten undefined Okuduğunda), nesnenin kendisiyle birlikte değerde bulunur. undefinedNesnenin prototipinde değeri ile mevcut undefinedya da olmayanundefined değer. 'key' in obj bir anahtarın bir nesnenin prototip zincirinde herhangi bir yer olup olmadığını söyler ve Object.prototype.hasOwnProperty.call(obj, 'key') doğrudan nesne üzerinde olup olmadığını söyleyecektir. Bu cevabın prototipleri ve cisimlerle anahtarlanmış haritalar olarak kullanılmasıyla ilgili ayrıntılara girmeyeceğim, çünkü çoğunlukla asıl sorunun olası yorumlarına bakılmaksızın diğer cevaplardaki tüm kötü tavsiyelere karşı koyma amaçlıdır. Üzerinde okumak MDN'de nesne prototipleri daha fazlası için!

Variable örnek değişken adı olağandışı seçim? Bu, Firefox için NoScript uzantısından gerçek ölü koddur.
² genel olarak kapsamda ne olduğunu bilmemekle birlikte, genel olarak iyi değil. Dinamik kapsamın kötüye kullanılmasının neden olduğu bonus açığı: Proje Sıfır 1225
³ bir kez daha ES5 + ortamını ve varsayarak undefined ifade eder undefined genel nesnenin özelliği. vekil void 0 aksi takdirde.


132
2018-02-26 21:17



@BenjaminGruenbaum Doğru ama tamamen yanıltıcı. Varsayılan olmayan herhangi bir içerik kendi tanımını yapabilir undefinedvarsayılan olanı saklıyor. En pratik amaçlar için hangisinin üzerine yazmayla aynı etkiye sahiptir. - blgt
Blgt Bu pratik bir şey için paranoyak ve alakasız. Her içerik, konsol.log'u geçersiz kılabilir, Dizi prototip yöntemlerini yeniden tanımlayabilir ve hatta Function.prototype.call 'un çengel işlevini geçersiz kılabilir ve JavaScript'te bir işlevi çağırdığınızda her seferinde değişiklik yapabilir. Buna karşı korumak çok paranoyak ve oldukça aptalcadır. Ben de dediğim gibi (ve minitech) void 0 undefined karşı tekrar karşılaştırmak - bu aptal ve overkill. - Benjamin Gruenbaum
Keşke vermek için birden fazla vesile olsaydı. Bu en doğru cevaptır. Gerçekten görmek istemiyorum typeof something === "undefined")  kod içinde. - Simon Baumgardt-Wellander
@BenjaminGruenbaum Tembel programcılar için, void 0 (bir kerede) hem daha kısa ve daha güvenli! Bu benim kitabımda bir kazan. - wizzwizz4


Ne anlama geliyor: "tanımsız nesne özelliği"?

Aslında iki farklı şey anlamına gelebilir! İlk olarak, bu demek olabilir hiç tanımlanmamış mülk nesnede ve ikinci olarak, undefined değeri olan özellik. Bu koda bakalım:

var o = { a: undefined }

o.a Tanımsız? Evet! Onun değeri undefined. mı o.b Tanımsız? Emin! Hiç bir 'b' özelliği yok! Tamam, her iki durumda da farklı yaklaşımların nasıl davrandığını görün:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Bunu açıkça görebiliyoruz typeof obj.prop == 'undefined' ve obj.prop === undefined eşdeğerdir ve bu farklı durumları ayırt etmezler. Ve 'prop' in obj Bir özellik hiç tanımlanmadığında ve tanımlanamayan özellik değerine dikkat etmediğinde durumu tespit edebilir.

Peki ne yapmalı?

1) Bir mülkün birinci veya ikinci anlamıyla tanımlanıp tanımlanmadığını bilmek istiyorsunuz (en tipik durum).

obj.prop === undefined // IMHO, see "final fight" below

2) Nesnenin bir özelliği olup olmadığını ve değerini önemsemediğini bilmek istersiniz.

'prop' in obj

Notlar:

  • Bir nesneyi ve mülkünü aynı anda kontrol edemezsiniz. Örneğin, bu x.a === undefined veya bu typeof x.a == 'undefined' yükseltmeler ReferenceError: x is not defined x tanımlanmamışsa.
  • Değişken undefined küresel bir değişkendir (yani aslında window.undefined tarayıcılarda). ECMAScript 1st Edition'dan beri ve ECMAScript 5'ten beri desteklenmiştir. Sadece oku. Yani modern tarayıcılarda bu olamaz doğru olarak yeniden tanımlandı Birçok yazar bizi korkutmaktan hoşlanıyor, ancak bu eski tarayıcılar için hala geçerli.

Son mücadele: obj.prop === undefined vs typeof obj.prop == 'undefined'

Artıları obj.prop === undefined:

  • Biraz daha kısa ve biraz daha güzel görünüyor
  • Eğer yanlış yazdıysanız JavaScript motoru size bir hata verecektir. undefined

Kötüler obj.prop === undefined:

  • undefined eski tarayıcılarda geçersiz kılınabilir

Artıları typeof obj.prop == 'undefined':

  • Bu gerçekten evrensel! Yeni ve eski tarayıcılarda çalışır.

Kötüler typeof obj.prop == 'undefined':

  • 'undefned' (yanlış yazılmış) Burada sadece bir dize sabit, bu yüzden ben sadece yaptım gibi yanlış yazdıysanız JavaScript motoru size yardımcı olamaz.

Güncelle (sunucu tarafı için JavaScript):

Node.js genel değişkeni destekliyor undefined gibi global.undefined ('global' öneki olmadan da kullanılabilir). Sunucu tarafı JavaScript'in diğer uygulamaları hakkında bilmiyorum.


101
2017-08-08 20:28



@Bergi yorumunuz için teşekkür ederim. Cevabımı düzelttim. Benim savunmamda bunu şu anda söyleyebilirim (v.0.10.18 itibariyle) resmi Node.js belgeleri hakkında hiçbir şey söylemiyor undefined üyesi olarak global. Ayrıca ne de console.log(global); ne de for (var key in global) { ... } göstermiyor Tanımsız üyesi olarak global. Ama sınamak gibi 'undefined' in global tersini göster. - Konstantin Smolyanin
O zamandan beri ekstra belgelere gerek yoktu EcmaScript özelliğinde, aynı zamanda diyor ki [[Enumerable]] yanlış :-) - Bergi
ilişkin Minuses of typeof obj.prop == 'undefined'olarak yazarak bu önlenebilir typeof obj.prop == typeof undefined. Bu da çok güzel bir simetri verir. - hlovdal
@hlovdal: Bu tamamen anlamsız obj.prop === undefined. - Ry-♦
Soru manşetine doğru olduğumuzda “algılama undefined özelliğiilk cümlede (farklı ve çok daha kolay) soruya (doğru değil mi kontrol edin ...) cevap vermezseniz if ('foo' in o)… Cevabınız gerçekten burada ilk doğru cevaptır. Hemen hemen herkes bu cümleyi cevaplıyor. - Frank Nocke


Sorun üç duruma düşüyor:

  1. Nesne özelliği vardır ve değeri değil undefined.
  2. Nesnenin özelliği var ve değeri undefined.
  3. Nesnenin özelliği yok.

Bu bize önemli gördüklerimi anlatıyor:

Tanımlanmamış bir üye ile tanımsız bir değere sahip tanımlanmış bir üye arasında bir fark vardır.

Ama ne yazık ki typeof obj.foo Bize sahip olduğumuz üç davadan hangisini söylemez. Bununla birlikte bunu birleştirebiliriz "foo" in objVakaları ayırt etmek.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Bu testler için aynı olan null girişler de

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Bazı durumlarda, mülkün orada olup olmadığını kontrol etmenin daha açık (ve daha net) olduğunu söyleyemiyorum, undefined olup olmadığını kontrol etmek ve bu kontrolün farklı olacağı tek durum, durum 2, nadir durumdur. Tanımlanmamış bir değere sahip nesnede gerçek bir giriş.

Örneğin: Bir nesnenin belirli bir mülk sahibi olup olmadığını kontrol eden bir grup kodun sadece yeniden kodlanmasını sağlıyorum.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Undefined için bir çek yazmadan daha net olanı.

if( "x" in blob ) { fn(blob.x); }

Ancak bahsettiğimiz gibi bunlar tam olarak aynı değil (ama ihtiyaçlarım için yeterince iyi).


59
2018-06-08 04:04



Merhaba Michael. Büyük öneri ve bence işleri daha temiz hale getiriyor. Ancak bulduğum bir tutam, onu kullanırken! "in" ile operatör. Söylemelisin if (!("x" in blob)) {} içeride parantez ile, çünkü! operatörün 'in' üzerinde önceliği vardır. Umarım birisine yardım eder. - Simon East
Özür dilerim Michael, ama bu asıl sorunun ışığında yanlış veya en azından yanıltıcıdır. 'in', bir object özelliğinin undefined tipinin olup olmadığını sınamak için yeterli bir yol değildir. Kanıt için lütfen şu keman'a bakın: jsfiddle.net/CsLKJ/4 - Tex
Bu iki kod parçası farklı bir şey yapıyor! Düşün ve nesneyle verilen a = {b: undefined}; sonra typeof a.b === typeof a.c === 'undefined' fakat 'b' in a ve !('c' in a). - mgol
+1. OP, mülkün var olup olmadığını ve değeri olup olmadığını netleştirmez Tanımsızveya mülkün kendisinin tanımlanmamış olup olmadığı (yani mevcut değil). - RobG
İlk tablonuzda (2) noktasını değiştirmenizi öneririm { x : undefined } ya da en azından bunu (2.) 'e başka bir alternatif olarak ekleyelim - bu noktayı değerlendirmek için bir an düşünmeliydim (2.) undefined (Daha sonra belirtmekle birlikte). - mucaho


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

Bu diğerleri benim için çalıştı, diğerleri için yoktu.


38
2017-07-27 16:03



Tipik bir operatör olduğu için parenler gereksizdir - aehlke
Ama kontrol edilen şeyi daha net hale getiriyorlar. Aksi halde şu şekilde okunabilir: typeof (something == "undefined"). - Abhi Beckert
Parantezlere ihtiyacınız varsa, JS'de operatör önceliğini öğrenmelisiniz: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Ian
Parantez tam olarak yararlıdır çünkü JS'de operatör önceliğini öğrenmenize gerek yoktur, ayrıca gelecekteki bakım programcılarının JS'de operatör önceliğini öğrenmesi gerekip gerekmediğini tahmin etmeniz gerekir. - DaveWalley
Parantez şeyleri açıklığa kavuşturmak için yararlıdır. Fakat bu durumda operatör sadece bir işlev gibi görünürler. Hiç şüphesiz, bu programcının amacını açıklığa kavuşturuyor. Ancak operatör önceliğinden emin değilseniz, yazmayı (typeof something) === "undefined". - Robert


Kullanmanın kaynağını nereden bilmiyorum === ile typeof geldim, ve bir kütüphane olarak birçok kütüphanede kullanıldığını görüyorum, ama typeof operatörü bir string literal döndürüyor ve biz bunu biliyoruz, öyleyse neden burayı da kontrol etmek istiyorsunuz?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

33
2017-09-22 14:20



Harika nokta Eric. Kontrol türünden de bir performans artışı var mı? - Simon East
@Simon: Tam tersine - '===' durumunda zorlamadan kaçınmak için hafif bir performans beklenebilir. Hızlı ve kirli test '===', FF5.0.1 altında '==' değerinden% 5 daha hızlıdır. - Antony Hatchkins
Daha kapsamlı bir test FF, IE ve Chrome '==' altında '===' (% 5-10) 'dan daha hızlı veya daha az olduğunu gösterdi ve Opera hiç bir fark yaratmadı: jsperf.com/triple-equals-vs-twice-equals/6 - Antony Hatchkins
kullanma == hala gerektirir en azından bir tür kontrolü - yorumlayıcı, türlerini ilk önce bilmeden iki işleneni karşılaştıramaz. - Alnitak
== daha az karakter === :) - svidgen