undefined !== undefined
Mit ír ki az alábbi JavaScript program, ha az első két alert: 1: undefined és 2: undefined?
alert('1: ' + typeof undef1);
alert('2: ' + typeof undef2);
alert('3: ' + undef1);
alert('4: ' + undef2);
// ...
A válasz: nem tudjuk biztosan.
Nálam jelen esetben: 3: undefined és semmi más. Ugyanis a három pontban elrejtettem egy var undef1;
deklarációt, így az undef1
változó létezik, de nincs értéke, míg az undef2
változó nem is létezik. Ezért a negyedik alertnél hibával elszáll a szkript (undef2 is not defined – milyen meglepő).
A nagy kérdés ez: Hogyan adjunk egy változónak alapértelmezett értéket, ha undefined
?
Ezen az ajánlott JavaScript oldalon a következőt olvashatjuk:
if (sayThis === undefined) { // Check to see if sayThis was passed
sayThis = 'default value'; // It wasn't so give it a default value
} // End check
alert(sayThis); // Toss up the alert.
Ezzel több probléma van, például, hogy nem tudhatjuk, az undefined
változó valóban undefined
-e.
Sajnos a következők sem megfelelők, hiszen ha a vizsgált változónk nem létezik, a futás megszakad:
var localVar = globalVar ? globalVar : defaultValue;
if (!variable) {
variable = something;
}
if (variable) {
use(variable);
}
Ha létrehozni akarjuk a változót, akkor nincs gond, hiszen mindegy, hogy a hatókörön belül hova helyezzük el a változó deklarációját: az
if (!myModule) {
var myModule = (function () { /* ... */ })();
}
pontosan ugyanaz, mint a
var myModule;
if (!myModule) {
myModule = (function() { /* ... */ })();
}
A minden körülmények között biztonságos módszer:
if (typeof myVar == 'undefined') {
myVar = defaultValue;
}
A lokális változókkal nincsenek gondok, hiszen éppen attól lokálisak, hogy a var
kulcsszóval vagy a függvény paramétereiként létrehoztuk őket.
Egy objektum tulajdonságai mindig léteznek* (még akkor is, ha nincsenek definiálva). A JavaScriptben minden globális változó a self
(vagy window
) adattagja, azaz globalVar === self.globalVar
igaz minden esetben (ha a változó létezik). Emiatt biztonsággal használhatjuk a var localVar = self.globalVar ? globalVar : defaultValue;
kifejezést is. (A globális névtérben ugyanis lokálisan a self
és window
is helyettesíthető mással.)
* Pongyola fogalmazás, itt is megjelenik a kétféle undefined:
var undefined = (function () {})();
var a = [];
a[1] = undefined
var print = function(place, index, element) {
$('#' + place).append($('<div>' + index + ': ' + element + '</div>'));
};
a.forEach(function(element, index) {
print('forEach', index, element);
}); // 1: undefined
$.each(a, function(index, element) {
print('jQuery', index, element);
}); // 0: undefined, 1: undefined
for(i = 0; i < a.length; i++) {
print('because', i, i in a);
}; // 0: false, 1: true
A natív forEach
(vagy az MDC oldalán javasolt megoldás) ezt szépen lekezeli, a jQuery azonban nem ismeri fel, hogy a 0-s elem nincs a tömbben.
Hasonló a helyzet az objektumoknál:
X = function () {
this.undef1 = (function () {})();
}
Y = function() {
this.undef1 = this.undef2 = 'UNDEFINED?';
}
var x = new X();
alert(x.undef1 + ', ' + x.undef2); // undefined, undefined
X.prototype = new Y();
var y = new X();
alert(y.undef1 + ', ' + y.undef2); // undefined, UNDEFINED?
Az undef1
nem definiált, az undef2
nem létezik. Ezért ha van prototípus, az undef2
megkapja onnan az értékét.
Konklúzió: jobb lett volna, ha van undefined
és nonexists
típus, de ha már így alakult, ne felejtkezzünk meg arról, mindkettő létezik, csak ugyanazon undefined
név alatt.
Adódik a kérdés: ezek után mit keres a null
a nyelvben? ;) Ennek megválaszolását az Olvasóra bízom.
Elvesztettem a fonalat.
var
kulcsszóval bevezetett változó deklarált. Ha egy változó deklarált, de nincs még értéke, akkor a változó értéke undefined. Ha egy változó nem deklarált, akkor annak típusa "undefined". Ez a kétfajta undefined valóban nem identikus, lévén egyik típus, másik érték. Az undefined érték típusa is undefined. Explicit visszatérés nélkül konstruált függvény undefined értékkel tér vissza.Tehát nem definiálva nincsen, hanem deklarálva. Ez pedig a JavaScript azon természetéből fakad, hogy ha egy objektum nemlétező tulajdonságára hivatkozunk, akkor undefined értéket kapunk vissza.
Nem csodálom
Éppen ezt szerettem volna kihangsúlyozni, ezek szerint nem sikerült jól megfogalmaznom.
OFF
Sajnálom