I am struggling to define multiple variables:
var city_NAME = ("Birmingham" , "London");
//**various code i can't share**
if(thisLoc.getName() == City_NAME) {
The issue solely lies on the:
var city_NAME = ("Birmingham" , "London");
because it is only printing out the second city (London)
Remove the (), and then either:
Make it an array
var CITY_NAMES = ["Birmingham", "London"];
or
Declare two variables
var CITY_NAME1 = "Birmingham",
CITY_NAME2 = "London";
I'd strongly recommend #1.
By including the (), you're grouping the items on the right-hand side into an expression with the comma operator. The comma operator is interesting: It evaluates its left-hand operand, then throws that result away, evaluates its right-hand operand, and takes that result.
The evaluation of expression ("Birmingham" , "London") will return "London".
The expression evaluates before is being assigned to a variable. This is why the city_NAME variable equals "London". You cannot pass multiple variables like that.
Possible fix:
You could, however, create an array of cities like this
var city_NAME = ["Brimingham", "London"];
and then check if your city exists in the array using indexOf() method:
if(city_NAME.indexOf(thisLoc.getName()) !== -1) {
//(...)
}
Related
If I have a ternary that is testing for a greater than/less than condition and that value is then assigned back to the original variable, is there short hand for that?
var firstVar = 1
var secondVar = 2
firstVar = firstVar > secondVar ? firstVar : secondVar
Is there a simpler way to write line 3?
I can think of another possible one-liner shortcut for your test, using || operator (logical OR).
var firstVar = 1;
var secondVar = 2;
firstVar > secondVar || (firstVar = secondVar);
console.log(firstVar);
Basically, expression on third line returns true, if first operand is evaluated as true (whole expression will return "truthy" return value of expression in first operand in general). Otherwise, it will return expression in second operand (return value of variable assignment in this case). However, return value of this whole expression isn't assigned to any variable, because goal was only to perform specific assignment (second operand), if given condition (first operand) wasn't satisfied.
Also, this method might not be as intuitive as simple if statement, because variable assignment can only happen, if condition in first operand is not satisfied. It will work like variable assignment in else statement after empty if statement from previous answer. Or you can inverse statement in first operand, if this pattern is not matching your original logic.
Note: Variable assignment in second operand has to be in parentheses, because it has lower precedence than logical OR. You might want to check this table on MDN, if you are not sure about precedence of operators while constructing expressions.
I will go with a simple if statement which only assigns the value if the condition is true.
var firstVar = 1;
var secondVar = 2;
if (firstVar <= secondVar) firstVar = secondVar;
console.log(firstVar);
Following this tutorial, what do these lines mean?
var join = require('path').join
, pfx = join(__dirname, '../_certs/pfx.p12');
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
How could these lines easier be written?
In this case, the comma separates two variables, and that's it, it's the same as writing
var join = require('path').join;
var pfx = join(__dirname, '../_certs/pfx.p12');
Instead one can do
var join = require('path').join,
pfx = join(__dirname, '../_certs/pfx.p12');
In this case, the comma is just a seperator, much as it would be an object literal or array.
The comma operator, which is only an operator when it acts on two expressions, one on the left side, and one on the right side, can be used when you want to include multiple expressions in a location that requires a single expression.
One example would be in a return statement
[1,2,3].reduce(function(a,b,i) {
return a[i] = b, a; // returns a;
},[]);
etc...
It's essentially the same as a semi-colon in many cases, so you could rewrite it as this:
var join = require('path').join;
var pfx = join(__dirname, '../_certs/pfx.p12');
The difference comes down to lines like declaring variables (like your example), in which the var is applied to each element in the comma-separated list. Beyond that, it's more or less a semi-colon, though it's not recommended to use the comma syntax in most cases.
I personally prefer it for the variables, because I think this look a little cleaner:
var a = 5,
b = 6,
c,
d;
But others dislike it.
I have the following test case in a coding kata for javascript:
*word-count_test.js
var words = require('./word-count');
describe("words()", function() {
it("handles properties that exist on Object’s prototype", function() {
var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, toString: 1, "ok?": 1};
expect(words("reserved words like prototype and toString ok?")).toEqual(expectedCounts);
});
});
The following code will not pass this:
code v1
var words = function(phrase) {
var wordCountAry = {};
// split on whitespace, including newline
phrase.split(/\s/).forEach(function(oneWord) {
if (!wordCountAry[oneWord]) {
wordCountAry[oneWord] = 1;
} else {
wordCountAry[oneWord]++;
}
});
return wordCountAry;
};
module.exports = words;
But something like the following counter line will not trigger the error:
code v2
wordCountary[word] = (+wordCountary[word] || 0) + 1
So what is so special about that unary "+" operator?
A standard JavaScript object prototype has predefined properties, such as:
toString()
constructor()
When you test those property names using typical conditional logic, they will appear as existent, e.g.
var x = {};
if (x['toString']) {
// this gets executed
}
The second code sample works around that issue with two tricks:
+x['toString'] || 0;
First, the property is coerced into a numeric value by using the unary plus operator. For functions or undefined values, the coercion yields NaN.
Secondly, the logical or operator is used to coalesce the left hand and right hand expression; if the right hand operand evaluates to false (that includes NaN) it will yield the right hand operand, otherwise it returns the left hand operand.
In this manner, either an undefined property value or a function value will yield 0 and therefore it will work as expected.
It's not really about "reserved" names (those are another matter in JavaScript, e.g. class although it's not reserved anymore in ES6), but about inherited properties.
wordCountAry is an object, so it already has a toString method. So when you test
if (!wordCountAry[oneWord])
with the words "toString" the condition will be false (because wordCountAry["toString"] is trueish (it's a function).
So you need to use a condition that will work when the property is not a number (which is the case with the Number coercion of a function with unary +), or, to be safer, also check if it is inherited (hasOwnProperty).
When you are creating your wordCountAry object, you can can pass null as the prototype, and this should solve your problem. So, instead of initializing it to {}, see how you can set it's prototype to null.
Which is the better way for conditional variable assignment?
1st method
if (true) {
var myVariable = 'True';
} else {
var myVariable = 'False';
}
2nd Method
var myVariable = 'False';
if (true) {
myVariable = 'True';
}
I actually prefer 2nd one without any specific technical reason. What do you guys think?
try this
var myVariable = (true condition) ? "true" : "false"
There are two methods I know of that you can declare a variable's value by conditions.
Method 1: If the condition evaluates to true, the value on the left side of the column would be assigned to the variable. If the condition evaluates to false the condition on the right will be assigned to the variable. You can also nest many conditions into one statement.
var a = (true)? "true" : "false";
Nesting example of method 1: Change variable A value to 0, 1, 2 and a negative value to see how the statement would produce the result.
var a = 1;
var b = a > 0? (a === 1? "A is 1" : "A is not 1") : (a === 0? "A is zero" : "A is negative");
Method 2: In this method, if the value of the left of the || is equal to zero, false, null, undefined, or an empty string, then the value on the right will be assigned to the variable. If the value on the left of the || does not equal to zero, false, null undefined, or an empty string, then the value on the left will be assigned to the variable.
Although the value on the left can be an undefined value for JS to evaluate the condition but the variable has to be declared otherwise an exception will be produced.
var a = 0;
var b = a || "Another value";
An alternative way of doing this is by leveraging the ability of logical operators to return a value.
let isAnimal = false;
let isPlant = true;
let thing = isAnimal && 'animal' || isPlant && 'plant' || 'something else';
console.log(thing);
In the code above when one of the flags is true isAnimal or isPlant, the string next to it is returned. This is because both && and || result in the value of one of their operands:
A && B returns the value A if A can be coerced into false; otherwise, it returns B.
A || B returns the value A if A can be coerced into true; otherwise, it returns B.
Answer inspired by this article: https://mariusschulz.com/blog/the-and-and-or-operators-in-javascript
PS: Should be used for learning purposes only. Don't make life harder for you and your coworkers by using this method in your production code.
You could do a ternary, which is a lot shorter (and no darn curly braces):
var myVariable = (true) ? 'True' : 'False';
Another cool thing is that you can do multiple assignment based on a conditional:
let [long_str, short_str] = a.length > b.length ? [a, b] : [b, a]
Third way when you are storing only true false in variabel then use
var myVariable =(condition_written_in_if);
Just for completion, there is another way in addition to all the others mentioned here, which is to use a lookup table.
Say you have many possible values, you could declaratively configure a Map instead of using an if, switch or ternary statement.
Object map = {
key1: 'value1',
key2: 'value2,
keyX: 'valueX'
};
var myVariable = map[myInput];
This works even for booleans:
Object map = { true: 'value1', false: 'value2 };
var myVariable = map[myBoolean];
For booleans you would probably do it the 'normal' way though with logic operators specifically designed for that. Though sometimes it can be useful, such as:
portability: you can pass a map around
configurability: maybe the values come from a property file
readability: if you don't care it's a boolean or not, you just want to avoid conditional logic and reduce cognitive load that way
Note there is some overlap between the advantages using a lookup map and advantages of using a function variable (closure).
The first solution uses only one assignment instead of 1,5 by average in the second code snippet. On the other hand the first code snippet is less readable as people not familiar with JavaScript might not realize that the scope of a variable is not block oriented by function oriented - on other languages with C-like syntax myVariable would not be accessible outside if and else blocks.
In other words both solutions have disadvantages. What about ternary operator:
var myVariable = condition? 'True' : 'False';
or if you don't care about the camel-case (although I understand this is just an example, not a real code);
var myVariable = (!!condition).toString();
If you tired of ternary operator then use IIFE
Another way would be to use Immediately Invoked Function Expression. The good thing about it is that it can hold some logic and can be encapsulated from the outside world.
const direction = "n";
const directionFull= (() => {
switch(direction ){
case "n": return "north";
case "s": return "south";
case "w": return "west";
case "e": return "east";
}
})()
console.log(directionFull);
I would prefer 2nd option too, no technical reason but for the sake of easy to read code, readability is very important in code.
If you see the second option, from processing point of view only one check will ever be executed, saved some very minute processing time, so there is only one check in second case.
It depends on the use for me. If I have code that I only want to run if true, but with no extra code for false, I'll use the second. If I want to execute some code on true, and different on false, I use the first. It all depends on use, but the general rule for me is to write once. Keep it clean, keep it simple, and keep it short
Maybe you simply need && operator to check if boolean is true, if it is, assing "myVariable" to true.
var myVariable = 'False';
true && myVariable = 'True';
If all you need to do is convert a boolean to a string, you should do so explicitly:
var myBool = true;
var myVariable = myBool.toString(); // 'true'
// '' + myBool, ''.concat(myBool), etc. also work
If it's important that the first letter be capitalized, as in your example, that is not difficult to do; see e.g. this answer.
Another approach with Map and Object: (Maps are more flexible with key types and Objects are more readable IMHO)
const condition_var = 'e'
const options1 = new Map([ ['n','north'],['s','south'],['e','east'],['w','west']])
const myVar1 = options1.get(condition_var) || null
const options2 = {n:'north', s:'south', e:'east', w:'west'}
const myVar2 = options2[condition_var] || null
console.log(myVar1)
console.log(myVar2)
At wtfjs, I found that the following is legal javascript.
",,," == Array((null,'cool',false,NaN,4)); // true
The argument (null,'cool',false,NaN,4) looks like a tuple to me, but javascript does not have tuples!
Some quick tests in my javascript console yields the following.
var t = (null,'cool',false,NaN,4); // t = 4
(null,'cool',false,NaN,4) === 4; // true
(alert('hello'), 42); // shows the alert and returns 42
It appears to behave exactly like a semicolon ; separated list of statements, simply returning the value of the last statement.
Is there a reference somewhere that describes this syntax and its semantics? Why does it exist, i.e. when should it be used?
You are seeing the effect of the comma operator.
The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand.
The resultant value when a,b,c,...,n is evaluated will always be the value of the rightmost expression, however all expressions in the chain are still evaluated (from left to right).
As already explained this behaviour is caused by , operator. Due to this the expression (null,'cool',false,NaN,4) will always evaluate to 4. So we have
",,," == Array(4)
Array(4) - creates new array with allocated 4 elements. At the time of comparison with the string this array is converted to string like it would be with Array(4).toString(). For arrays toString acts like join(',') method called on this array. So for the empty array of 4 elements join will produce the string ",,,".
Try this alert((null,'cool',false,NaN,4)) and then you can see.
demo
The reason is because the comma operator evaluates all the statements and return the last one.
Think of this line: a = 1, b = 2, c = 3; it will run each expression so in essence it will set the variables to what you want and return the last value (in this case 3)