Not sure this problem is because of a bug in jsFiddle or my misunderstanding of the round bracket of javascript. I have this code:
let x = 5
(x > 0) && console.log('hello')
This doesn't work. However, the following without bracket works.
x > 0 && console.log('hello')
My impression is that i can use the round brackets in condition to group things together. I have no idea why my first line of code does not work. Is it my misunderstanding of round bracket?
I am actually trying to teach someone a more advance example in this jsFiddle code. https://jsfiddle.net/x616atk0/
It does not work, because you're missing a semicolon after let x = 5
The code should be:
let x = 5;
(x > 0) && console.log('hello');
Otherwise, your code can be translated to this:
let x = 5(x > 0) && console.log('hello');
And of course 5 isn't a function, and x (which you're using in the expression which evaluated value will be passed as argument) isn't defined yet.
The error is misleading because you're using the same variable that you're defining as argument. If you had
let x = 5
(5 > 0) && console.log('hello');
You would get: TypeError: 5 is not a function which is exactly the problem.
This is why semicolons are important!
Do you recommend using semicolons after every statement in JavaScript?
yes, I absolutely do
You forgot to put semicolons at the end of your lines, which is resulting in the error. When you do this:
let x = 5
let y = 4
x > 0 && console.log('code 4')
(x > 0) && (y > 0) && console.log('code 5');
because the third line ends in a ), the interpreter thinks you're calling the result of console.log with the (x > 0) argument:
let x = 5
let y = 4
x > 0 && console.log('code 4')(x > 0) && (y > 0) && console.log('code 5');
But console.log returns undefined: it doesn't return a function, so of course you can't call it as a function.
Always use semicolons if you're just still learning the language, or you can easily trip yourself up.
Also, what you're doing is not a good way of doing things; while it's an interesting language quirk, it's better to test for conditions explicitly using if or the ternary operator than to use && for that.
Related
The following works:
let x = 1 && console.log("true"); (-- logs true)
let y = 0 && console.log("true"); (-- logs nothing)
The above shows that the statement before && operator is acting like an expression.
Then I tried this:
console.log(let m = 5); // Error
What is going on here? If that's an expression then why it didn't work in this case and if it's not an expression then why it worked in the first two cases?
The following works -
let x = 1 && console.log("true"); (-- logs true)
let y = 0 && console.log("true"); (-- logs nothing)
The above shows that the statement before && operator is acting like an expression
This is where you are mistaken. The && operator is used to join expressions, not statements (even though it has control flow effects). This parses as follows:
let x = (1 && console.log("true")); (-- logs true)
let y = (0 && console.log("true")); (-- logs nothing)
console.log is acting as an expression here, not let .... Function calls always return a value (which may be undefined). If you logged x and y, you'd see that x === undefined (result of 1 && undefined) and y === 0 (result of 0 && <not evaluated>).
It is probably confusing you here that && short-circuits: In the first expression, the first operand of && is 1 (truthy), so the second operand - the expression which is a call to console.log - has to be evaluated; in the second expression, the first operand of && is the falsy 0, so && short-circuits to 0, not evaluating (not calling) console.log("true").
let statements are statements and not expressions, which is why you get a syntax error in your second example.
I'm not a programmer by any means. I'm an animator trying to use JS expressions in After Effects. I'm getting an "Undefined value used in expression" error on line 1 where I define a variable.I already showed it to my friend on discord who is a cs major, and he had no clue what was wrong with it.
Here's just a paste of the code if you need it:
var count = 1;
if (framesToTime(time) % 12 == 0) {
count = count + 1
if (count % 2 == 0){
thisProperty = 95
} else {
thisProperty = 20
};
} ;
Ok I don't know why the hell this fixed it, but I changed the name of the variable from "count" to just "x" and it works now. Go figure
Try it.
var count = 1;
if (framesToTime(time) % 12 == 0) {
count = count + 1;
if (count % 2 == 0){
thisProperty = 95;
} else {
thisProperty = 20;
}
}
thisProperty;
In your code, thisProperty has become an ordinary variable. If you write its name at the end of the code, then its value will be assigned to the property.
In AE, if there is nothing inside an if statement or the if statement contains malformed/error code you will receive this error. Put a temp value inside the curly braces or something to process and ensure nothing inside will throw an error.
I also received this error with this:
pastTime = timeToFrames(time)-1;
curPos = transform.xPosition;
pastPos = transform.xPosition.valueAtTime(framesToTime(pastTime));
if (curPos-pastPos[0] != 0) {
// Here is the problem in my case. added a value here 99 to fix until finished testing.
}
else {
effect("Angle Control")("Angle")
}
if/else statements are strict
The syntax for if/else statements is strict in the JavaScript engine
and need to be written for standardized JavaScript.
https://helpx.adobe.com/after-effects/using/expression-language-reference.html*
I got this error because there was a missing semicolon.
I already know this wouldn't work If I passed something like 0 or 1, but why wouldn't it work If it managed to work with 2 and 7.
I'm still new to Javascript programming so I'm just trying to figure out why adding
if(number = number % 2 == 0) or the other wouldn't work.
Here's the code:
function even_or_odd(number) {
if(number = number % 2 == 0) {
return "Even"
}else if(number = number % 2 !== 0) {
return "Odd"
}
};
= is an assignment operator. It assigns the value of the expression on the right-hand side to a variable on the left-hand side.
== is an equality operator. It tests the equality of the result of both the left and right-hand-side expression.
Since you're using = and inadvertently assigning number to the value of your expression on the right, it will always evaluate to a truthy value and return "Even". To fix, remove the number = from each of the expressions:
function even_or_odd(number) {
if(number % 2 == 0) {
return "Even"
}else if(number % 2 !== 0) {
return "Odd"
}
};
console.log(even_or_odd(0));
console.log(even_or_odd(1));
MDN has a great section on this in their if...else page:
It is advisable to not use simple assignments in a conditional expression, because the assignment can be confused with equality when glancing over the code. For example, do not use the following code:
if (x = y) {
/* do something */
}
If you need to use an assignment in a conditional expression, a common practice is to put additional parentheses around the assignment. For example:
if ((x = y)) {
/* do something */
}
a = 1;
b = "1";
if (a == b && a = 1) {
console.log("a==b");
}
The Javascript code above will result in an error in the if statement in Google Chrome 26.0.1410.43:
Uncaught ReferenceError: Invalid left-hand side in assignment
I think this is because the variable a in the second part of the statement &&, a=1 cannot be assigned. However, when I try the code below, I'm totally confused!
a = 1;
b = "1";
if (a = 1 && a == b) {
console.log("a==b");
}
Why is the one statement right but the other statement wrong?
= has lower operator precendence than both && and ==, which means that your first assignment turns into
if ((a == b && a) = 1) {
Since you can't assign to an expression in this way, this will give you an error.
The second version is parsed as a = (1 && a == b); that is, the result of the expression 1 && a == b is assigned to a.
The first version does not work because the lefthand side of the assignment is not parsed as you expected. It parses the expression as if you're trying to assign a value to everything on the righthand side--(a == b && a) = 1.
This is all based on the precedence of the various operators. The problem here stems from the fact that = has a lower precedence than the other operators.
Because the order of operations is not what you expect. a == b && a = 1 is equivalent to (a == b && a) = 1 which is equivalent to false = 1.
If you really want to do the assignment, you need to use parentheses around it: a == b && (a = 1).
In if (a = 1 && a == b),
The operations to be first performed is 1 && a == b. 1 && the result of a == b is performed. The result of this && operation is assigned to a.
I'm working with this JS plugin, and I've encountered some syntax I've never seen before. I understand what it's doing, but I'm not sure why it works.
Here's an example of one instance of it:
settings.maxId != null && (params.max_id = settings.maxId);
Is this just taking advantage of conditionals and the single = ? Is this common syntax for JS?
In JavaScript the = operator is an expression and evaluates the assigned value. Because it is an expression it can be used anywhere an expression is allowed even though it causes a side-effect.
Thus:
settings.maxId != null && (params.max_id = settings.maxId)
Means: If settings.maxId is not null then (and only then, since && is short circuiting) evaluate the right-expression (params.max_id = settings.maxId) which in turn causes the value of settings.maxId to be assigned to params.max_id.
This is much more clearly written as:
if (settings.maxId != null) {
params.max_id = settings.maxId
}
Happy coding.
The && operator is known as "boolean AND". Typically, you'd see it in an if statement:
if (x == true && y == false) {
but that's not a restriction. You may use it in any valid expression to "combine" the boolean values of its operands into a single boolean result, according to the logical "AND" operation:
var z = (x == true && y == false);
// z is now true or false, accordingly
One of the lovely things about && is that it "short circuits". In false && true, because the first operand is false the entire expression may only evaluate to false, so the second operand is not even evaluated.
Let's check that again:
var z = (false && foo());
// z is now false
In this statement, the function foo is never even called! It doesn't have to be, for the program to know that z will be false.
This is more than an optimisation — you can rely on it.
Some silly people use this technique to rewrite conditional statements:
if (x == 0) {
foo();
}
into hard-to-read single expressions:
(x == 0) && foo();
Now, consider that assignment can be an expression just like a function call:
var a = (b = c);
Or:
var a = (b = foo());
And add in a conditional via the above technique:
var a = ((x == 0) && (b = foo()));
Now the entire expression b = foo() won't be evaluated at all if x is not 0, because of short circuiting.
We don't even need to do anything with the result of the && operation, and if we don't store it to a you're left with just:
(x == 0) && (b = foo());
which is a statement that'll assign b to the value of foo() only if x is 0.
Avoid it. It's hard to read. Just use an if statement.
this statement will assign params.max_id = settings.maxId only if settings.maxId != null due to the fact that && is a short-circuit logic operator
this behaviour is due to the fact that javascript will evaluate the condition until it's necessary. thus, if first condition is false and the second is in AND there's no need to check further