JavaScript boş kontrolü


170

Aşağıdaki kod rastladım:

function test(data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

JavaScript için biraz yeniyim, ancak burada okuduğum diğer sorulardan, bu kodun çok mantıklı olmadığı izlenimi altındayım.


Özellikle, bu cevap belirtiyor

Dışında herhangi bir bağlamda tanımlanmamış bir değişkene erişirseniz hata alırsınız typeof.

Güncelleme: Yukarıdaki (alıntı) cevabı yanıltıcı olabilir. Bu demeliyim «bildirilmemiş bir değişkeni» yerine, «tanımlanmamış bir değişkene» .

Bildiğim gibi, Ryan ♦ , maerics ve nwellnhof'un cevaplarında , bir işleve hiçbir argüman verilmemiş olsa bile, argümanları için değişkenleri her zaman bildirilir. Bu gerçek, aşağıdaki listedeki ilk öğenin de yanlış olduğunu kanıtlamaktadır.


Anladığım kadarıyla, aşağıdaki senaryolar yaşanabilir:

  • İşlev bağımsız değişken olmadan çağrıldı, böylece datatanımsız bir değişken oluşturuldu ve bir hata oluştu data != null.

  • İşlev, bağımsız değişkeni olarak null(veya undefined) ile çağrıldı , bu durumda data != nulliç kodu zaten korur ve && data !== undefinedişe yaramaz hale getirir .

  • İşlev null olmayan bir argümanla çağrıldı, bu durumda önemsiz bir şekilde hem data != null ve hem de geçecek data !== undefined.

S: Anladığım doğru mu?


Firefox'un konsolunda aşağıdakileri denedim:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

Ben dava çözemiyorum data !== undefined sonra data != null herhangi bir kullanım olabilir.


9
Sadece kullan if (data). dataDeğişkenin true olarak değerlendirilip değerlendirilmediğini kontrol etmenin anımsatıcı Javascript yolu . undefined,, nullfalse, 0, boş dize, boş dizi ve hiçbir özelliği olmayan (?) nesnesi false olarak değerlendirilir, gerisi doğrudur.
J0HN

20
@ J0HN - Kullanması if(data), geçemeyeceği falseveya 0değer olarak vereceği anlamına gelir data.
techfoobar

@ J0HN Ayrıca, bahsettiğim aynı cevap şunları da belirtir:, if(typeof someUndefVar == whatever) -- worksve if(someUnderVar) -- error.
afsantos

2
Muhtemelen olması gerekiyordu data !== null && data !== undefinedeşdeğer olan data != nulleşdeğerdir hangi data != undefined. O koşulları hakkında daha açık olduğu gibi her iki olduğunu gözden kaçırmak kolay olurdu oysa eski form tercih edilme eğilimi nullve undefineddaha sonra iki koşullarla kontrol ediliyor.
15'te zzzzBov

2
Bu arada, açık testler undefinedIMO bir kod kokusudur. Bu, korumalı bir anahtar kelime değil null, tanımlanmamış bir değişkendir. Bu tamamen geçerli ve kodunuzu kıracak:undefined = 1
Izkata

Yanıtlar:


106

Bir "tanımsız değişken" değerden farklı undefined.

Tanımlanmamış bir değişken:

var a;
alert(b); // ReferenceError: b is not defined

Şu değere sahip bir değişken undefined:

var a;
alert(a); // Alerts “undefined”

Bir işlev bağımsız değişken aldığında, bu bağımsız değişken değeri olsa bile her zaman bildirilir undefinedve bu nedenle herhangi bir hata olmaz. Haklısınız yaklaşık edilir != null, ardından !== undefinedda, işe yaramaz olmak.


32
data !== null && data !== undefinedolsa mantıklı olurdu.
bfavaretto

@bfavaretto: Evet, aslında bir yazım hatası olabilir. Ama asla bilemezsin…: D
Ry-

1
Tam düşündüğüm gibi, açıklama için teşekkürler. Ayrıca, bunun bir yazım hatası olduğunu sanmıyorum. Komut dosyasında bir bul ve say çalıştırdım ve 10 kez bulundu, yani ... Sanırım yazarın da bu konuda açıklığa ihtiyacı var.
afsantos

2
Aslında: Yukarıdaki yorumumu kaşı data != nullhem kontrol ediyorum nullve undefined(ilginçtir, ama sadece için, nullve undefined, ve diğer falsy değerleri).
bfavaretto

90

JavaScript'te, null"değer yok" sinyali vermek için yararlı olan özel bir singleton nesnesidir. Karşılaştırma yaparak test edebilirsiniz ve JavaScript'te her zamanki gibi, ===tip zorlamayı karıştırmak için operatörü kullanmak iyi bir uygulamadır :

var a = null;
alert(a === null); // true

@Rynah'ın belirttiği gibi, "tanımsız" JavaScript'te biraz kafa karıştırıcı. Ancak, typeof(x)"x" bildirilmiş bir değişken olmasa bile, "tanımsız" dizesinin olup olmadığını test etmek her zaman güvenlidir :

alert(typeof(x) === 'undefined'); // true

Ayrıca, değişkenler başlatılmazlarsa "tanımlanmamış değere" sahip olabilirler:

var y;
alert(typeof(y) === 'undefined'); // true

Hepsini bir araya getirmek, çekiniz şöyle görünmelidir:

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

Ancak, "data" değişkeni her zaman biçimsel bir işlev parametresi olduğu için tanımlandığından, "typeof" operatörünü kullanmak gereksizdir ve doğrudan "tanımsız değer" ile güvenle karşılaştırabilirsiniz.

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

Bu snippet, "işlev tanımlanmış ve boş olmayan bir argümanla çağrılmışsa ..."


5
Neden gerektiğini olsa, böyle bakmak? ve != nulldışındaki tüm değerler için geçerli olacaktır nullve undefinedbu değişkenin bildirildiğinden eminiz. typeofdiğer durumlarda bile tehlikeli olabilir - ya değişken adını yanlış yazarsanız? Uzun süre farkedilmeyebilir çünkü hata yoktur.
Ry-

Doğru cevap izledi eğer @maerics Yani, yukarıdaki senaryoda gibi boş çek, kullanmak olmaz !=hiç, sadece sıkı bir karşılaştırma, !==?
afsantos

@rynah: OP'nin bir boş testin uygun olup olmadığını bilmek için genel çözümü hakkında yeterince bilgi sahibi olduğumu sanmıyorum ama "typeof" kullanmanın gereksiz olduğu gerçeğinden bahsetmek için düzenleme yaptım.
maerics

@afsantos: gerçekte pek çok (herhangi bir?) değerin null değerine dönüşeceğini sanmıyorum; ancak, ===ne yaptığınızı gerçekten bilmiyorsanız ve dönüşümden ( ==) sonra karşılaştırma istemiyorsanız, sıkı karşılaştırma ( ) kullanmak en iyi uygulamadır .
maerics

1
@Izkata: Yeniden tanımlamaya çalışan tüm kitaplıkları bırakın undefined. Ayrıca, iPad'deki Safari bunu hiçbir koşulda yapmaz. Yapamazsın bile delete window.undefined.
Ry-

10

Sizin durumunuzda data==null(SADECE null ve undefined için geçerlidir - ikinci resim satırlara / sütunlara null-undefined üzerine odaklanır)

Burada hepsi var ( src ):

Eğer

resim açıklamasını buraya girin

== (olumsuzlaması ! = )

resim açıklamasını buraya girin

=== (olumsuzlaması ! == )

resim açıklamasını buraya girin


8

S: İşlev bağımsız değişken olmadan çağrıldı, böylece veri tanımsız bir değişken haline getirildi ve verilerde hata oluştu! = Null.

C: Evet, datatanımsız olarak ayarlanacak. Bkz. Bölüm 10.5 Spesifikasyonun Beyan Bağlama Örneği . Ancak tanımsız bir değere erişmek bir hata oluşturmaz. Muhtemelen bunu katı modda bildirilmemiş bir değişkene erişmekle karıştırıyorsunuz, bu da bir hataya neden oluyor.

S: İşlev bağımsız değişken olarak null (veya undefined) ile çağrıldı, bu durumda data! = Null zaten iç kodu korur ve && data! == undefined işe yaramaz hale getirir.

S: İşlev null olmayan bir argümanla çağrıldı, bu durumda önemsiz bir şekilde hem veriyi geçirecek! = Null hem de veri! == tanımsız.

C: Doğru. Aşağıdaki testlerin eşdeğer olduğuna dikkat edin:

data != null
data != undefined
data !== null && data !== undefined

Bkz. Bölüm 11.9.3 Soyut Eşitlik Karşılaştırma Algoritması ve bölüm 11.9.6 Spesifikasyonun Katı Eşitlik Karşılaştırma Algoritması .


Beyan edilmemiş değişkenlerle karıştırılmıyordum, hiçbir argüman verilmediğinde gerçekten nasıl çalıştığını bilmiyordum. Bunun datayerine var olmayacağına ikna olmuştum undefined. Açıklamayı takdir ediyorum ve bu referanslar her iki eşitliğin nasıl çalıştığını daha iyi anlamama yardımcı oldu.
afsantos

3

Değişkenleri beklemediğiniz değerler için test etmek genel olarak iyi bir fikir değildir. Çünkü sizin gibi test, yasak değerlerin bir kara listesini yazmak olarak düşünebilirsiniz. Ama ya yasak değerleri listelemeyi unutursanız? Birisi, hatta siz bile, kodunuzu beklenmedik bir değer ileterek çözebilir. Bu nedenle, daha uygun bir yaklaşım, beyaz listeye ekleme gibi bir şeydir - değişkenleri yalnızca beklenen değerler için test etmek, beklenmedik değil. Örneğin, veri değerinin bunun yerine dize olmasını bekliyorsanız:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

böyle bir şey yap:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}

