You can parse it
JSON.parse('null') // null
JSON.parse('1') // 1
so
var val = sessionStorage.getItem('key');
val = JSON.parse(val);
Close to cast
Alternative would be:
var val = sessionStorage.getItem('key');
val = val*1 || null;
Answer from kidwon on Stack OverflowYou can parse it
JSON.parse('null') // null
JSON.parse('1') // 1
so
var val = sessionStorage.getItem('key');
val = JSON.parse(val);
Close to cast
Alternative would be:
var val = sessionStorage.getItem('key');
val = val*1 || null;
I just want something that would evaluate to false
You could use an empty string instead to mark the unset value:
sessionStorage.setItem('key','');
This way you can re-use your current check:
if (!sessionStorage.getItem('key')) {
// do something
}
That said, you mentioned you had a drop down to select values, and that's why you need such a value, but I think a solution involving deleting the item on the null value would be better. Here's a working demo, and the code used to make it:
var dd = document.getElementById('dropdown');
dd.addEventListener('change', function(){
var value = this.value;
if (value === 'null')
sessionStorage.removeItem('key');
else sessionStorage.setItem('key', value);
});
var check = document.getElementById('check');
check.addEventListener('click', function(){
this.innerHTML = 'Value: '+sessionStorage.getItem('key')+
', check: '+(!sessionStorage.getItem('key'));
});
<select id="dropdown">
<option value="null">none</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
<button id="check">Check value</button>
You wrote:
document.getElementById("demo").innerHTML = String(null); //returns an empty string document.getElementById("demo").innerHTML = null.toString(); //returns "null" string
But both assertions are false, I am afraid.
String(null) never returns an empty string, rather a primitive of type string whose value is "null".
BTW, the form String(null) should never be used.
new String(null), on the other hand, returns an object, an instance of String (note the uppercase first letter) whose primitive value ([[PrimitiveValue]] internal property) is "null".
null.toString() raises an error in every JS engine I know. Even though null might be considered an object (due to a historical bug), it has no property, therefore no 'method' toString() (I quote the 'method' because there are no methods in JS, really).
Anyway, to be consistent, you could use this :
document.getElementById("demo").innerHTML = whateverVariable || '';
Should whateverVariable be falsy (null, undefined, 0, -0, '', NaN or false), empty string '' will be assigned to document.getElementById("demo").innerHTML.
I don't think there's a real convention here; Element.innerHTML is a property that tests the given value to determine what to do. In Safari it behaves like this:
if (value === null || value === '') {
// remove all contents
} else {
// parse string representation of value into the elements contents
}
So both "" (empty string) and null are considered the same and the assignment will just remove all contents; I couldn't find conclusive evidence that would suggest other browsers work this way, but it seems very likely that it should be considered an implementation detail that you shouldn't rely upon (see update).
That said, the documented way of clearing an element is by assigning the empty string to this property.
Update
I've found this (inconclusive) email thread about the subject, highlighting that this behaviour is not standardised:
For .innerHTML = null Opera and Internet Explorer act as if the literal string "null" was used. Firefox acts as if "" was used.
After reviewing my previous answer, it seems a complete overhaul of my previous answer is necessary. I was way over complicating it, as the short answer is that these are standards-specified special cases.
The specification for String() (String used as a function):
15.5.1.1 String ( [ value ] )
Returns a String value (not a String object) computed by ToString(value). If value is not supplied, the empty String "" is returned.
The ToString function (that exists internally, not in userland) is defined as follows (9.8):
"The abstract operation ToString converts its argument to a value of type String according to Table 13"
Argument Type | Result
Null | "null"
Undefined | "undefined"
This means that String(null) and String(undefined) go into this special table of types and just return the string values valued "null" and "undefined".
A user-land pseudo-implementation looks something like this:
function MyString(val) {
if (arguments.length === 0) {
return "";
} else if (typeof val === "undefined") {
return "undefined";
} else if (val === null) {
return "null";
} else if (typeof val === "boolean") {
return val ? "true" : "false";
} else if (typeof val === "number") {
// super complex rules
} else if (typeof val === "string") {
return val;
} else {
// return MyString(ToPrimitive(val, prefer string))
}
}
(Note that this example ignores the constructor case (new MyString()) and that it uses user-land concepts rather than engine-land.)
I got a bit carried away and found an example implementation (V8 to be specific):
string.js:
// Set the String function and constructor.
%SetCode($String, function(x) {
var value = %_ArgumentsLength() == 0 ? '' : TO_STRING_INLINE(x);
if (%_IsConstructCall()) {
%_SetValueOf(this, value);
} else {
return value;
}
});
macros.py:
macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : NonStringToString(arg));
runtime.js:
function NonStringToString(x) {
if (IS_NUMBER(x)) return %_NumberToString(x);
if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
if (IS_UNDEFINED(x)) return 'undefined';
return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x));
}
The NonStringToString (which is essentially what is of interest), is luckily defined in psuedo-JS-land. As you can see, there is indeed a special case for null/true/false/undefined.
There is probably just some extra checks and handling for special cases like null and undefined.
MDN says:
It's possible to use String as a "safer" toString alternative, as although it still normally calls the underlying toString, it also works for null and undefined.
This is a simple function which involves the use of a function to evaluate the strings. This way you can remove the part of cases' "switch". Be aware that this handles also assignments to global variables, so I recommend it only if you know anytime where is the source from(don't allow users to use this function!)
var convertType = function (value){
try {
return (new Function("return " + value + ";"))();
} catch(e) {
return value;
}
};
You can see the jsfiddle here.
How about:
var convertType = function (value){
var values = {undefined: undefined, null: null, true: true, false: false}
,isNumber = !isNaN(+(value));
return isNumber && +(value) || !(value in values) && value || values[value];
};
convertType('null'); //=> null
convertType('something'); //=> "something"
convertType('57.321'); //=> 57.321
convertType('undefined'); //=> undefined
This seems faster @ jsPerf
var convertType = function (value){
var v = Number (value);
return !isNaN(v) ? v :
value === "undefined" ? undefined
: value === "null" ? null
: value === "true" ? true
: value === "false" ? false
: value
}
When you write +!service.getNullValue() ?? undefined, you're actually performing four steps.
- Call
service.getNullValue(). - Logically negate (
!) the result of (1). - Use the unary plus operator (
+) to convert the result of (2) into a number. - Coalesce (
??) the result of (3) andundefined.
The order is important. Also important is that TypeScript compiles to JavaScript which has the concept of truthiness. The behavior you are seeing is a direct result of the truthiness of the return values of your service's methods.
In the case of getNullValue(), the evaulation is:
service.getNullValue()returnsnull.!nulluses the fact thatnullis falsey to returntrue.+trueconvertstrueto1.1 ?? undefinedreturns1.
Similarly, for getStringValue():
service.getStringValue()returns"20".!"20"uses the fact that a non empty string is truthy to returnfalse.+falseconvertsfalseto0.0 ?? undefinedreturns0.
I cannot think of a good way to inline the check for null and the conversion to a number in the same coalesce statement.
For JavaScript, you can use the fact that parseInt returns NaN for null (among other values) to check whether the result of calling service.getNullValue()/service.getStringValue() was null.
function getStringValue() { return "20"; }
function getNullValue() { return null; }
var value = parseInt(getStringValue());
console.log(isNaN(value) ? undefined : value);
value = parseInt(getNullValue());
console.log(isNaN(value) ? undefined : value);
Since TypeScript checks the type of the parameter for parseInt(:string), I think your best bet is just moving to an explicit null check.
let value = this.service.getStringValue();
console.log(value
? parseInt(value as string)
: undefined);
value = this.service.getNullValue();
console.log(value
? parseInt(value as string)
: undefined);
You can simply use like that
(Number(YourNullableString) || null)
Your function should be like this:
function (key, value) {
return (value === null) ? "" : value;
}
If the value is null, then it returns an empty string.
If you can replace null-s with empty strings on serialized string, do something like this:
data = JSON.parse(JSON.stringify(data).replace(/\:null/gi, "\:\"\""));
Without JSON.parse, you cannot.
You can evaluate hello and alter its value later on in the code, which is much more real-world scenario.
hello = hello === 'null' ? null : hello
Assign null, I've just done this:
var a=1;
console.log(a);
a=null;
console.log(a);
console.log(a===null);
Results:
1
null
true
Though, null in JS is also a value.