The `parseInt() function can return undesired and/or unexpected results if the radix is not supplied.Please make a radix is used on all parseInt() instances.
how to edit it
please helpme
i will send file if you need it
The radix is the second parameter to the parseInt() function.
It sets the numerical base that should be used when converting the string to an integer.
Obviously you would expect parseInt('11') to always return 11 :)
This is not guaranteed by all various JavaScript implementations.
What is guaranteed though is that parseInt('11', 10) will always return that 11 that you'd expect "by instinct".
Choosing a different radix ( or working in an implementation that has a different default for that matter ) say 2 would mean that the number is interpreted relative to base 2 => parseInt('11') would actually mean parseInt('11', 2) and hence come out to 3.
Assuming you want to create an Error when a radix is not passed,
Shadow parseInt, keeping the old reference in a closure such as an IIFE
Test for your conditions
Invoke the old reference
For example
parseInt = (function (old_parseInt) {
return function parseInt(x, radix) {
if (arguments.length < 2)
throw new TypeError('parseInt must be given a radix');
return old_parseInt.apply(this, arguments);
};
}(parseInt));
Then in usage,
parseInt('12', 8); // 10
parseInt('12'); // TypeError: parseInt must be given a radix
(Running this code on this page will break stackoverflow, be warned)
Related
I've seen people using regex, typeof or some built-in function like isNaN; to check if a variable / object's property is number or not.
But then today I found a "hack":
if(a.x*1) {
//a.x if a number
} else {
//a.x is not a number; a.x*1 is NaN
}
I'm just wondering if there is any downside to this trick.
Edit: I can't control the value of a.x, but I know it's either a number (1.2), a string("error") or a string that can be coerced to a number ("1.2"). I need a fast and clean way to both check its validity and convert it into a number.
Edit2: What if I check with a.x*1!==NaN?
Your check will incorrectly claim 0 isn't a number, so no, it isn't a replacement for isNaN or similar.
Note that if you want to know if a.x is already a number (and not something that can be coerced to a number), even isNaN isn't the right tool, since it will report that "12" is a number, or that any date instance is. To check if it's already a number (rather than something that can be coerced to one), you need typeof. (Of course, typeof NaN is "number", so you have to allow for that, too.)
So if you want to know if a.x is already a number and isn't NaN:
if (typeof a.x === "number" && !isNaN(a.x))
If you want to know if it's a number or something that can be implicitly coerced to a number that isn't NaN:
if (!isNaN(a.x))
Multiplying someVariable by 1 will cause implicit conversion to a number. This is the same as doing someVariable - 0 or +someVariable or the explicit Number(someVariable).
One downside to using the proposed method is that using a unary plus (+) or calling Number as a version for the conversion is idiomatic in JavaScript, which means it's well understood, so using another method to achieve the same can be confusing and make your code harder to read.
However, there is another aspect - the result of all of those conversions would not accurately tell you if the value was a number or not. Consider the following:
function isNumber(someVariable) {
if(someVariable*1) {
console.log(`"${someVariable}" is a number. For real: ${typeof someVariable}`)
} else {
console.log(`"${someVariable}" is not a number. It was a ${typeof someVariable}`)
}
}
//these are correct
isNumber(1);
isNumber("abc");
//these are incorrect
isNumber(0);
isNumber("123");
isNumber(" 321");
isNumber([1]); //logged as simply *1* the string value of an array with with one element is that element
var obj = {
name: "Fred",
age: 42,
valueOf: function() {
return this.age;
}
}
//this is also incorrect
isNumber(obj)
Checking the result of some operation would, by definition, tell you about the result of that operation. So, checking if something can be implicitly converted to a number by examining the result would tell you exactly that - the source could be implicitly converted to a number.
Furthermore, when doing if (resultOfImplicitConversion) you are checking if that result is truthy or falsey. That's not the same as checking it's type.
So, the pitfalls of your proposed method is that it is inaccurate in both steps of its attempted verification, and it also possibly inaccurately presents your intentions to future readers of your code (including yourself).
If you want to check if a value is a number, then follow this great answer on StackOverflow
I have a simple String extension to convert to numbers:
String.prototype.toInt = function(){ return parseInt(this); }
Because it's rather difficult without comments to know what kind of value you are getting in JS, I want to protect myself if I try to cast a Number to a Number that I thought was a string. I thought this would work:
Number.prototype.toInt = function(){ return this;}
But this returns the entire function. I see that there is a [[PrimitiveValue]] property in Number that ideally I could return, but I cannot figure out how to access it (such as this['[[PrimitiveValue]]'])
This should do the trick for you:
Number.prototype.toInt = function (){ return this.valueOf(); };
Though I must say, modifying the prototypes of native objects (Array, String, Number, etc) has many downsides. A functional approach is more flexible and fault tolerant, ie use parseInt(value) instead of value.toInt() would tolerate strings and numbers without issue.
Your method is returning the value as a boxed Number instance, so you just need to cast it to a primitive. For example, using the unary plus operator:
Number.prototype.toInt = function(){
return +this;
}
typeof(Infinity) returns Number in Javascript.
But why doesn't x.isNaN, where x = 1/0, return Number ?
Sample code:
var x = 1/0;
document.write(typeof(x)); //returns Number
document.write(x.isNaN); //return undefined
P.S: I am new to Javascript and learning it from W3Schools. I would be glad if you can direct me to any other reliable resources.
isNan is not a property of any number. isNaN, however, is both a function on the global scope, and on the Number object. (With the latter one being newer / more robust version)
Since isNaN is a function, you'll have to pass the variable you'd like to check as an argument:
isNaN(x) or Number.isNaN(x) will return true, as you expected.
The reason document.write(x.isNaN); returns undefined, is because x (a Number) doesn't have the property isNan.
Numbers (including NaN) don't have an isNaN method. It's global. What you want is actually isNaN(x). (Note the capital N.)
isNaN is not a property, it is a global function or a Number static method (won't work on instantiated variables).
you'll have to use either:
isNaN(x);
Number.isNaN(x);
Preferencially, Number.isNaN, although it isn't supported in IE, Opera or Safari yet.
This question already has answers here:
Why does parseInt yield NaN with Array#map?
(8 answers)
Closed 3 years ago.
Can someone explain why this has the unexpected result:
["1", "2", "3"].map(parseInt);
which returns [1, NaN, NaN] instead of [1, 2, 3]?
I can make it work by forcing a single-argument function:
["1", "2", "3"].map(function(s) {return parseInt(s);});
but I don't know what exactly went wrong in the first way.
As others mentioned, the problem is due to the 2nd argument.
Comments from MDN:
// parseInt is often used with one argument, but takes two. The second being the radix
// To the callback function, Array.prototype.map passes 3 arguments: the element, the index, the array
// The third argument is ignored by parseInt, but not the second one, hence the possible confusion.
// See the blog post for more details
But, with the use of bind, you can achieve the desired result:
var _parseInt = function(radix, number) {
return parseInt(number, radix);
}
["1", "2", "3"].map(_parseInt.bind(this, 10));
parseInt takes two arguments (the second being the radix), that's why this doesn't work. See the bottom of this MDN page for more information. Cited:
parseInt is often used with one argument, but takes two. The second
being the radix To the callback function, Array.prototype.map passes 3
arguments: the element, the index, the array. The third argument is
ignored by parseInt, but not the second one, hence the possible
confusion.
this article describes your issue in its last sample, exactly the same what you are trying to do. However the blog article they refer to doesn't exist anymore.
array.map() and parseInt callback
A better answer cited from Stackoverflow:
So if you call a function which actually expects two arguments, the
second argument will be the index of the element.
In this case, you ended up calling parseInt with radix 0, 1 and 2 in
turn. The first is the same as not supplying the parameter, so it
defaulted to base 10. Base 1 is an impossible number base, and 3 is
not a valid number in base 2:
parseInt('1', 0); // OK - gives 1
parseInt('2', 1); // FAIL - 1 isn't a legal radix
parseInt('3', 2); // FAIL - 3 isn't legal in base 2
I have a COM object which has a method that returns an unsigned int64 (VT_UI8) value. We have an HTML page which contains some JavaScript which can load the COM object and make the call to that method, to retrieve the value as such:
var foo = MyCOMObject.GetInt64Value();
This value can easily be displayed to the user in a message dialog using:
alert(foo);
or displayed on the page by:
document.getElementById('displayToUser').innerHTML = foo;
However, we cannot use this value as a Number (e.g. if we try to multiply it by 2) without the page throwing "Number expected" errors. If we check "typeof(foo)" it returns "unknown".
I've found a workaround for this by doing the following:
document.getElementById('displayToUser').innerHTML = foo;
var bar = parseInt(document.getElementById('displayToUser').innerHTML);
alert(bar*2);
What I need to know is how to make that process more efficient. Specifically, is there a way to cast foo to a String explicitly, rather than having to set some document element's innerHTML to foo and then retrieve it from that. I wouldn't mind calling something like:
alert(parseInt((string)foo) * 2);
Even better would be if there is a way to directly convert the int64 to a Number, without going through the String conversion, but I hold out less hope for that.
This:
alert(Number(String(foo)) * 2);
should do it (but see below), if your COM object implements toString (or valueOf with the "string" hint) correctly (and apparently it does, if your innerHTML trick works -- because when you assign foo to innerHTML, the same process of converting the COM object to a string occurs as with String(foo)).
From Section 15.5.1 of the 5th Edition ECMAScript spec:
When String is called as a function rather than as a constructor, it performs a type conversion.
And Section 15.7.1
When Number is called as a function rather than as a constructor, it performs a type conversion
It may be worth trying just Number(foo) * 2 to make sure, but I don't think it'll work (it seems like your COM object only handles conversion to String, not Number, which isn't surprising or unreasonable).
Edit If String(foo) is failing, try:
alert(Number("" + foo) * 2);
I'm very surprised that your innerHTML trick is working but String(foo) is throwing an error. Hopefully "" + foo will trigger the same implicit conversion as your innerHTML trick.
Edit Okay, this COM object is being very strange indeed. My next two salvos:
alert(("" + foo) * 2);
That uses all implicit conversions (adding an object to a string converts the object to a string; applying the * operator to a string converts it to a number).
Alternately, we can make the string->number conversion explicit but indirect:
alert(parseInt("" + foo) * 2);
Eek. Well if none of the explicit conversions are working because of the strange behaviour of the host object, let's try the implicit ones:
var n= +(''+foo);
I'm assuming you don't mind that the target type Number doesn't cover the full range of values of an int64 (it's a double, so you only get 52 bits of mantissa).
Matt, from the comments to other answers, I suspect you're running this code in some sort of loop. If so, make sure that you check the returned value for null before trying your conversions.
var foo = MyCOMObject.GetInt64Value();
if (foo == null) {
foo = 0; // Or something else
}