Javascript Coding Practices: Empty Values in Objects - javascript

Just read this highly-related question, and then reflected on what I was using in my own code base for a project at work.
I wrote a simple function to demonstrate this question (using Google Apps Script, thus the calls to Logger.log()):
function emptyValueTest() {
var object = {
prop1: "real_data",
prop2: "",
prop3: undefined,
prop4: null
}
// What I have used in my code personally. All evaluate to TRUE
if (object.prop2 === "") Logger.log("prop2 was empty");
if (typeof object.prop3 === "undefined") Logger.log("prop3 was undefined");
if (object.prop4 === null) Logger.log("prop4 was null");
// The other solution I've seen. All evaluate to FALSE
if (object.prop2) Logger.log("prop2 was empty");
if (object.prop3) Logger.log("prop3 was undefined");
if (object.prop4) Logger.log("prop4 was null");
}
I've been building a system for the past few months with thousands of lines of code, and I often find myself back-tracking when I see a particular value, to remember what it's previous state was before a particular conditional expression.
Since I'm the one writing the code it isn't too difficult for me to figure it out, because I know the structure of the data, the values that are supposed to be there, etc.
However, this system will be taken over by another developer after I graduate from my university, so I wonder what the best practice is for representing that a property has no data.
For example, my use case is that I have event Objects which are initialized with empty data and, during the lifetime of a semester, are eventually filled with real data. Personally I use undefined because it makes more sense to me to read if (typeof data === "undefined"), having a similar semantic meaning to "if this data is undefined" (i.e. no value yet).
But I wonder, in industry, in libraries, and in personal projects, what are commonly-used methods to make code more readable, understandable? Though the length of the first three conditionals is longer than the latter three, I find the latter three to be ambiguous.
For example, prop2 could have a non-empty string like "data", or the value true, which would cause the latter conditional if (object.prop2) to evaluate to true in both cases, because everything in JavaScript is truthy except the following:
null
undefined
NaN
empty string ("")
0
false
And it is entirely possible that data could have "", 0, and false as valid values, whereas null, undefined and (especially) NaN are probably not typical values for real data.
Obviously I we know the structure of the data then we might impose more strict checks to disambiguate non-empty strings from true. But in a project with thousands of lines of code it seems to me that this gets out of hand fast, especially if the structure of the data changes over time.
So my question: Is there a preferred method of representing empty values in Javascript? And is there a particular reason for the preference (performance, readability, scalability, etc.)?

Javascript is especially insidious in the NaN constant:
alert(NaN==NaN?"isNaN":"isNotNaN"); // isNotNaN !
The most common way to represent empty object is the null constant. However, you can run into troubles using it:
var coords = null;
if(coords===null) alert("empty object");
if(coords.x==0 && coords.y==0) alert("[0,0]");
// Uncaught TypeError: Cannot read property 'x' of null
There is a design pattern called Null object: to create an object representing null value with correct properties:
var nullcoords = {x:-1,y:-1}; // null object
var coords = nullcoords;
if(coords===nullcoords) alert("empty coords");
if(coords.x==0 && coords.y==0) alert("[0,0]");
// no TypeError
As RobG points in the comment, you can afford this attitude iff
the nullobject default properties are not valid values
the default values don't spoil you operations
However, null is not a good idea for coords properties since it is not a numeric type and can mess some arithmetic operations (not in JS, though). The below code is more appropriate (and more sophisticated) solution with custom null object handler:
function nullCoordsHandler(obj) {
// any error handling you want
alert("setting default values...");
obj.x = obj.y = 0;
}
function coords() {
var _x, _y;
var defined = false;
Object.defineProperty(this,"x",{
enumerable: true,
get:function() { if(!defined) nullCoordsHandler(this); return _x; },
set:function(value) { defined = true; _x = value; }
});
Object.defineProperty(this,"y",{
enumerable: true,
get:function() { if(!defined) nullCoordsHandler(this); return _y; },
set:function(value) { defined = true; _y = value; }
});
};
var c = new coords();
if(c.x==0 && c.y==0) alert("[0,0]");
// nullCoordsHandler was called to handle the null object situation

Related

Why is null an object in Javascript? [duplicate]

