Codecademy - Looking for clarification on syntax ( === "number" ) - javascript

I'm working my way through the Codecademy 'Intro to JavaScript' course. I've just came across an example section of code that has confused me a little and doesn't seem to be explained. I've looked at the Mozilla documentation and think I understand but I'm really just looking for clarification on the subject.
let restaurant = {
_name: 'Italian Bistro',
_seatingCapacity: 120,
_hasDineInSpecial: true,
_entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine
pesto'],
set seatingCapacity(newCapacity) {
if (typeof newCapacity === 'number') { // THIS LINE
this._seatingCapacity = newCapacity;
console.log(`${newCapacity} is valid input.`);
} else {
console.log(`Change ${newCapacity} to a number.`)
}
}
My question - Does 'number' here mean a number (12, 343 etc.) rather than the string 'number' in all cases? Or is it only within the typeof operator?
I'm assuming it's a silly question but it's one that threw me off. Thanks.

=== is used to check for strict equality. Consider the following example
0 == false //<== returns true
0 === false //<== returns false
In your example is not necessary, as typeof will never return any value that could be equal to number without being the number string itself. But it's considered good practice to use === (although I personally think it depends on what you are comparing)
(list of possible returned values for typeof here)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof

Related

Javascript printing all if conditions in textbot [duplicate]

This question already has answers here:
What's the prettiest way to compare one value against multiple values? [duplicate]
(8 answers)
Closed 4 years ago.
This is literally the first thing I have ever coded and I am self-taught, so I'm sure it's a mess and I've made a dumb error, but after an hour of looking up the issue and trying things I cannot solve this.
To try and teach myself very basic javascript concepts I've written a textbot that has existential conversations with you. The problem is that regardless of user input, all the if statements for the condition of whatDream are printing in a row. Can anyone tell me what I've screwed up here? Apologies if my methods are wack - 100% of what I'm doing is from self teaching and letting myself flail to learn, and I'll appreciate any advice.
function yesHappy (){
alert ("Good for you. To be happy as a human is a great gift.");
alert ("The content human starts over again everyday, in spite of all they know, against all they know.");
alert ("If one advances each day confidently in the direction of their dreams, and endeavors to live the life which they have imagined, they will meet with a success unexpected in common hours.");
var g = 0
while (g < 2) {
g = 0
var whatDream = prompt ("What is your dream?");
if (whatDream === "success" || "Success" || "power" || "Power" || "wealth" || "Wealth"){
alert ("That is a goal that takes much will in the earthly domain, and is not one I can readily reccomend.");
alert ("But, read your fate, see what is before you, and walk into futurity.");
g = 3
}
if (whatDream === "friends" || "Friends" || "family" || "Family" || "love" || "Love"){
alert ("To surround oneself with others fulfills a basic human goal to be social, thus your dream is only natural.");
alert ("Properly speaking, a human has as many social selves as there are individuals who recognize them.");
alert ("To all of these you surround yourself with, see in your goals only to show your true social self.");
g = 3
}
if (whatDream === "fun" || "Fun" || "charity" || "Charity" || "faith" || "Faith" || "travel" || "Travel"){
alert ("These are honorable dreams, chosen to bring joy to yourself and others.");
alert ("Above all however, avoid falsehood, especially falseness to yourself.");
alert ("Be true to your purpose.");
g = 3
}
if (g === 0){
alert ("Though knowledge is the plague of life, and consciousness an open wound in its heart, I am still sad to say I don't know what you mean.");
alert ("Let's try that again.");
}
}
}
You need to refactor all your conditional statements. For example: This one
if (whatDream === "success" || "Success" || "power" || "Power" || "wealth" || "Wealth")
Would have to be translated to:
if (whatDream === "success" || whatDream === "Success" || whatDream === "power" || whatDream === "Power" || whatDream === "wealth" || whatDream === "Wealth")
Which does what you want: Checks to see if whatDream equals any of those. Or alternatively you can use a data structure and use a method to check if the string exists in that data structure- but above is the simplest refactoring you'd have to do.
Javascript has "truthy" and "Falsey" values. Strings like "Success" map to true whereas "" map to false. So your conditionals were always evaluating to true because strings with length > 0 are "truthy". This is probably more explanation that you need- but its important to know that in the future of javascript development.
In essence- your issue is that you weren't checking the values of whatDream in your boolean logic. The above simple refactoring I did fixes it.
If you're curious: You can read up on truthy and falsey values here:
https://j11y.io/javascript/truthy-falsey/

how many ways to check if x is integer and which one is most efficient?

I already checked what is the best way to check variable type in javascript
question on So but didn't found answer of my question.
In javascript how many ways to find if input type is integer? which one is efficient?
I was looking the way to find the integer in javascript and found number of ways to do this:
Using typeof
function isInteger(x)
{
return (typeof x === 'number') && (x % 1 === 0);
}
console.log(isInteger(10));
console.log(isInteger(10.1))
Using parseInt
function isInteger(x)
{
return parseInt(x, 10) === x;
}
console.log(isInteger(10));
console.log(isInteger(10.1));
Using Math.round
function isInteger(x)
{
return Math.round(x) === x;
}
console.log(isInteger(10));
console.log(isInteger(10.1));
Is there any other way to find the type of Integer and which one will be most efficient for consider small to large integer values.
The most intuitive one is Number.isInteger(), at least in my opinion
function isInteger(x)
{
return Number.isInteger(x);
}
console.log(isInteger(10)); // Output: True
console.log(isInteger(10.1)); // Output: False
Edit
As for efficiency, I created a benchmark on jsben.ch where I try all your methods and mine, you can see for yourself ;)
Link
I just tested the speed of each code at JSBEN.CH
typeof => 347 ms
parseInt => 338 ms
Math.round => 367 ms
Interestingly, parseInt is the fastest way!
It's only the speed comparison. Go with Number.isInteger(x) instead! It's the instinctive & fastest of all.
Your propositions seem fine, but let's add for completion the polyfill Mozilla puts forward :
Number.isInteger = Number.isInteger || function(value) {
return typeof value === 'number' &&
isFinite(value) &&
Math.floor(value) === value;
};
I am concluding answer for this question after some resarch
From ECMAscript 6 which introduces a new Number.isInteger() function for precisely this purpose.
However, prior to ECMAScript 6, this is a bit more complicated, since no equivalent of the Number.isInteger() method is provided.
The simplest and cleanest pre-ECMAScript-6 solution (which is also sufficiently robust to return false even if a non-numeric value such as a string or null is passed to the function) would be the following use of the bitwise XOR operator:
function isInteger(x)
{
return (x ^ 0) === x;
}
Others like Math.round() ,typeof and parseInt can be used also to find the Integer.
While this parseInt-based approach will work well for many values of x, once x becomes quite large, it will fail to work properly. The problem is that parseInt() coerces its first parameter to a string before parsing digits. Therefore, once the number becomes sufficiently large, its string representation will be presented in exponential form (e.g., 1e+21). Accordingly, parseInt() will then try to parse 1e+21, but will stop parsing when it reaches the e character and will therefore return a value of 1.