2

typeof foo === "undefined"farklıdır foo === undefined, asla karıştırmayın. typeof foo === "undefined"gerçekten ihtiyacın olan şey bu. Ayrıca kullanmak !==yerine!=

Yani ifade şöyle yazılabilir

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

Düzenle:

foo === undefinedBildirilmemiş değişkenler için kullanamazsınız .

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}

1
Tamam, ama değişken bu durumda bildirildi, sorun ne?
Ry-

Şahsen ben foo === undefinedkullanmak tehlikeli buluyorum . Kodunuzu önlemeye çalıştığınız koşul için başarısız olur.

Söz konusu işleve olan argümandan bahsediyorum. Ayrıca diğer yorumuma bakın .
Ry-

1
İlk cümle doğru ve önemli bir ayrımdır!
Izkata

1
@Izkata: çünkü ilk ifade için bir açıklama yok. foo === undefinedOP'nin durumunda mükemmel kabul edilebilir ( undefinedgeçersiz kılınmadığı varsayılarak ). Cevap, neden !== yerine kullanılması gerektiğini de açıklayamıyor !=.
Matt

1

Testinizi yapmanın basit yolu:

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}

5
Bu test bağlama bağlı değil mi? Yani, beklenen tür databir dize ise, bu test uygun olabilir veya olmayabilir, boş dizeleri yanlış döndürür (işlev bir şekilde boş dize ile uğraşmak isteyebilirsiniz).
afsantos

5
"Veri" değerinin ""veya 0veya NaN(veya başkalarının) değerine sahip olması durumunda " if" bloğunun atlanmasının dışında; bu da OP'nin niyeti olabilir veya olmayabilir.
maerics

Maalesef @afsantos, yorumunuzu görmedim, eğer veri tanımsız olduğunda yanlış almak istiyorsanız, null ... tarihin boş olduğu durumlar dışında başka bir var oluşturmak zorundasınız: toTest = data; ilk testten sonra başka bir testle: if (toTest == "") {// burada bazı kodlar}
Kadiri

-5
var a;
alert(a); //Value is undefined

var b = "Volvo"; 
alert(b); //Value is Volvo

var c = null;
alert(c); //Value is null

4
Lütfen bunun ne anlama geldiği hakkında biraz açıklama ekleyin.
Ry-

Bu gerçekten vermez kontrol için null.
user4642212
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.