Why is null considered an object in JavaScript?
Is checking
if ( object == null )
Do something
the same as
if ( !object )
Do something
?
And also:
What is the difference between null and undefined?
(name is undefined)
You: What is name? (*)
JavaScript: name? What's a name? I don't know what you're talking about. You haven't ever mentioned any name before. Are you seeing some other scripting language on the (client-)side?
name = null;
You: What is name?
JavaScript: I don't know.
In short; undefined is where no notion of the thing exists; it has no type, and it's never been referenced before in that scope; null is where the thing is known to exist, but it's not known what the value is.
One thing to remember is that null is not, conceptually, the same as false or "" or such, even if they equate after type casting, i.e.
name = false;
You: What is name?
JavaScript: Boolean false.
name = '';
You: What is name?
JavaScript: Empty string
*: name in this context is meant as a variable which has never been defined. It could be any undefined variable, however, name is a property of just about any HTML form element. It goes way, way back and was instituted well before id. It is useful because ids must be unique but names do not have to be.
The difference can be summarized into this snippet:
alert(typeof(null)); // object
alert(typeof(undefined)); // undefined
alert(null !== undefined) //true
alert(null == undefined) //true
Checking
object == null is different to check if ( !object ).
The latter is equal to ! Boolean(object), because the unary ! operator automatically cast the right operand into a Boolean.
Since Boolean(null) equals false then !false === true.
So if your object is not null, but false or 0 or "", the check will pass
because:
alert(Boolean(null)) //false
alert(Boolean(0)) //false
alert(Boolean("")) //false
null is not an object, it is a primitive value. For example, you cannot add properties to it. Sometimes people wrongly assume that it is an object, because typeof null returns "object". But that is actually a bug (that might even be fixed in ECMAScript 6).
The difference between null and undefined is as follows:
undefined: used by JavaScript and means “no value”. Uninitialized variables, missing parameters and unknown variables have that value.
> var noValueYet;
> console.log(noValueYet);
undefined
> function foo(x) { console.log(x) }
> foo()
undefined
> var obj = {};
> console.log(obj.unknownProperty)
undefined
Accessing unknown variables, however, produces an exception:
> unknownVariable
ReferenceError: unknownVariable is not defined
null: used by programmers to indicate “no value”, e.g. as a parameter to a function.
Examining a variable:
console.log(typeof unknownVariable === "undefined"); // true
var foo;
console.log(typeof foo === "undefined"); // true
console.log(foo === undefined); // true
var bar = null;
console.log(bar === null); // true
As a general rule, you should always use === and never == in JavaScript (== performs all kinds of conversions that can produce unexpected results). The check x == null is an edge case, because it works for both null and undefined:
> null == null
true
> undefined == null
true
A common way of checking whether a variable has a value is to convert it to boolean and see whether it is true. That conversion is performed by the if statement and the boolean operator ! (“not”).
function foo(param) {
if (param) {
// ...
}
}
function foo(param) {
if (! param) param = "abc";
}
function foo(param) {
// || returns first operand that can't be converted to false
param = param || "abc";
}
Drawback of this approach: All of the following values evaluate to false, so you have to be careful (e.g., the above checks can’t distinguish between undefined and 0).
undefined, null
Booleans: false
Numbers: +0, -0, NaN
Strings: ""
You can test the conversion to boolean by using Boolean as a function (normally it is a constructor, to be used with new):
> Boolean(null)
false
> Boolean("")
false
> Boolean(3-3)
false
> Boolean({})
true
> Boolean([])
true
What is the difference between null and undefined??
A property when it has no definition is undefined. a null is an object. Its type is object. null is a special value meaning "no value. undefined is not an object, its type is undefined.
You can declare a variable, set it to null, and the behavior is identical except that you'll see "null" printed out versus "undefined". You can even compare a variable that is undefined to null or vice versa, and the condition will be true:
undefined == null
null == undefined
Refer to JavaScript Difference between null and undefined for more detail.
and with your new edit yes
if (object == null) does mean the same if(!object)
when testing if object is false, they both only meet the condition when testing if false, but not when true
Check here: Javascript gotcha
First part of the question:
Why is null considered an object in JavaScript?
It is a JavaScript design error they can't fix now. It should have been type null, not type object, or not have it at all. It necessitates an extra check (sometimes forgotten) when detecting real objects and is source of bugs.
Second part of the question:
Is checking
if (object == null)
Do something
the same as
if (!object)
Do something
The two checks are always both false except for:
object is undefined or null: both true.
object is primitive, and 0, "", or false: first check false, second true.
If the object is not a primitive, but a real Object, like new Number(0), new String(""), or new Boolean(false), then both checks are false.
So if 'object' is interpreted to mean a real Object then both checks are always the same. If primitives are allowed then the checks are different for 0, "", and false.
In cases like object==null, the unobvious results could be a source of bugs. Use of == is not recommended ever, use === instead.
Third part of the question:
And also:
What is the difference between null and undefined?
In JavaScript, one difference is that null is of type object and undefined is of type undefined.
In JavaScript, null==undefined is true, and considered equal if type is ignored. Why they decided that, but 0, "" and false aren't equal, I don't know. It seems to be an arbitrary opinion.
In JavaScript, null===undefined is not true since the type must be the same in ===.
In reality, null and undefined are identical, since they both represent non-existence. So do 0, and "" for that matter too, and maybe the empty containers [] and {}. So many types of the same nothing are a recipe for bugs. One type or none at all is better. I would try to use as few as possible.
'false', 'true', and '!' are another bag of worms that could be simplified, for example, if(!x) and if(x) alone are sufficient, you don't need true and false.
A declared var x is type undefined if no value is given, but it should be the same as if x was never declared at all. Another bug source is an empty nothing container. So it is best to declare and define it together, like var x=1.
People are going round and round in circles trying to figure out all these various types of nothing, but it's all just the same thing in complicated different clothes. The reality is
undefined===undeclared===null===0===""===[]==={}===nothing
And maybe all should throw exceptions.
TLDR
undefined is a primitive value in JavaScript that indicates the implicit absence of a value. Uninitialized variables automatically have this value, and functions without an explicit return statement, return undefined.
null is also a primitive value in JavaScript. It indicates the intentional absence of an object value. null in JavaScript was designed to enable interoperability with Java.
typeof null returns "object" because of a peculiarity in the design of the language, stemming from the demand that JavaScript be interoperable with Java. It does not mean null is an instance of an object. It means: given the tree of primitive types in JavaScript, null is part of the "object-type primitive" subtree. This is explained more fully below.
Details
undefined is a primitive value that represents the implicit absence of a value. Note that undefined was not directly accessible until JavaScript 1.3 in 1998. This tells us that null was intended to be the value used by programmers when explicitly indicating the absence of a value. Uninitialized variables automatically have the value undefined. undefined is a one-of-a-kind type in the ECMAScript specification.
null is a primitive value that represents the intentional absence of an object value. null is also a one-of-a-kind type in the ECMAScript specification.
null in JavaScript was designed with a view to enable interoperability with Java, both from a "look" perspective, and from a programmatic perspective (eg the LiveConnect Java/JS bridge planned for 1996). Both Brendan Eich and others have since expressed distaste at the inclusion of two "absence of value" values, but in 1995 Eich was under orders to "make [JavaScript] look like Java".
Brendan Eich:
If I didn't have "Make it look like Java" as an order from management,
and I had more time (hard to unconfound these two causal factors), then I would have preferred a Self-like "everything's an object"
approach: no Boolean, Number, String wrappers. No undefined and null.
Sigh.
In order to accommodate Java's concept of null which, due to the strongly-typed nature of Java, can only be assigned to variables typed to a reference type (rather primitives), Eich chose to position the special null value at the top of the object prototype chain (i.e. the top of the reference types), and to include the null type as part of the set of "object-type primitives".
The typeof operator was added shortly thereafter in JavaScript 1.1, released on 19th August 1996.
From the V8 blog:
typeof null returns object, and not null, despite null being a
type of its own. To understand why, consider that the set of all
JavaScript types is divided into two groups:
objects (i.e. the Object type)
primitives (i.e. any non-object value)
As such, null means “no object value”, whereas undefined means “no
value”.
Following this line of thought, Brendan Eich designed JavaScript to
make typeof return 'object' for all values on the right-hand side,
i.e. all objects and null values, in the spirit of Java. That’s why
typeof null === 'object' despite the spec having a separate null type.
So Eich designed the hierarchy of primitive types to enable interoperability with Java. This led to him positioning null along with the "object-type primitives" on the hierarchy. To reflect this, when typeof was added to the language shortly thereafter, he chose typeof null to return "object".
The surprise expressed by JavaScript developers at typeof null === "object" is the result of an impedance mismatch (or abstraction leak) between a weakly-typed language (JavaScript) that has both null and undefined, and another, strongly-typed language (Java) that only has null, and in which null is strictly defined to refer to a reference type (not a primitive type).
Note that this is all logical, reasonable and defensible. typeof null === "object" is not a bug, but a second-order effect of having to accommodate Java interoperability.
A number of imperfect backwards rationalisations and/or conventions have emerged, including that undefined indicates implicit absence of a value, and that null indicates intentional absence of a value; or that undefined is the absence of a value, and null is specifically the absence of an object value.
A relevant conversation with Brendan Eich, screenshotted for posterity:
typeof null; // object
typeof undefined; // undefined
The value null represents the intentional absence of any object value. It is one of JavaScript's primitive values and is treated as falsy for boolean operations.
var x = null;
var y;
x is declared & defined as null
y is declared but not defined. It is declared with no value so it is undefined.
z is not declared so would also be undefined if you attempted to use z.
One way to make sense of null and undefined is to understand where each occurs.
Expect a null return value in the following situations:
Methods that query the DOM
console.log(window.document.getElementById("nonExistentElement"));
//Prints: null
JSON responses received from an Ajax request
{
name: "Bob",
address: null
}
RegEx.exec.
New functionality that is in a state of flux. The following returns null:
var proto = Object.getPrototypeOf(Object.getPrototypeOf({}));
// But this returns undefined:
Object.getOwnPropertyDescriptor({}, "a");
All other cases of non-existence are denoted by undefined (as noted by #Axel). Each of the following prints "undefined":
var uninitalised;
console.log(uninitalised);
var obj = {};
console.log(obj.nonExistent);
function missingParam(missing){
console.log(missing);
}
missingParam();
var arr = [];
console.log(arr.pop());
Of course if you decide to write var unitialised = null; or return null from a method yourself then you have null occurring in other situations. But that should be pretty obvious.
A third case is when you want to access a variable but you don't even know if it has been declared. For that case use typeof to avoid a reference error:
if(typeof unknown !== "undefined"){
//use unknown
}
In summary check for null when you are manipulating the DOM, dealing with Ajax, or using certain ECMAScript 5 features. For all other cases it is safe to check for undefined with strict equality:
if(value === undefined){
// stuff
}
Comparison of many different null checks in JavaScript:
http://jsfiddle.net/aaronhoffman/DdRHB/5/
// Variables to test
var myNull = null;
var myObject = {};
var myStringEmpty = "";
var myStringWhiteSpace = " ";
var myStringHello = "hello";
var myIntZero = 0;
var myIntOne = 1;
var myBoolTrue = true;
var myBoolFalse = false;
var myUndefined;
...trim...
http://aaron-hoffman.blogspot.com/2013/04/javascript-null-checking-undefined-and.html
To add to the answer of What is the differrence between undefined and null, from JavaScript Definitive Guide 6th Edition, p.41 on this page:
You might consider undefined to represent system-level, unexpected,
or error-like absense of value and null to represent program-level,
normal, or expected absence of value. If you need to assign one of
these values to a variable or property or pass one of these values to
a function, null is almost always the right choice.
null and undefined are both false for value equality (null==undefined): they both collapse to boolean false. They are not the same object (null!==undefined).
undefined is a property of the global object ("window" in browsers), but is a primitive type and not an object itself. It's the default value for uninitialized variables and functions ending without a return statement.
null is an instance of Object. null is used for DOM methods that return collection objects to indicate an empty result, which provides a false value without indicating an error.
Some precisions:
null and undefined are two different values. One is representing the absence of a value for a name and the other is representing the absence of a name.
What happens in an if goes as follows for if( o ):
The expression in the parentheses o is evaluated, and then the if kicks in type-coercing the value of the expression in the parentheses - in our case o.
Falsy (that will get coerced to false) values in JavaScript are: '', null, undefined, 0, and false.
The following function shows why and is capable for working out the difference:
function test() {
var myObj = {};
console.log(myObj.myProperty);
myObj.myProperty = null;
console.log(myObj.myProperty);
}
If you call
test();
You're getting
undefined
null
The first console.log(...) tries to get myProperty from myObj while it is not yet defined - so it gets back "undefined". After assigning null to it, the second console.log(...) returns obviously "null" because myProperty exists, but it has the value null assigned to it.
In order to be able to query this difference, JavaScript has null and undefined: While null is - just like in other languages an object, undefined cannot be an object because there is no instance (even not a null instance) available.
For example window.someWeirdProperty is undefined, so
"window.someWeirdProperty === null" evaluates to false while
"window.someWeirdProperty === undefined" evaluates to true.
Moreover checkif if (!o) is not the same as checking if (o == null) for o being false.
In Javascript null is not an object type it is a primitave type.
What is the difference?
Undefined refers to a pointer that has not been set.
Null refers to the null pointer for example something has manually set a variable to be of type null
Look at this:
<script>
function f(a){
alert(typeof(a));
if (a==null) alert('null');
a?alert(true):alert(false);
}
</script>
//return:
<button onclick="f()">nothing</button> //undefined null false
<button onclick="f(null)">null</button> //object null false
<button onclick="f('')">empty</button> //string false
<button onclick="f(0)">zero</button> //number false
<button onclick="f(1)">int</button> //number true
<button onclick="f('x')">str</button> //string true
From "The Principles of Object-Oriented Javascript" by Nicholas C. Zakas
But why an object when the type is null? (In fact, this has been acknowledged as an error by TC39, the committee that designs and maintains JavaScript. You could reason that null is an empty object pointer, making "object" a logical return value, but that’s still confusing.)
Zakas, Nicholas C. (2014-02-07). The Principles of Object-Oriented JavaScript (Kindle Locations 226-227). No Starch Press. Kindle Edition.
That said:
var game = null; //typeof(game) is "object"
game.score = 100;//null is not an object, what the heck!?
game instanceof Object; //false, so it's not an instance but it's type is object
//let's make this primitive variable an object;
game = {};
typeof(game);//it is an object
game instanceof Object; //true, yay!!!
game.score = 100;
Undefined case:
var score; //at this point 'score' is undefined
typeof(score); //'undefined'
var score.player = "felix"; //'undefined' is not an object
score instanceof Object; //false, oh I already knew that.
null is an object. Its type is null. undefined is not an object; its type is undefined.
The best way to think about 'null' is to recall how the similar concept is used in databases, where it indicates that a field contains "no value at all."
Yes, the item's value is known; it is 'defined.' It has been initialized.
The item's value is: "there is no value."
This is a very useful technique for writing programs that are more-easily debugged. An 'undefined' variable might be the result of a bug ... (how would you know?) ... but if the variable contains the value 'null,' you know that "someone, somewhere in this program, set it to 'null.'" Therefore, I suggest that, when you need to get rid of the value of a variable, don't "delete" ... set it to 'null.' The old value will be orphaned and soon will be garbage-collected; the new value is, "there is no value (now)." In both cases, the variable's state is certain: "it obviously, deliberately, got that way."
The other fun thing about null, compared to undefined, is that it can be incremented.
x = undefined
x++
y = null
y++
console.log(x) // NaN
console.log(y) // 0
This is useful for setting default numerical values for counters. How many times have you set a variable to -1 in its declaration?
Undefined means a variable has been declared but it has not been assigned any value while Null can be assigned to a variable representing "no value".(Null is an assignment operator)
2.Undefined is a type itself while Null is an object.
3.Javascript can itself initialize any unassigned variable to undefined but it can never set value of a variable to null. This has to be done programatically.
What is a type?
A type is a way to categorize values. Here is a table with the types in question and their typeof result.
Type
Values type contains
typeof result
Is typeof result a lie?
Undefined
Only: undefined
"undefined"
No
Null
Only: null
"object"
Yes
Object
Infinite amount of values: {}, {a: "b"}, ...
"object"
No
null is not an object, its a value of type Null.
The typeof operator is lying! It returning "object" for null is a mistake in the JavaScript language.
I wrote a chapter about this in my open-source e-book. You can read it here https://github.com/carltheperson/advanced-js-objects
Use null to define something as having no value, use undefined when you expect something might not be defined at all.
For example, if a variable has no value, assign it as null.
var weDontHaveAValue = null;
If you expect that something might be not defined at all, e.g. an optional options argument, use undefined.
if (typeof args.optionalParam !== 'undefined') { }
The main difference between null and undefined is that null represents
a missing object, while undefined represents an uninitialized state of a variable.
You can think of null as an undefined object but undefined will be undefined only
since its type is undefined.
let a;
console.log(a); //undefined, since it is declared but not initialized
console.log(null == undefined) //true
console.log(null === undefined) // false
console.log(typeof null) //object
console.log(typeof undefined) //undefined
Not defined and undefined are not the same thing happening.
age;
You: What is the value of age?
Computer: Okay, let me check my memory/reference table..... at this point (the time of you asking), i do not see any identifier named age, not in this scope/context or any parent scope/context; age is not known to me. Maybe later i will come across an instruction to add that identifier to memory, but it does not exist right now.
var age;
You: What is the value of age;
Computer: Okay, checking my memory... I see an identifier in my reference table with that name age but no value or pointer or anything was assigned to it at the time i added it, so i don't know; you can consider it (age) empty/nothing/useless.
var age = null;
You: What is the value of age;
Computer: Okay, checking my memory... i see age in my reference table: it is null. Basically, it is nothing/empty, you cannot do anything with this value; this was intentional.
Now, i probably should not explain it this way but hopefully it will make sense.
I can see why null was designed to be an object in JS, and i personally like it that way.
null and undefined practically means the same thing: empty/nothing. The difference is in how it is used conceptually.
I look at null as developer-intended nothingness; something being null was done on purpose to represent nothing. I look at undefined as computer-intended nothingness; something not having value by accident of the developer/user.
For example, if you call a function from a library/sdk and got back null, you can almost be sure that was designed on purpose by the developer/author; they specifically wanted to indicate nothingness.
Also see - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null

Empty value for int property

I got the following class:
function Corpus(name){
this.name=name; // A string
this.recordings = []; // An array to fill
this.num = ... ; // A int number to set later
}
What is the best default value for my int value (num), when it is not defined ?
The best value candidate for a number is 0, so that the typed is predefined, but the value unknown.
This is because JavaScript has internal types, even though it seems weakly typed at our level.
More generally for different types:
String: ''
Object: null
Array: null
RegExp: null
As a side note, it is totally legit to leave it undefined as said in Shomz's answer of your question. It is up to you from here :)
Depends what you want to do with it. It's perfectly fine to leave it undefined, to set it to false, and if you plan to do some math with it, you can always set it to zero (0).
Note that all of the above values are falsy, so the loose typing in JS make it matter even less.
If you want to easily check whether it's been defined or not, then leave it undefined or false, but don't forget to compare by value AND type later to avoid errors:
this.num = false;
this.num == 0; // true - be careful with this
this.num === 0; // false - the way to go

JavaScript object detection: dot syntax versus 'in' keyword

I have seen two ways of detecting whether a UA implements a specific JS property: if(object.property) and if('property' in object).
I would like to hear opinions on which is better, and most importantly, why. Is one unequivocally better than the other? Are there more than just these two ways to do object property detection? Please cover browser support, pitfalls, execution speed, and such like, rather than aesthetics.
Edit: Readers are encouraged to run the tests at jsperf.com/object-detection
if(object.property)
will fail in cases it is not set (which is what you want), and in cases it has been set to some falsey value, e.g. undefined, null, 0 etc (which is not what you want).
var object = {property: 0};
if(object.isNotSet) { ... } // will not run
if(object.property) { ... } // will not run
if('property' in object)
is slightly better, since it will actually return whether the object really has the property, not just by looking at its value.
var object = {property: 0};
if('property' in object) { ... } // will run
if('toString' in object) { ... } // will also run; from prototype
if(object.hasOwnProperty('property'))
is even better, since it will allow you to distinguish between instance properties and prototype properties.
var object = {property: 0};
if(object.hasOwnProperty('property')) { ... } // will run
if(object.hasOwnProperty('toString')) { ... } // will not run
I would say performance is not that big of an issue here, unless you're checking thousands of time a second but in that case you should consider another code structure. All of these functions/syntaxes are supported by recent browsers, hasOwnProperty has been around for a long time, too.
Edit: You can also make a general function to check for existence of a property by passing anything (even things that are not objects) as an object like this:
function has(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
Now this works:
has(window, 'setTimeout'); // true
even if window.hasOwnProperty === undefined (which is the case in IE version 8 or lower).
It really depends what you want to achieve. Are you talking about host objects (such as window and DOM nodes)? If so, the safest check is typeof, which works for all host objects I know of:
if (typeof object.property != "undefined") { ... }
Notes:
Avoid object.hasOwnProperty() for host objects, because host objects are not obliged to inherit from Object.prototype and therefore may not have a hasOwnProperty() method (and indeed in IE < 9, they generally do not).
A simple Boolean coercion (e.g. if (object.property) { ... }) is a poor test of the existence of a property, since it will give false negatives for falsy values. For example, for an empty textarea, if (textarea.selectionStart) { ... } will not execute the block even though the property exists. Also, some host object properties throw an error in older versions of IE when attempting to coerce to a Boolean (e.g. var xhr = new ActiveXObject("Microsoft.XMLHTTP"); if (xhr.responseXML) { ... }).
The in operator is a better test of the existence of a property, but there are once again no guarantees about support for it in host objects.
I recommend against considering performance for this kind of task. Choose the safest option for your project and only optimize later. There will almost certainly be much better candidates for optimization than property existence checks.
For more background on this, I recommend this excellent article by Peter Michaux.
Definitely if ('property' in object) is the right way to go. That actually tests if the property is in the object (or in its prototype chain, more on that below).
if (object.property) on the other hand, will coerce 'property' into a truth/flase value. If the property is unset, it will return "undefined", which will be coerced into false, and appear to work. But this will also fail for a number of other set values of properties. javascript is notoriously inconsistent in what it treats as truthy and falsy.
Finally, like I said above, 'property' in 'object' will return true if it's in anywhere in the prototype chain. If you want to test that's on the object itself, and not somewhere higher up in the chain, you use the hasOwnProperty method like so:
if (object.hasOwnProperty('property')) ...
The first one would fail if "property" is false of 0. To make sure that there actually exist a property you need to check that object.property !== undefined, or use the in-keyword.
[Edit]
There is also the hasOwnProperty-function, but I've never really used that one so I can't say much about it. Though I think it won't return true if the property is set in a prototype, which sometimes you want, other times you don't want.
This allows you to use window.hasOwnProperty as either referring to itself or something else, regardless of your scripting host.
// No enclosing functions here
if (!('hasOwnProperty' in this))
function hasOwnProperty(obj, prop) {
var method = Object.prototype.hasOwnProperty;
if (prop === undefined)
return method.call(this, obj);
return method.call(obj, prop);
}
//Example of use
var global = global || this; //environment-agnostic way to get the global object
var x = 'blah';
WScript.Echo(global.hasOwnProperty('x') ? 'true' : 'false'); //true
//Use as non-object method
var y = { z: false };
WScript.Echo(hasOwnProperty(y, 'z') ? 'true' : 'false'); //true
WScript.Echo(hasOwnProperty(y, 'w') ? 'true' : 'false'); //false
// true ಠ_ಠ
WScript.Echo(hasOwnProperty(global, 'hasOwnProperty') ? 'true' : 'false');

When to check for undefined and when to check for null

[Bounty Edit]
I'm looking for a good explanation when you should set/use null or undefined and where you need to check for it. Basically what are common practices for these two and is really possible to treat them separately in generic maintainable codee?
When can I safely check for === null, safely check for === undefined and when do I need to check for both with == null
When should you use the keyword undefined and when should one use the keyword null
I have various checks in the format of
if (someObj == null) or if (someObj != null) which check for both null and undefined. I would like to change all these to either === undefined or === null but I'm not sure how to guarantee that it will only ever be one of the two but not both.
Where should you use checks for null and where should you use checks for undefined
A concrete example:
var List = []; // ordered list contains data at odd indexes.
var getObject = function(id) {
for (var i = 0; i < List.length; i++) {
if (List[i] == null) continue;
if (id === List[i].getId()) {
return List[i];
}
}
return null;
}
var deleteObject = function(id) {
var index = getIndex(id) // pretty obvouis function
// List[index] = null; // should I set it to null?
delete List[index]; // should I set it to undefined?
}
This is just one example of where I can use both null or undefined and I don't know which is correct.
Are there any cases where you must check for both null and undefined because you have no choice?
Functions implicitly return undefined. Undefined keys in arrays are undefined. Undefined attributes in objects are undefined.
function foo () {
};
var bar = [];
var baz = {};
//foo() === undefined && bar[100] === undefined && baz.something === undefined
document.getElementById returns null if no elements are found.
var el = document.getElementById("foo");
// el === null || el instanceof HTMLElement
You should never have to check for undefined or null (unless you're aggregating data from both a source that may return null, and a source which may return undefined).
I recommend you avoid null; use undefined.
Some DOM methods return null. All properties of an object that have not been set return undefined when you attempt to access them, including properties of an Array. A function with no return statement implicitly returns undefined.
I would suggest making sure you know exactly what values are possible for the variable or property you're testing and testing for these values explicitly and with confidence. For testing null, use foo === null. For testing for undefined, I would recommend using typeof foo == "undefined" in most situations, because undefined (unlike null) is not a reserved word and is instead a simple property of the global object that may be altered, and also for other reasons I wrote about recently here: variable === undefined vs. typeof variable === "undefined"
The difference between null and undefined is that null is itself a value and has to be assigned. It's not the default. A brand new variable with no value assigned to it is undefined.
var x;
// value undefined - NOT null.
x = null;
// value null - NOT undefined.
I think it's interesting to note that, when Windows was first written, it didn't do a lot of checks for invalid/NULL pointers. Afterall, no programmer would be dumb enough to pass NULL where a valid string was needed. And testing for NULL just makes the code larger and slower.
The result was that many UAEs were due to errors in client programs, but all the heat went to Microsoft. Since then, Microsoft has changed Windows to pretty much check every argument for NULL.
I think the lesson is that, unless you are really sure an argument will always be valid, it's probably worth verifying that it is. Of course, Windows is used by a lot of programmers while your function may only be used by you. So that certainly factors in regarding how likely an invalid argument is.
In languages like C and C++, you can use ASSERTs and I use them ALL the time when using these languages. These are statements that verify certain conditions that you never expect to happen. During debugging, you can test that, in fact, they never do. Then when you do a release build these statements are not included in the compiled code. In some ways, this seems like the best of both worlds to me.
If you call a function with no explicit return then it implicitly returns undefined. So if I have a function that needs to say that it did its task and there is nothing result, e.g. a XMLHTTPRequest that returned nothing when you normally expect that there would be something (like a database call), then I would explicitly return null.
Undefined is different from null when using !== but not when using the weaker != because JavaScript does some implicit casting in this case.
The main difference between null and undefined is that undefined can also mean something which has not been assigned to.
undefined false
(SomeObject.foo) false false
(SomeObject.foo != null) false true
(SomeObject.foo !== null) true true
(SomeObject.foo != false) true false
(SomeObject.foo !== false) true false
This is taken from this weblog
The problem is that you claim to see the difference, but you don't. Take your example. It should really be:
var List = []; // ordered list contains data at odd indexes.
var getObject = function(id) {
for (var i = 1; i < List.length; i+=2) {
if (id === List[i].getId()) {
return List[i];
}
}
// returns undefined by default
}
Your algorithm is flawed because you check even indexes (even though you know there's nothing there), and you also misuse null as a return value.
These kind of functions should really return undefined because it means: there's no such data
And there you are in the heart of the problem. If you don't fully understand null and undefined and may use them wrongly sometimes, how can you be so sure that others will use it correctly? You can't.
Then there are Host objects with their nasty behavior, if you ask me, you better off checking for both. It doesn't hurt, in fact, it saves you some headaches dealing with third party code, or the aformentioned non-native objects.
Except for these two cases, in your own code, you can do what #bobince said:
Keep undefined as a special value for signalling when other languages might throw an exception instead.
When to set/use them...
Note that a method without a return statement returns undefined, you shouldn't force this as an expected response, if you use it in a method that should always return a value, then it should represent an error state internally.
Use null for an intentional or non-match response.
As for how/when to check...
undefined, null, 0, an empty string, NaN and false will be FALSE via coercion. These are known as "falsy" values... everything else is true.
Your best bet is coercion then testing for valid exception values...
var something; //undefined
something = !!something; //something coerced into a boolean
//true if false, null, NaN or undefined
function isFalsish(value) {
return (!value && value !== "" && value !== 0);
}
//get number or default
function getNumber(val, defaultVal) {
defaultVal = isFalsish(defaultVal) ? 0 : defaultVal;
return (isFalsish(val) || isNaN(val)) ? defaultVal : +val;
}
Numeric testing is the real bugger, since true, false and null can be coerced into a number, and 0 coerces to false.
I would treat them as 2 completely different values, and check for the one you know might occur.
If you're checking to see if something has been given a value yet, check against undefined.
If you're checking to see if the value is 'nothing,' check against 'null'
A slightly contrived example:
Say you have a series of ajax requests, and you're morally opposed to using callbacks so you have a timeout running that checks for their completion.
Your check would look something like this:
if (result !== undefined){
//The ajax requests have completed
doOnCompleteStuff();
if (result !== null){
//There is actually data to process
doSomething(result);
}
}
tldr; They are two different values, undefined means no value has been given, null means a value has been given, but the value is 'nothing'.

How important is checking for bad parameters when unit testing?

Let's say I've got a method that takes some arguments and stores them as instance variables. If one of them is null, some code later on is going to crash. Would you modify the method to throw an exception if null arguments are provided and add unit tests to check that or not? If I do, it's slightly more complicated since javascript has many bad values (null, undefined, NaN, etc.) and since it has dynamic typing, I can't even check if the right kind of object was passed in.
I think it really depends on what sort of API you're unit testing. If this is a component designed and built for internal use only, and you know usage will be under certain constraints, it can be overkill to unit test for bad parameters. On the other hand, if you're talking about something for distribution externally, or which is used in a wide variety of situations, some of which are hard to predict, yes, checking for bad parameters is appropriate. It all depends on usage.
I think you really have 2 different questions here.
The first is what is the best practice for parameter input validation and the second is should your unit test handle test for these situations.
I would recommend that you either throw an Argument Exception for the parameter that was not supplied correctly to your function or some other variable/message that informs the calling function/user of the situation. Normally, you do not want to throw exceptions and should try to prevent the functions from even being called when you know they will fail.
For your unit test, you should definitely include NULL value tests to make sure a graceful result occurs.
JavaScript has instanceof and typeof that can help you check what kind of objects are being passed to your functions:
'undefined' == typeof noVariable; // true
var noVariable = null;
'undefined' == typeof noVariable; // false
typeof noVariable; // 'object'
noVariable === null; // true
var myArray = [];
typeof myArray; // 'object'
myArray instanceof Object; // true
myArray instanceof Array; // true
var myObject = {};
typeof myObject; // 'object'
myObject instanceof Object; // true
myObject instanceof Array; // false
You can use these to set some default "bad" values for your instance variables:
function myFunction(foo,bar) {
foo = foo instanceof Array ? foo : []; // If 'foo' is not an array, make it an empty one
bar = bar instanceof Number ? bar : 0;
// This loop should always exit without error, although it may never do a single iteration
for (var i=0; i<foo.length; i++) {
console.log(foo[i]);
}
// Should never fail
bar++;
}
The or operator is also very useful:
function myFunction(blat) {
var blat = blat||null; // If 'blat' is 0, '', undefined, NaN, or null, force it to be null
// You can be sure that 'blat' will be at least *some* kind of object inside this block
if (null!==blat) {
}
}
Also, don't forget that with JavaScript you can pass in fewer than or more than the expected number of parameters. You can check that too, if you like.
For creating robust and secure code, checking the edge cases is definitely important task. Positive and negative testing is always good for the quality. The lack of negative tests might bite you in the long run.
So I'd say it is better play it safe - do both. It's a bit more work, but if you can afford the time, then it'll be worth it. Taking the developer hat off and putting on the cracker hat can be very interesting sometimes.

Categories