typeof! == “undefined” vs.! = null


491

Genellikle tanımsız parametreleri vb. Kontrol eden JavaScript kodunu bu şekilde görüyorum:

if (typeof input !== "undefined") {
    // do stuff
}

Bu, hem tür arama hem de dize karşılaştırması içerdiğinden, ayrıntılarından bahsetmeden, biraz savurgan görünüyor. Yine de gerekli çünkü undefinedyeniden adlandırılabilir.

Benim sorum:
Bu kod bu yaklaşımdan daha iyi nasıl:

if (null != input) {
    // do stuff
}

Bildiğim kadarıyla yeniden tanımlayamazsınız null, bu yüzden beklenmedik bir şekilde kırılmaz. Ve, çünkü tip zorlama !=operatörü, bu ikisi için kontroller undefinedve nullsık sık ... Eğer (örneğin isteğe bağlı fonksiyon parametreleri için) istediğiniz tam olarak ne.

Yine de bu form yaygın görünmüyor ve JSLint'in kötü !=operatörü kullandığınız için size bağırmasına bile neden oluyor .

Bu neden kötü stil olarak kabul edilir?


13
@ Marcel, gerçek bir fark yok, ama bunu yapmanın iki nedeni var. Birincisi, bazıları için okumak daha açık. İkinci neden, bir değişkenin yanlışlıkla üzerine yazılmasını engellemesidir. Bunu hiç yaptınız mı: bir karşılaştırma yapmak istediğinizde if (foo = "value"). Değişkeni tersine çevirme alışkanlığına sahipseniz, atama / karşılaştırma işlecinde bu sorunla karşılaşmazsınız.
Layke

29
Bazıları için (ben dahil) bunu okumak daha zordur . Ayrıca, çoğu IDE sizi yanlışlıkla atama konusunda uyarır. Ancak karşılaştırılan değişken çok uzunsa bu formu kullanmaya devam ediyorum. YMMV.
johndodo

15
@MarcelKorpel Buna "Yoda koşulu" denir: umumble.com/blogs/Programming/321
kol

55
Okumak daha zor. "Şişe boş değil" demez.
Noel Abrahams

11
if (null != input)sadece "Yoda konuşun" İngilizce konuşmacı (biri olduğumu .... uuammmmm) yani onlar aynı şey eşittir eğer gerçekten sadece anlambilimidir. BENİM NACİZANE FİKRİME GÖRE.
webLacky3rdClass

Yanıtlar:


709

typeof tanımlayıcının daha önce hiç bildirilmemesine izin verdiği için daha güvenlidir:

if(typeof neverDeclared === "undefined") // no errors

if(neverDeclared === null) // throws ReferenceError: neverDeclared is not defined

3
if ((typeof neverDeclared! == "undefined") && (neverDeclared! == null)) {dönüş doğru; } else {dönüş yanlış; }
Anthony DiSanti

88
Null / undefined ile karşılaştırırken === kullanın.
MyGGaN

47
@MyGGaN sadece ikisini birbirinden ayırmak istiyorsanız. Birçok durumda, ==daha iyi olabilir, çünkü hem null hem de undefined için test yapar.
seanmonstar

10
Typeof somevar == 'undefined' ve typeof somevar === 'undefined' arasında herhangi bir fark bulamıyorum çünkü typeof her zaman dize döndürür. Null için 'nesne' döndürür. Yoksa yanıldığım olabilir mi?
TomTom

2
@ TomTom'un yorumunun sorunun kaynağı olduğuna inanıyorum - türü dize olduğu bilinen bir değeri karşılaştırırken neden !==veya ===işleçlerini kullanacağımı anlayamıyorum .
Nicolas Rinaudo

49

Değişken bildirilirse ( varanahtar sözcükle, işlev bağımsız değişkeni olarak veya genel değişken olarak), bunu yapmanın en iyi yolunun bence:

if (my_variable === undefined)

jQuery yapar, bu yüzden benim için yeterince iyi :-)

Aksi takdirde, typeofönlemek için kullanmanız gerekir ReferenceError.

Undefined öğesinin yeniden tanımlanmasını bekliyorsanız, kodunuzu şu şekilde sarabilirsiniz:

(function(undefined){
    // undefined is now what it's supposed to be
})();

Veya voidoperatör üzerinden alın :

const undefined = void 0;
// also safe

1
Undefined zaten tanımlanmışsa, undefined adlı bir parametre aracılığıyla anonim işlevinize geçmez ve hiçbir şey yapmaz mıydınız?
Anthony DiSanti

20
@ Anthony DiSanti: Hayır, undefineddeğeri değil, fonksiyon parametresine verilen addır. İşleve hiçbir şey iletilmez, yani ilk parametrenin değeri tanımsızdır.
Joey Adams

3
Ah benim hatam, takip ettiğiniz için teşekkürler. Oyumu kaldırdım, bunun için üzgünüm.
Anthony DiSanti

2
Başlamak için doğru bir şekilde yapabildiğinizde neden başka bir geliştirici tarafından tanımlanmamış tanımlamayı işlemek için bir istisna yazmalısınız? jQuery, tanımsız tanımlı olmadığından emin olmak ve simge durumuna küçültülmüş boyutu azaltmak için ilk anonim işlevi işlevinizde gösterdiğiniz gibi sarar. Bunu yapmak için beklenmedik sonuçlar verebiliyorsa, neden yazmayı önlemek için tembel programlamanın neden risk altında olduğunu belirtin (typeof variable === 'undefined'). İstersek (typeof variable === 'object') bir nesne olan varsayılan bir değişken sağlamalıyız ki yapabilmemiz için (variable === object)?
Ocak'ta fyrye

28

iyi bir yol:

if(typeof neverDeclared == "undefined") //no errors

Ancak en iyi görünen yol şu yollarla kontrol etmektir:

if(typeof neverDeclared === typeof undefined) //also no errors and no strings

6
var undefined = function () {}; if (typeof neverDeclared === undefined türünde); neverDecalred! = 'işlev'; jsfiddle.net/hbPZ5 dönüş türü var; bir dize döndürür. Hata ya da dize yoktur, ancak her zaman beklenen sonuçları vermez. Verilen geliştiriciler tanımsız olarak beyan edilmemelidir, ancak bunu yapan bazı çerçeveler ve kütüphaneler vardır.
Ocak'ta fyrye