TypeScript isNaN only accepts a number

I work with WebStorm 2016.2.2, TypeScript 2.1, Node.js.
For some reason, isNaN is declared as a function that only accepts a number:
declare function isNaN(number: number): boolean;
I tried to change it to any, but it looks like it doesn't influence on the TSC. I still get the same error:
Argument of type 'string' is not assignable to parameter of type
'number'
My code (simplified):
isNaN("10");
How can I solve/workaround it?
Edit:
Notice that according to specification, isNaN's parameter can be any type: Number.isNaN()
Also: My code was simplified. I actually receive a parameter that may be either a string or a number, and if it's a string it may be either a stringy number that I would like to convert to number ("10") or a simple string ("Hello world").
I didn't want to make this question long by including my entire code, but because it caused confusion, this is my real code:
if (typeof expectedValue === "string" && !isNaN(expectedValue)) {
expectedValue = +expectedValue;
}
if (typeof actualValue === "string" && !isNaN(ctualValue)) {
actualValue = +actualValue;
}
switch (this.operator) {
case Operator.equal:
return actualValue == expectedValue;
case Operator.notEqual:
return actualValue === undefined || actualValue != expectedValue;
case Operator.greaterThan:
return actualValue > expectedValue;
case Operator.littleThan:
return actualValue < expectedValue;
case Operator.greaterOrEqual:
return actualValue >= expectedValue;
case Operator.littleOrEqual:
return actualValue <= expectedValue;
}
I advise you to implement your code differently.
The reasons:
It might be short, but it's not easy to understand what's going on
Using isNaN isn't the best option here: isNaN("") returns false as well
You better try to convert the value into a number and check if that's NaN or not (as #smnbbrv wrote):
if (typeof expectedValue === "string" && !Number.isNaN(Number(expectedValue))) {
expectedValue = Number(expectedValue);
}
Edit
You can pass your value as any:
isNaN(ctualValue as any)
To bypass the compiler check.
You should not solve it because this is how TypeScript works.
Just cast the input to number first
Number("10") // 10
Number("abc") // NaN
and then check the result with the isNan function:
isNaN(Number("abc"))
As ironically only numbers can be NaN, you need to transform strings into numbers first.
A very simple way to do this is the unary plus operator.
So you can do a simple isNaN(+"10").
Keep in mind that thing like +"", +" " and +"\n" are 0!
First of all, only values of type number can be NaN. So if the static context tells you your value is of type string for example, you can be sure that it is not a NaN. If you have a value with type string|number (which should be avoided btw) you can still decide how you handle this. Strictly speaking, the string value "foo" is not NaN, as NaN is a specific value specified in the IEEE standard for float numbers. But still, in javascript, isNaN("foo") will be true, as the function will coerect the string to a number first, and that coerection results in a NaN. Typescript tries to take advantage of types here, it tries to prevent you from using isNaN where you should not.
You can solve this by using parseInt inside your isNaN. The check isNaN will still work if the parseInt returns NaN. And your Typescript error will be solved.
if (typeof actualValue === "string" && !isNaN(parseInt(actualValue, 10))) {
actualValue = +actualValue;
}
In the accepted answer, !Number.isNaN(Number(expectedValue)) still returns true for empty string ('') and whitespace strings (' '). And converting these to number will result in 0.
I'm not a JavaScript developer, and – especially coming from .Net – it looks insane to me as well, but this is what I've done that seems to work:
private static isNumber(value: any): boolean {
return (typeof value === 'number' && !isNaN(value))
|| ((typeof value === 'string') && value.trim() != '' && !isNaN(Number(value)))
}
If you know a saner solution, be sure to edit this!
console.log(isNumber([])); // false
console.log(isNumber({})); // false
console.log(isNumber("")); // false
console.log(isNumber(" ")); // false
console.log(isNumber(" 1 ")); // true <= note
console.log(isNumber(" 1 2")); // false
console.log(isNumber("1")); // true
console.log(isNumber(1)); // true
Found this answer from Google, and reached my answer from the various answers and comments here; my answer is to use:
isNaN(Number(string))
This will correctly tell me if the string is a number.
I was previously using parseInt(), but this fails if the string is something like 123abc as parseInt just discards the letters (useful sometimes, but not here).
Note: I'm happy that Number('') evaluates to zero, but if your not, this isn't the solution!
Passing isNaN(value as unknown as number) satisfied my compiler.
In my case, I was using isNaN() to prevent "NaN" from flashing while data loaded. This allowed me to pass a string into isNaN() since the interface expected a string.

