We can do:
NaN = 'foo'
as well as
undefined = 'foo'
Why are they not reserved keywords?
I think it should be implemented in order to be sure that when we are looking for a number, it is a number :)
If we should use IsNaN() or typeof, why are NaN or undefined needed?
I cannot tell you why, but undefined and NaN are actually properties of the global object:
15.1.1 Value Properties of the Global Object
15.1.1.1 NaN
The value of NaN is NaN (see 8.5). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
(...)
15.1.1.3 undefined
The value of undefined is undefined (see 8.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
There is a difference between the value undefined (NaN) and the corresponding property.
You might notice the [[Writable]]: false. I'm not sure whether this new in ES5 (and might not be adapted by all browsers), but in newer browsers (tested in Firefox 6), assigning a new value to undefined has no effect:
[12:28:15.090] < undefined = "foo"
[12:28:15.093] > "foo"
[12:28:19.882] < undefined
[12:28:19.883] > undefined
So although it seems you can assign a new value, you actually cannot.
Why they are not reserved keywords?
Not sure if there was a specific reason to not make them reserved keywords, but it was decided against it. The language still works. You cannot override these values, so it's fine.
The only way to test whether a number is NaN, is to use isNaN() anyway.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/NaN
NaN is a property of the global object.
The initial value of NaN is Not-A-Number — the same as the value of
Number.NaN. In modern browsers, NaN is a non-configurable,
non-writable property. Even when this is not the case, avoid
overriding it.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/undefined
undefined is a property of the global object, i.e. it is a variable in global scope.
The initial value of undefined is the primitive value undefined.
I'm speculating now, but the reason why I think NaN and undefined are not keywords is because you generally don't assign these values to variables.
var x = undefined; // doesn't make sense, use null!
var y = NaN; // You can't do much with this variable!
undefined basically means uninitialized, and if you want to make it clear that the value is unknown you use null. So undefined usually means not-initialized or the result of JavaScript code gone wrong.
NaN Is rarely assigned manually, simply because you can't do much with this value. It is usually the result of a calculation gone wrong. The makers of JavaScript probably didn't want to give this value the visibility of primitive values.
Also, NaN is also present in other languages and it isn't used as a keyword there either. For example: In C# NaN is represented by Double.NaN, since you don't make a distinction between floating point and integer values in JavaScript, I'm guessing that's why they put NaN with the Global Identifiers!
I hope this clears things up!
Both NaN and undefined are values in JavaScript.
NaN is of number type. (it denotes "not a valid number").
undefined is of undefined type. (when there is nothing assigned to a variable, JavaScript assigned undefined particular in var declaration).
And also both are read-only values(property) of global window object.
So that's why JavaScript cannot make values as a reserved word.
NaN is not a keyword, but it is rather a built-in property of the global object, and as such may be replaced (like undefined, but unlike the keyword this or the literals true, false, and null).
You can test if a value is NaN with the isNaN() function. Moreover NaN is defined to be unequal to everything, including itself.
Or in a nutshell you can say that:
NaN is the value returned when you try to treat something that is not a number as a number. For instance, the results of 7 times "abc" is not a number. The old form of it is Number.NaN. You can test for not-a-number values with the isNaN() function.
One reason is that it is possible to use those words as object keys:
messages = {
NaN: 'that was not a number',
undefined: 'that was not initialized',
default: 'that was something' // not in the original question but is valid syntax
};
console.log (messages.NaN);
While it would be possible to use { 'NaN': 'that was not a number' } and console.log(messages['NaN']), leaving as many words as possible unreserved could make your code easier to read.
Related
undefined is a global variable which has the value undefined — a datatype by itself which can have only one value. But what is the value null?
MDN says:
The value null is a literal.
What does that mean?
I know literal as "something you write fixed into your code". Like x = 3 + 4.
Here 3 and 4 would be integer-literals. But I don't get that together with what the MDN documentation says.
Literals are just a way to write values in our code. null, the thing you actually type, is a literal that defines the value null, just like 1 is a literal that defines the value 1. The null value is just that: A value (the only value in the Null type), like 1 is a value (one of many values in the Number type).
Remember that MDN is a community-edited resource. It's usually pretty good, but it comes down to who wrote and/or subsequently edited the page. Sometimes the terminology is a bit off. Let's look at the opening sentence of that page as it was when you posted your question:
The value null is a JavaScript literal representing null or an "empty" value, i.e. no object value is present.
Yeah, that looks like an editing error. It should read something like:
The value null represents the intentional absence of any object value.
I'll probably edit it later. I've edited it and the subsequent line that's trying to highlight that null is a literal, not an identifier for a property on the global object like undefined can be.
I am no expert but I think you already have the answer: you said 3 and 4 are "integer-literal". Quoting wikipedia:
In computer science, a literal is a notation for representing a fixed value in source code.
So 3 and 4 are both literals, as well as 34 or "hello". null is a literal in the same way, but instead of representing a number or a string, is has a meaning of nothingness.
EDIT: As I said, I am no expert and it seems I am not quite right about literals. T.J. Crowder explains it much better than me, see his answer
Null is one of the primitives in JS.
This primitive type is used as a literal in some cases which need to represent an absence of a value in a variable or reference.
However said, the literal value of null has a special meaning.
Point worth noting is that:
typeof null // object (bug in ECMAScript, should be null)
typeof undefined // undefined
null === undefined // false
null == undefined // true
null is not an object , has no methods , and is absent of any value
See Null
In computer science, a null value represents a reference that points,
generally intentionally, to a nonexistent or invalid object or
address. The meaning of a null reference varies among language
implementations.
In JavaScript, null is one of the primitive values.
Primitive
A primitive (primitive value, primitive data type) is data that is not
an object and has no methods
4.3.12 null value
primitive value that represents the intentional absence of any object
value
4.3.13 Null type
type whose sole value is the null value
I am looking at JavaScript's number type system.
I'm using Chrome, When I evaluate 15-- for a number literal I get a ReferenceError since it makes no sense to decrement a constant.
When I evaluate var x=10;x--; as expected everything works.
Expectantly var a=Infinity;a-- evaluates to Infinity, this all makes sense and is in accordance to the javascript language spec.
However to my surprise Infinity-- and Infinity++ evaluate to Infinity unlike other literals.
This also happens for Number.POSITIVE_INFINITY which is the same.
tl;dr :
Why does Infinity-- yield infinity as a result when 15-- and (new Number(15))-- yield a reference error?
Infinity as used in your example is not actually a value but refers to the Infinity property of the global object:
15.1 The Global Object
[...]
15.1.1 Value Properties of the Global Object
[...]
15.1.1.2 Infinity
The value of Infinity is +∞ (see 8.5). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
So, Infinity-- is the same as window.Infinity-- which is perfectly valid.
Because there is no such thing as a the number infinity, it is a concept, and thus in coding it isn't built as other constants but as an object like null or undefined but with some properties thrown in to make it behave nice with Math methods.
what is NaN, Object or primitive?
NaN - Not a Number
It's a primitive. You can check in a number of ways:
typeof NaN gives "number," not "object."
Add a property, it disappears. NaN.foo = "hi"; console.log(NaN.foo) // undefined
NaN instanceof Number gives false (but we know it's a number, so it must be a primitive).
It wouldn't really make sense for NaN to be an object, because expressions like 0 / 0 need to result in NaN, and math operations always result in primitives. Having NaN as an object would also mean it could not act as a falsey value, which it does in some cases.
NaN is a primitive Number value. Just like 1, 2, etc.
NaN is a property of the global object.
The initial value of NaN is Not-A-Number — the same as the value of
Number.NaN. In modern browsers, NaN is a non-configurable,
non-writable property. Even when this is not the case, avoid
overriding it.
It is rather rare to use NaN in a program. It is the returned value
when Math functions fail (Math.sqrt(-1)) or when a function trying to
parse a number fails (parseInt("blabla")).
Reference
var boolTrue = true;
var randomObject;
if (boolTrue)
// this will fire
if (randomObject)
// this will fire, because the object is defined
if (!objectNotDefined)
// this will fire, because there is no defined object named 'objectNotDefined'
Coming from a C++ and C# background, I am very familiar with the basic if(expression) syntax. However, I think it is not very readable to have both expressions (true/false) and have object existence also being a expression. Because now if I see a function like below, i don't know if the data coming in is an object (existence/undefined check) or a boolean.
function(data) {
if (data)
// is this checking if the object is true/false or if the object is in existence?
}
Is this just the way it is? I mean, is there anyway to easily read this? Also, where is this documented anywhere in the JS spec (curious)?
In Javascript everything is "true" (or "truthy" to be more precise using Javascript parlance) except false, 0, undefined, null, NaN and empty string.
To avoid confusion use:
if (data === true) // Is it really true?
and
if (typeof data === 'undefined') // Is the variable undefined?
You can check for (non-)existence separately:
if ( typeof variable == 'undefined' ) {
// other code
}
However, the syntax you show is commonly used as a much shorter form and is sufficient in most usecases.
The following values are equivalent to false in conditional statements:
false
null
undefined
The empty string ”
The number 0
The number NaN
It checks whether it is truthy.
In JavaScript, everything is truthy except false, 0, "", undefined, null and NaN.
So, true will pass, as well as any object (also empty objects/arrays/etc).
Note that your third comment is true if you mean "declared but not defined" - a variable that has never been declared throws a ReferenceError on access. A declared, non-defined variable (var something;) is undefined (so, not truthy) so it will indeed pass the condition if you negate it.
if i want to test the result of an expression and the function would return NaN
how would i check that?
examples: $('amount').value.toInt()!='NaN' ^ does not work and i assume that the returned value is not a string,
$('amount').value.toInt()!=NaN^ doesnt seem to work either and this one seems obvious
so how do i check wether the returned value is not a number?
The NaN value is defined to be unequal to everything, including itself. Test if a value is NaN with the isNaN() function, appropriately enough. (ECMAScript 6 adds a Number.isNan() function with different semantics for non-number arguments, but it's not supported in all browsers yet as of 2015).
There are two built-in properties available with a NaN value: the global NaN property (i.e. window.NaN in browsers), and Number.NaN. It is not a language keyword. In older browsers, the NaN property could be overwritten, with potentially confusing results, but with the ECMAScript 5 standard it was made non-writable.
As #some pointed out in the comments, there is also the global function isFinite() which may be useful.
the best way to check the result of numeric operation against NaN is to aproach this way ,
example:
var x = 0;
var y = 0;
var result = x/y; // we know that result will be NaN value
// to test if result holds a NaN value we should use the following code :
if(result !=result){
console.log('this is an NaN value');
}
and it's done.
the trick is that NaN can't be compared to any other value even with it self(NaN !=NaN is always true so we can take advantage of this and compare result against itself)
this is JavaScript(a good and bizarre language)
Equality operator (== and ===) cannot be used to test a value against NaN. Use Number.isNaN() or isNaN() instead.
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true