Let's look at the examples below:
Q1: Why is the output 0 here? What does it mean?
var a = 7;
console.log(a.constructor()); // prints 0 (Why?)
Q2: When typeof a and typeof 7 both are number, why a.constructor() runs whereas 7.constructor() doesn't?
var a = 7;
var bool = typeof a === typeof 7;
console.log(a.constructor()); // 0
console.log((++a).constructor()); // 0
console.log(7.constructor()); // SyntaxError: Invalid or unexpected token
console.log(++a.constructor()); // ReferenceError: Invalid left-hand side expression in prefix operation
Q1: Why is the output 0 here? What does it mean?
a.constructor is Number and you are calling it with first argument undefined. Because Number() returns undefined so x.constructor() returns undefined. If no argument is passed to Number() it returns 0
var a = 5;
console.log(a.constructor === Number)
console.log(Number())
When typeof a and typeof 7 both are number, why a.constructor() runs whereas 7.constructor() doesn't?
Actually 7. is itself a number. Here . doesnot work as Dot Notation but as decimal point because the digits after decimal point are optional.
Solution:
There can be different ways to directly access the method of number.
console.log(5..constructor)
console.log((5).constructor)
console.log(5 .constructor)
Q1: Because js number is object and has method constructor (which returns 0 when no parameter is provided)
Q2: Because first dot is interpret by js as decimal dot, but try
console.log( 7..constructor() );
Q1: Why is the output 0 here? What does it mean?
The constructor method is there to determine the type of the variable (Check the example)
var a = 7;
console.log(a.constructor == Number);
var b = new Object;
console.log(b.constructor == Number);
console.log(b.constructor == Object);
Q2: When typeof a and typeof 7 both are number, why a.constructor() runs whereas 7.constructor() doesn't?
Because the point after 7 is treated like a decimal and therefore it gives an error because constructor() is not a number. The code below would fix this (even tho it makes no sense):
console.log((7).constructor())
Related
Trying to convert string to a number, works fine apart from when the number is zero it returns an empty string;
I understand 0 is false, but I just need a neat way of it returning the string "0"
I'm using:
const num = this.str ? this.str.toString() : '' ;
I even thought of using es6 and simply ${this.str} but that didn't work
Because 0 is "false-y" in JavaScript, as you've already figured out, you can't utilized it in a conditional. Instead, ask yourself what the conditional is really trying to solve.
Are you worried about null / undefined values? Perhaps this is better:
const num = (typeof this.str !== "undefined" && this.str !== null) ? this.str.toString() : "";
Odds are you really only care if this.str is a Number, and in all other cases want to ignore it. What if this.str is a Date, or an Array? Both Date and Array have a .toString() method, which means you may have some weird bugs crop up if one slips into your function unexpectedly.
So a better solution may be:
const num = (typeof this.str === "number") ? this.str.toString() : "";
You can also put your code in a try catch block
const num = ''
try {
num = this.str.toString();
} catch(e) {
// Do something here if you want.
}
Just adding to given answers - if you do:
x >> 0
you will convert anything to a Number
'7' >> 0 // 7
'' >> 0 // 0
true >> 0 // 1
[7] >> 0 // 7
It's a right shift bit operation. You can do magic with this in many real life cases, like described in this article.
In my case, the zero (number) that I wanted to converted to a string (which was the value of an option in a select element) was a value in an enum.
So I did this, since the enum was generated by another process and I could not change it:
let stringValue = '';
if (this.input.enumValue === 0) {
stringValue = '0';
} else {
stringValue = this.input.enumValue.toString();
}
If debugging shows that a variable is 0, then I think that I should be able to catch it with either ==='0' or ===0 but that didn't work. I had to use only == instead, then it worked:
var offset = 0;
alert("## DEBUG non_sortable_columns " + non_sortable_columns)
if (non_sortable_columns == '0' || non_sortable_columns == 0) {
offset = 1;
}
I first tried this but it didn't work:
var offset = 0;
alert("## DEBUG non_sortable_columns " + non_sortable_columns)
if (non_sortable_columns === '0' || non_sortable_columns === 0) {
offset = 1;
}
The value was [0] and [0] === [0] is false. How can it be false?
1. [0] === [0] is false because each [0] is actually a declaration that creates an array with the number 0 as its first index. Arrays are objects and in JavaScript, 2 objects are == or === only and only if they point at the same location in memory. This means:
var a = [];
var b = a;
console.log(a == b); // "true". They both point at the same location in memory.
a = [];
b = [];
console.log(a == b); // "false". They don't point at the same location in memory.
2. [0] == "0" evaluates to true, because: In JavaScript, due to the nature of the == operator, when you compare an object with a primitive, the object will be coerced to a primitive, and then that primitive will be coerced to the specific type of primitive you are trying to compare it with.
"0" is a string, so [0] will have to be coerced to a string. How ? First, JavaScript will invoke its valueOf method to see if it returns a primitive, the array version of valueOf will just return that array, so valueOf doesn't yield a primitive; now JavaScript will try the object's (aka array's) toString method, an array's toString method will return a string that is the result of a comma-separated concatenation of its elements (each element will be coerced to a string as well, but that is irrelevant here), this would have been more visible if your array contained more than one element (e.g if it were [0,1], toString would return "0,1"), but your array only has 1 element, so the result of its stringification is "0" (if toString didn't return a string but another primitive, that primitive would be used in a ToString abstract operation; if neither valueOf nor toString returned a primitive, a TypeError would be thrown).
Now, our end comparison, with all the coercions and stuff, has changed to "0" == "0", which is true.
3. [0] == 0, mostly the same as #2, except after JavaScript has the string "0", it will coerce it to a number, the result of coercing the string "0" to a number is the number 0. So we have 0 == 0 which is true.
4. [0] === 0 and [0] === "0", these 2 are very simple, no coercions will happen because you are using ===.
In the first one, the reference (aka location pointed at in memory) held by [0] will be compared to the number 0, this will obviously evaluate to false;
In the second one, again, the reference held by [0] will be compared with the string "0", this again, is false.
So, as you can see, good ser, all your misery comes from ==, this operator, along with !=, are called "the evil counterparts of === and !==" by Douglas Crockford, for the same reasons which are causing your confusions.
Feel free to request any elaborations you might want and ask any questions you might have.
Additionally, see this article about object coercion, this MDN article about Array#toString, and this StackOverflow question which outlines the differences between == and ===.
I just did the following test
var num = 0;
console.log("Number: ", num);
if(num === '0' || num === 0) {
console.log("Num is 0 (===)");
}
if(num == '0' || num == 0) {
console.log("Num is 0 (==)");
}
and got the output
Number: 0
Num is 0 (===)
Num is 0 (==)
Try console.log the value itself, if you alert or append strings to a number in JS it will always output as a string. This can be misleading when trying to debug code.
The value of non_sortable_columns might be false.
The basic difference between the === and == is that the 3 equals to comparison operator also checks the type of the variable, that means: '0' which is a string would not be equal to: 0 which is a number.
In your case the variable non_sortable_columns value might be false which means 0in JavaScript therefore the value of the == finds it same as it doesn't check the type but === fails as it checks the type of it.
For better understanding refer to: Which equals operator (== vs ===) should be used in JavaScript comparisons?
I would like to sum the args of my function if and only if the two args are numbers (hence my first function).
function checkNum() {
var num = 0;
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] !== 'number') {
return false;
}
}
return true;
}
function addTogether() {
var num = 100;
if ( checkNum() ) {
return arguments[0] + arguments[1];
} else {
return undefined;
}
}
addTogether(2, "");
However my second function performs the sum no matter what the args values are. Any hints on how to fix this ?
checkNum() isn't declared to explicitly take any arguments (which implies to anyone looking at the function that none are expected) and you are not sending any when you call it, so arguments.length is always 0, you never enter into your loop body and you always return true.
Your second function is called by passing two arguments, so your references to arguments[0] and arguments[1] are valid there. But, even still, the use of arguments isn't really meant for all argument passing.
It's best to set up your functions with named parameters and then you can access them via those names. The use of arguments (while valid), is not encouraged as the default mechanism for accessing arguments. It's generally used for validation (ensure that the correct amount of parameters were passed to the function before the function attempts to operate on them, for example).
Also, it's best to test for numbers with a regular expression because typeof can "lie" to you. For example:
// Would you ever think that not a number is of type "number"?!
console.log(typeof NaN === "number");
Now, depending on your criteria for "number", there are two ways you could go.
Only numeric digits are allowed (i.e. 6 is allowed, "6" is not)
// It's better for this function to test one number
// at a time, so you can react to that particular
// success or failure
function checkNum(num) {
// No loop and no if/then needed, just return
// whether the argument is a number, but don't
// test for typeof number because typeof NaN === "number"
// Use a regular expression instead
var reg = /[0-9]+$/; // digits or strings of characters that are from 0 - 9
// Test for only digits not numbers passed as strings
// For example 6 is good, "6" is bad. Here, the use of "typeof"
// is safe because you are also testing that the input is digits
// or characters from 0 to 9 (NaN wouldn't pass this test)
return reg.test(num) && typeof num === "number"; // true or false will be returned
}
function addTogether(val1, val2) {
// Test each input, independantly so that you can react more granularly
if ( checkNum(val1) && checkNum(val2) ) {
return val1 + val2;
}
// It's not necessary to have an "else" that returns undefined because
// that's what will happen as long as you don't return anything else.
}
console.log(addTogether(2, "")); // undefined
console.log(addTogether(2, 6)); // 8
console.log(addTogether(2, "6")); // undefined because "6" is a string, not a digit
Numeric digits and numeric characters are allowed (i.e. 6 and "6" are allowed). In this case, you'd need to ensure that numeric characters get converted to numbers before addition is done so you get mathematical addition and not string concatenation.
// It's better for this function to test one number
// at a time, so you can react to that particular
// success or failure
function checkNum(num) {
// No loop and no if/then needed, just return
// whether the argument is a number, but don't
// test for typeof number because typeof NaN === "number"
// Use a regular expression instead
var reg = /[0-9]+$/; // digits or strings that are from 0 - 9
// Test for only digits and numbers passed as strings
return reg.test(num); // true or false will be returned
}
function addTogether(val1, val2) {
if ( checkNum(val1) && checkNum(val2) ) {
// If checkNum returns true for numeric characters as well as digits, then
// you'd need to ensure that the characters get converted to numbers so that
// you get mathmatical addition and not string concatenation. That would be done like this:
return +val1 + +val2
}
// It's not necessary to have an "else" that returns undefined because
// that's what will happen as long as you don't return anything else.
}
console.log(addTogether(2, "")); // undefined
console.log(addTogether(2, 6)); // 8
console.log(addTogether(2, "6")); // 8 because "6" is converted to 6, not a string of "6"
The arguments array, as evaluated within checkNum, contains the arguments passed to checkNum. But you aren't passing any arguments to checkNum. Try changing the if statement to
if ( checkNum(arguments[0], arguments[1]) )
You aren't passing any arguments to checkNum. You can fix this with apply:
// ...
if (checkNum.apply(this, arguments)) {
// ...
Edit: That would allow you to check any number of arguments passed to addTogether. If you only want to allow for two arguments, you can used named parameters:
function checkNum(a, b) {
return typeof a === 'number' && typeof b === 'number';
}
function addTogether(a, b) {
if (checkNum(a, b)) return a + b;
else return undefined; // line not needed
}
addTogether(2, "");
I had been going through the ES6 assuming that it would be easy to switch to EcmaScript 2017.
While going through, I got confused about this code
function f (x, y = 7, z = 42) {
return x + y + z
}
f(1) === 50
Which has ES5 equivalent
function f (x, y, z) {
if (y === undefined)
y = 7;
if (z === undefined)
z = 42;
return x + y + z;
};
f(1) === 50;
I did understand the default parameter thing from it.
But what does f(1)===50 mean in both the codes? Whats the use of it?
Here is another example
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9
What does f(1, 2, "hello", true, 7) === 9 mean?
I understand that === for comparison between the LHS and RHS of the operator including the type of both and not just value.
But why have it been used like that??
Kindly explain its usage.
This is the link from where I got this. http://es6-features.org/#RestParameter
This is a strict comparison test whether function f(x,y,z), when called with an x parameter value of 1 returns the value 50. This would be true when the default parameter values added to the value of x are 7 and 42.
These function calls and comparisons are purely to provide usage examples and possibly test examples for the functions they call.
The code
function f (x, y, ...a) {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9
is an example of extended parameter handling. the ...a variables length property equates to 3 thus the test is confirming the number of parameters passed to the function after x and y.
According to me, you almost took it in a correct way.
Just put that function call along with the triple equals sign in if condition.
if ( f(1) === 50 ){
console.log(true);
}
else {
console.log(false);
}
Thats it.
The triple equal to is simply a comparison operator. And the function call on one side of the triple equal to operator means the value returned from that function.
Hence just treat it as any other comparison operator in javascript.
And please correct me if I have misinterpreted your question.!
All the best!
The f(1)===50 checks if f(1) is equal to 50. If this expression is evaluated to true, then the result of this expression is true. Otherwise it is false. Since you don't assign this value to a variable, as it is, you can't use it anywhere.
Formally, the === is called strict equality operator. For further info please have a look here.
The point here is that its example code. They are showing you that the function's results when called with those arguments is equal to something. The expression itself won't do anything, unless you paste it into a console.
They could have just as easily used a comment.
f(1, 2, "hello", true, 7) // 9
The identity (===) operator behaves identically to the equality (==) operator except no type conversion is done, and the types must be the same to be considered equal.
In your example if you will put all three arguments of numeric type you will get number as the result and then to check if the result has correct type you have to use === operator.
Maybe this example will be more clear in your case:
f(1,1,1) // returns 3 - numeric type
f(1,1,"1") // returns "111" - string type
//so now if you will write
f(1,1,1) == "3" // true
f(1,1,1) == 3 // true
f(1,1,1) === "3" // false, because the result is 3 not "3" as string.
f(1,1,1) === 3 // true
f(1,1,"1") == "111" // true
f(1,1,"1") == 111 // true
f(1,1,"1") === "111" // true
f(1,1,"1") === 111 // false, because the result is string "111" not 111 number.
So in your case this === operator is used to double check if the result is really what you expect it to be.
How can I check if a variable is currently an integer type? I've looked for some sort of resource for this and I think the === operator is important, but I'm not sure how to check if a variable is an Integer (or an Array for that matter)
A variable will never be an integer type in JavaScript — it doesn't distinguish between different types of Number.
You can test if the variable contains a number, and if that number is an integer.
(typeof foo === "number") && Math.floor(foo) === foo
If the variable might be a string containing an integer and you want to see if that is the case:
foo == parseInt(foo, 10)
These days, ECMAScript 6 (ECMA-262) is "in the house". Use Number.isInteger(x) to ask the question you want to ask with respect to the type of x:
js> var x = 3
js> Number.isInteger(x)
true
js> var y = 3.1
js> Number.isInteger(y)
false
A number is an integer if its modulo %1 is 0-
function isInt(n){
return (typeof n== 'number' && n%1== 0);
}
This is only as good as javascript gets- say +- ten to the 15th.
isInt(Math.pow(2,50)+.1) returns true, as does
Math.pow(2,50)+.1 == Math.pow(2,50)
A clean approach
You can consider using a very small, dependency-free library like Issable. Solves all problems:
// at the basic level it supports primitives
let number = 10
let array = []
is(number).number() // returns true
is(array).number() // throws error
// so you need to define your own:
import { define } from 'issable'
// or require syntax
const { define } = require('issable')
define({
primitives: 'number',
nameOfTyping: 'integer',
toPass: function(candidate) {
// pre-ECMA6
return candidate.toFixed(0) === candidate.toString()
// ECMA6
return Number.isInteger(candidate)
}
})
is(4.4).custom('integer') // throws error
is(8).customer('integer') // returns true
If you make it a habit, your code will be much stronger. Typescript solves part of the problem but doesn't work at runtime, which is also important.
function test (string, boolean) {
// any of these below will throw errors to protect you
is(string).string()
is(boolean).boolean()
// continue with your code.
}
I know you're interested in Integer numbers so I won't re answer that but if you ever wanted to check for Floating Point numbers you could do this.
function isFloat( x )
{
return ( typeof x === "number" && Math.abs( x % 1 ) > 0);
}
Note: This MAY treat numbers ending in .0 (or any logically equivalent number of 0's) as an INTEGER. It actually needs a floating point precision error to occur to detect the floating point values in that case.
Ex.
alert(isFloat(5.2)); //returns true
alert(isFloat(5)); //returns false
alert(isFloat(5.0)); //return could be either true or false
Quite a few utility libraries such as YourJS offer functions for determining if something is an array or if something is an integer or a lot of other types as well. YourJS defines isInt by checking if the value is a number and then if it is divisible by 1:
function isInt(x) {
return typeOf(x, 'Number') && x % 1 == 0;
}
The above snippet was taken from this YourJS snippet and thusly only works because typeOf is defined by the library. You can download a minimalistic version of YourJS which mainly only has type checking functions such as typeOf(), isInt() and isArray(): http://yourjs.com/snippets/build/34,2
You may also have a look on Runtyper - a tool that performs type checking of operands in === (and other operations).
For your example, if you have strict comparison x === y and x = 123, y = "123", it will automatically check typeof x, typeof y and show warning in console:
Strict compare of different types: 123 (number) === "123" (string)
Try this code:
alert(typeof(1) == "number");