1
Öncelikle kullanıyorum if (typeof neverDeclared === typeof undefined) { ama Lint bir hata veriyor. Msgstr "Bir dize bekleniyordu ve bunun yerine 'typeof' gördü." Bu hatayı nasıl aşarsınız? Lint'in taleplerine boyun eğmeli ve bunun yerine 'iyi yolu' kullanmalı mıyız?
Ayelis

2
@fyrye Tanımsız olarak gerçekten mutasyona uğrayan herhangi bir JavaScript kitaplığı / çerçevesi biliyor musunuz? Bunun mümkün olduğunu biliyorum; ama vahşi bir örnek bulmak istiyorum, "İşte bu kötü Wildebeest ile karşılaşabileceğiniz yer!"
bigtunacan

4
typeof neverDeclared === typeof void 0;-D
Alex Yaroshevich

1
Hataya yatkındır, çünkü aslında tanımlanmayan belirli bir değişkene ("tanımsız") güveniyorsunuz. Diğer gönderilerin gösterdiği gibi yanlış olabilir. Her zaman yapabilirsiniz if(typeof neverDeclared === typeof undefined_variable_with_a_name_assumed_to_be_never_defined) {ama oldukça uzun.
Pierre-Olivier Vares

12

Tanımsız olarak yeniden adlandırılması konusunda gerçekten endişelenmemelisiniz. Birisi undefined olarak yeniden adlandırırsa, kontrol başarısız olursa birkaç tanesinden çok daha fazla sorun yaşarsınız. Kodunuzu gerçekten korumak istiyorsanız, aşağıdaki gibi bir IFFE (hemen çağrılan işlev ifadesi) içine sarın:

(function($, Backbone, _, undefined) {
    //undefined is undefined here.
})(jQuery, Backbone, _);

Bir tarayıcı ortamında küresel değişkenlerle (zaten yanlış olan) çalışıyorsanız, şu şekilde tanımsız olup olmadığını kontrol ederim:

if(window.neverDefined === undefined) {
    //Code works
}

Global değişkenler pencere nesnesinin bir parçası olduğundan, bir dizeye yayın yapmak ve dizeleri karşılaştırmak yerine tanımsızlara karşı kontrol edebilirsiniz.

Üstelik değişkenleriniz neden tanımlanmadı? Değişkenlerin varlığını kontrol ettikleri ve buna dayalı bazı eylemler gerçekleştirdikleri bir sürü kod gördüm. Bu yaklaşımın nerede doğru olduğunu bir kez görmedim.


1
Giriş doğrulaması ve bağımlılık kontrolü, bunu kullanmak için iyi sebeplerdir. Yüklenen veya belirtilen nesneleri başlatan diğer dosyalara bağımlı olan Javascript dosyalarım varsa, bir dosyanın tanımsızlara bağımlı olduğu nesneleri veya özellikleri test etmek ve komut dosyanızın öngörülemeyen bir yerde başarısız olmasına izin vermek yerine güzel bir istisna atmak yararlıdır.
Amerikan

AMD hatlarında bir şeye ihtiyaç duyabileceğiniz anlaşılıyor (requir.js)
Peeter

1
Ya da projeme başka bir kütüphane eklemek yerine çok basit bir karşılaştırma yapmak isteyebilirim :)
AmericanUmlaut

Düzenlemek için çok geç :(. Eklemek istedim - requir.js, giriş doğrulaması için de doğru çözüm değil (ilk yorumumda bahsettiğim init nesneleri). yüklenmeden önceki değerleri, daha sonra tanımlanmamışlarsa bir istisna atmak yararlı olur
AmericanUmlaut

1
Hayır, çünkü typeof bir dize döndürür. Yani typeof undefined, "undefined" değerini döndürür. window.input! == undefined (değişkeniniz global görünümdeyse)
Peeter

5

Eğer tanımsızın yeniden tanımlanmasından gerçekten endişeleniyorsanız, buna karşı bazı yardımcı yöntemlerle korunabilirsiniz:

function is_undefined(value) {
   var undefined_check; // instantiate a new variable which gets initialized to the real undefined value
   return value === undefined_check;
}

Bu işe yarar çünkü birisi yazdığında undefined = "foo", adın yalnızca undefinedyeni bir değere başvurmasına izin verir , ancak gerçek değerini değiştirmez undefined.


1
Ancak, şimdi performansa zarar verecek bir işlev çağrısı başlattınız.
Tim Down

Bu işlev çağrısının performansı öldüreceğini sanmıyorum, DOM'un darboğaz olması daha muhtemel. Her neyse, kitaplığınızı içeren her zamanki büyük anonim işleviniz varsa undefined_check, üstte de tanımlayabilir ve daha sonra kodunuzun her yerinde kullanabilirsiniz.
Ivo Wetzel

1
Kabul ettim ve bunun kötü bir fikir olduğunu söylemiyorum. Bu işlevi çağırmanın bir typeofkontrol yapmaktan daha yavaş gerçekleşeceğini belirtmek gerekir .
Tim Down

Bence bu fonksiyon satır içi olacak kadar basit, bu yüzden performans etkilenmeyecek.
huyz

4
@TimDown: okunabilir olan ilk yazma kodu. ikinci yazma kodu, bu sürdürülebilir, ve sonra, eğer gerçekten yavaş. sonra performansı düşünün.
andreas

4

Tanımlanmamış bir değer elde etmek için void operatörünü de kullanabilirsiniz:

if (input !== void 0) {
    // do stuff    
}

(Ve evet, başka bir cevapta belirtildiği gibi, değişken bildirilmezse bu bir hata atar, ancak bu durum genellikle kod denetimi veya kod yeniden düzenleme yoluyla, örneğin window.input !== void 0genel değişkenleri test etmek veya eklemek için devre dışı bırakılabilir var input.)


1

Ben aslında (typeof input !== 'undefined')varsayılan fonksiyon parametreleri sağlamak için kullanılan bu senaryoda rastlamak :

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';

  return `${greeting} ${name}!`;
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

ES6, varsayılan işlev parametrelerini bu şekilde tanıtmanın yeni yollarını sunar:

function greet(name = 'Student', greeting = 'Welcome') {
  return `${greeting} ${name}!`;
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

Bu, ilk seçenekten daha az ayrıntılı ve daha temizdir.


1

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';

  console.log(greeting,name);
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

//ES6 provides new ways of introducing default function parameters this way:

function greet2(name = 'Student', greeting = 'Welcome') {
//  return '${greeting} ${name}!';
console.log(greeting,name);
}

greet2(); // Welcome Student!
greet2('James'); // Welcome James!
greet2('Richard', 'Howdy'); // Howdy Richard!


0

(function(){

  var a= b = 3;
  var ed = 103;
  
})();



//console.log(ed); //ed is not defined

console.log("a defined? " + (typeof a !== 'undefined')); //no define
console.log("b defined? " + (typeof b !== 'undefined')); //yes define
console.log(typeof(b)); //number
console.log(typeof(4+7));   //number
console.log(b); //3
console.log(typeof("4"+"7")); //string
var e= "ggg";
console.log(typeof(e)); //string
 var ty=typeof(b);
console.log(ty); //number
console.log(typeof false); //boolean
console.log(typeof 1); //number
console.log(typeof 0); //number
console.log(typeof true); //boolean


console.log(typeof Math.tan);  //function
console.log(typeof function(){}); //function 

if(typeof neverDeclared == "undefined") //no errors
if(typeof neverDeclared === "undefined") //no errors

//if(neverDeclared == null) //showing error 


console.log(typeof {a:1}); //object
console.log(typeof null); //object
console.log(typeof JSON); //object
console.log(typeof Math); //object
console.log(typeof /a-z/); //object
console.log(typeof new Date()); //object

console.log(typeof afbc); //undefined
//console.log(typeof new);//error

document.write("<br> * oprator as math ");
var r=14*"4";
document.write(r);

document.write("<br> + oprator as string ");
var r=14+"44";
document.write(r);

document.write("<br> Minus Operator work as mathematic ");
var r=64-"44";
document.write(r);


document.write("<br>");
console.log(typeof(4*"7")); //returns number
console.log(typeof(4+"7")); //returns string




 
Interview Question in JavaScript


Bir açıklama yapabilir misiniz?
jhpratt GOFUNDME RELICENSING

Typeof döndüren altı olası değer vardır: object, boolean, function, number, string ve undefined. Typeof operatörü, işleneninin veri türünü (dize döndürür) almak için kullanılır. İşlenen, bir değişmez bilgi ya da değişken, işlev ya da nesne gibi bir veri yapısı olabilir. Operatör veri türünü döndürür. Operand veya typeof (operand) sözdizimi
Avinash Maurya

0

var bar = null;
console.log(typeof bar === "object"); //true yes 
//because null a datatype of object

var barf = "dff";
console.log(typeof barf.constructor);//function


console.log(Array.isArray(bar));//falsss


console.log((bar !== null) && (bar.constructor === Object)); //false

console.log((bar !== null) && (typeof bar === "object"));  // logs false
//because bar!==null, bar is a object


console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function"))); //false

console.log(typeof bar === typeof object); //false
console.log(typeof bar2 === typeof undefined); //true
console.log(typeof bar3 === typeof undefinedff); //true
console.log(typeof bar2 == typeof undefined); //true

console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]")); //false


-7
if (input == undefined) { ... }

gayet iyi çalışıyor. Tabii ki bu bir nullkarşılaştırma değil , ama genellikle undefinedve arasında bir ayrım yapmam gerekirse null, aslında undefinedve sadece herhangi bir yanlış değeri ayırt etmem gerektiğini buluyorum.

else if (input) { ... }

yapar.

Bir program yeniden undefinedtanımlıyorsa, zaten gerçekten cesur olur.

Aklıma gelen tek nedeni o anlamadı, IE4 uyumluluk için oldu undefined(ne yazık ki, aslında bir anahtar kelime değildir) anahtar kelime, ama tabii ki değerler olabilir olmak undefined buna sahip zorunda:

var undefined;

ve yukarıdaki karşılaştırma işe yarayacaktır.

İkinci örneğinizde, tiftikleri mutlu etmek için muhtemelen çift parantezlere ihtiyacınız var mı?


Sizin input == undefineddönecektir truebir üstünde nullgirişi.
mgol
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.