Curious how others would create a fallback for this: som var = number 0 || false?

so, I came across a bug and thought it was interesting. Once I sat and thought about it for 5 seconds, it made sense but curious how one would get past it in the future.
so, I have some hashes set up in an obj. (snippet of code from a larger obj).
someBigObj : {
someObj : {
item1 : 0
item2: 1
item4: 2
item3: 3
}
}
So, I set it up this way because I need to reference an Array position that corresponds to data that is associated with those items.
So, if I happen to reference item1 -- look what we get.
var varReference = someBigObj.someObj['item1'] || false;
// which is equivalent to
var varReference = 0 || false;
see what happens there? that reference is 0. So varReference is always false. I actually want the number 0 in this case because I need to access an array element. I think stringing it is odd to me, because it is not a string, but rather an integer. How can I still use this fallback of || false, but actually get the number 0 to be seen as a valid value.
Note: I understand I can explicitly test etc.. just curious if there is a a shortcut or native js (that I am unaware of) that solves my solutions. figured something like would work but didn't.
Number(0) || false
additional note: I ended not putting a || false, as even if it it's not referenced correctly there is no error. So it doesn't actually matter, but I always like to have fallbacks so that is why I am curious.
If you want falsey values to pass your test, then the test probably needs to look explicitly for undefined, not just a falsey value.
var varReference = someBigObj.someObj['item1'] !== undefined ? someBigObj.someObj['item1'] : false;
Keep in mind that lots of legitimate values are falsey such as 0, "", null (and others).
You can use an inline if to check if your value is undefined explicity.
var varReference = (typeof(someBigObj.someObj['item1']) !== 'undefined') ? someBigObj.someObj['item1'] : false;
Instead of trying to look at the value in the property (and its falsiness, which fails you sometimes), you should check whether the property exists in the object with the in operator:
var varReference = 'item1' in someBigObj.someObj
? someBigObj.someObj['item1']
: false;
which can be simplified to
var varReference = 'item1' in someBigObj.someObj && someBigObj.someObj['item1'];

Why is angular.isNumber() not working as expected?

It appears as if AngularJS's angular.isNumber is not working. It doesn't work with strings that are numbers. Am I doing something wrong? Should I just use isNaN()?
angular.isNumber('95.55') == false
angular.isNumber('95.55' * 1) == true
angular.isNumber('bla' * 1) == true
angular.isNumber(NaN) == true
I need something to see if a string is a number (when it actually is) and angular.isNumber() won't let me do that unless I multiply by 1, but if I do that then it will always be true. Also NaN is not a number (by definition) and so should return false.
In JavaScript, typeof NaN === 'number'.
If you need to recognise a String as a Number, cast it to Number, convert back to String and compare this against the input, for example.
function stringIsNumber(s) {
var x = +s; // made cast obvious for demonstration
return x.toString() === s;
}
stringIsNumber('95.55'); // true
stringIsNumber('foo'); // false
// still have
stringIsNumber('NaN'); // true
I was working on the same problem and I was trying to work around that edge case. So I created a slightly different approach.
FIDDLE
function isStringNumber(str) {
var parsed = parseFloat(str);
var casted = +str;
return parsed === casted && !isNaN(parsed) && !isNaN(casted);
}
Use it as below,
angular.isNumber(eval('99.55'))
for other expressions also we may use eval(input).
Note: eval() is a javascript method
Edit:
It is not recommended to use eval(), as document says Never use eval()!
Thanks #Diogo Kollross

Categories

Resources