a pretty simple question, is there ever a case where using a primitive data-type is preferable in javascript, i am specifically bothered by primitive booleans, consider the foll
These are not primitives. Primitives are like 100
, "foobar"
, false
:
> typeof false
"boolean"
> typeof new Boolean(false)
"object"
new Boolean
(or Number
or String
) is an object and follows objects', not primitives' rules for comparison, boolean conversion etc. These objects are indeed hardly useful for a JS programmer (as opposed to a JS engine which uses them internally).
Note that while it's rarely needed to use Boolean
and friends to construct objects (as in x = new Boolean(...)
), these functions are sometimes useful per se. For example, the following nice idiom removes all falsy values from an array:
ary = ary.filter(Boolean)
Your example:
var bool = new Boolean(false);
if (bool){
alert(bool);
}
and you're wanting to know why it alerts false.
bool
is the variable, you assigned it a value when you created it. So, when you say if(bool)
JavaScript does some coercion and tests whether bool
is falsy, it isn't, so the conditional block executes. Now you're at alert(bool)
which will try to call the toString method of your object and display the result. The toString method of the boolean object returns the value of the boolean object as a string so, you get the word "false" alerted.
Go ahead, try
var bool = new Boolean(false);
bool.toString = function () {
return 'I need a banana';
}
if (bool){
alert(bool);
}
and you'll get completely different results.
This brings us to your other question of "why" you'd even use the boolean constructor: you can assign properties to the boolean object, you can not assign properties to true
and false
. You may want to inherit from the boolean object when building some logic handling library with chainable methods, for instance.
The primitive values are very useful (ex of primitive values: true, false, null, 1, 2, etc). What you are talking about in the question are the Object wrappers around them.
Object wrappers are useful because it allows you to add functions to be called on them. One more important thing is that when you call methods on the primitive values, Object wrappers are created over them and the methods are called on the Object wrappers*.
Example 1: String
String.prototype.sayHello = function() {
return this + ' says hello';
};
// calling a method on a string literal temporarily converts it to a String
console.log('John'.sayHello()); // 'John says hello'
Example 2: Boolean
var bool = new Boolean(false);
console.log(bool); // Boolean
console.log(bool.toString()); // 'false'
console.log(bool.valueOf()); // false
// How you can use it:
Boolean.prototype.toCaps = function() {
return this.valueOf().toString().toUpperCase();
};
console.log(bool.toCaps()); // 'FALSE'
// calling a method on a boolean literal temporarily converts it to a Boolean
console.log(true.toCaps()); // 'TRUE'
console.log((1 === 1).toCaps()); // 'TRUE'
DEMO: http://jsbin.com/apeGOve/1/edit
*) Different Object wrappers are created each time a method is called on a primitive value:
String.prototype.getWrapper = function() { return this; };
String.prototype.setTest = function() { this.test = 'test' };
String.prototype.getTest = function() { return this.test; };
var str = '123';
console.log('Different wrappers each time',str.getWrapper() === str.getWrapper());
var wrapper = str.getWrapper();
wrapper.setTest();
console.log(wrapper.getTest());
console.log(str.getTest());