Why can you only use expressions in JSX, not statements? - javascript

Before proceeding, I should mention that yes, I have already read the questions and answers on "Use if statement in React JSX" and its different variants on SO and elsewhere.
However, these posts are more about how to get around without using statements in JSX. I'd like to know why statements aren't allowed in JSX, for which I cannot find any posts on.
I am reading the official documentation on this called "If-Else in JSX", and the reason given for why is, quote,
JSX is just syntactic sugar for function calls and object construction
They go on to contrast the following two pieces of code, the first of which works and the second one doesn't work:
This is valid:
// This JSX:
ReactDOM.render(<div id="msg">Hello World!</div>, mountNode);
// Is transformed to this JS:
ReactDOM.render(React.createElement("div", {id:"msg"}, "Hello World!"), mountNode);
This is not valid:
// This JSX:
<div id={if (condition) { 'msg' }}>Hello World!</div>
// Is transformed to this JS:
React.createElement("div", {id: if (condition) { 'msg' }}, "Hello World!");
I would really like to understand this under the hood. First of all, in the second example, I would never have thought to write JavaScript inside the id property of an HTML element. In fact, this is the first time I've seen code of any sort used in an id property. If I were to try to write an if conditional, I would just do it in curly braces within the render return expression, as a naïve analog of other JS that works (like map or ternary expression).
render() {
return (
{if ...
}
)
I have no doubt that it is perfectly clear to the author of this document that this slightly unorthodox example explains their assertion that "JSX is just syntactic sugar for function calls and object construction", but I cannot figure out how.

Let's start conceptually. What are the definitions of statement vs expression?
A statement does something. An expression evaluates to a value.
JSX is meant to be built up and passed around from one segment of your code to another, eventually ending up as HTML. The name even suggests this "JavaScript to XML" conversion.
The whole point of it is to return a "value" of HTML nodes. JSX kindly allows for expressions, because those help you determine values.
Perhaps it will help to take a closer look at the difference between a ternary expression and an if/else.
If/Else
if(isSaturday){
wakeUpHour = 10;
}else{
wakeUpHour = 7;
}
Ternary
wakeUpHour = isSaturday ? 10 : 7;
Those both accomplish the same thing, right? But under the hood they are operating differently. In English, the if/else might read:
If the value of 'isSaturday' is truthy, run the code inside the curly braces
Assign the number 10 to 'wakeUpHour'
Otherwise, run the code inside the next curly brace
Assign the number 7 to to 'wakeUpHour'
The ternary statement also has two parts:
If isSaturday is truthy, have a value of 10. Otherwise have a value 7.
Assign this value to 'wakeUpHour'
We think of those as accomplishing the same thing. The key point here is that the ternary expression itself is just a value. It's not lines of codes. To do something with that value required another part, assigning it.
In JSX, we don't want to be assigning things. We want values. So we are just taking the ternary expression (a value), not the assignment part or any other code statements.
Finally, and hopefully not to add to your confusion, I would note that you can define functions in JSX.
const myJSX = <button onClick={ () => { return 'hello'; } }>Say hello</button>
Wait, what? I thought we couldn't execute lines of code. It's not executing the lines of code, it's defining them; it's rendered to:
var myJSX = React.createElement("button", {onClick: () => {
return 'hello';
}}, "Say hello");
Compare that with trying to just throw in an if/else statement:
const myJSX = <span>{ if(true){ return 'hello'; } }</span>
Which would try to render as:
var myJSX = React.createElement("span", null, if(true){ return 'hello' });
That doesn't work, for the same reason that you can't normally pass an unencapsulated chunk of code into an argument of a function.

Maybe this is irrelevant to your question, but I've been redirected here because one of my questions said to be duplicate to your question.
if you want to do multi-line JavaScript code, you can wrap your JS code with an IIFE, for example:
<b>
{(() => {
const a = [1, 2, 3].find((el) => el === 2)
// as much code as you want ...
// ...
// ...
console.log(a)
})()}
</b>

Related

Testing out my understanding of expressions and statements with two examples [duplicate]

For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true. However, none of the articles and SO questions I read provided me with a cheatsheet of sorts to distinguish between the 3 (or the 2, expressions vs statements).
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var. The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
And then there are declarations, is every declaration also a statement ?
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
I would be more than glad if someone could ask the above questions (or at least some of them), or if someone could provide me with some sort of a cheatsheet. Why is there so little material on a topic that appears to be so simple in such a popular language ?
There are standard definitions of these terms that all languages, including JS, follow. My takes on them are the following:
An expression produces a value and can be written wherever a value is expected.
A statement on the other hand is is a standalone unit of execution. It does not return anything.
A declaration is a statement in which a value is assigned to a variable.
All declarations are statements, but not all statements are declarations.
Most statements and all declarations contain expressions.
Javadoc also gives nice, succinct definitions:
An expression is a construct made up of variables, operators, and method invocations, which are constructed according to the syntax of the language, that evaluates to a single value.
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution.
Now, your theory on keywords being necessarily involved is incorrect. Here is a statement that includes a keyword:
break;
And here is one that does not:
foo();
In the first example I execute a break, whereas in the second one I call a function. Both are statements, however only one includes any special keyword.
A function is not a statement. A function call is a statement, as demonstrated above. In the case of a function that returns something, the call can also be a declaration:
var bar = foo();
And for your final question, the reason there is so little material out there on this is because this is merely an issue of semantics. People do not linger on the exact definitions of these terms.
For further clarification, I recommend taking a look at this blog post by Axel Rauschmayer that specifically talks about the difference between statements and expressions in JS.
For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true.
A declaration is any construct that "declares" a variable name into existence at compile/load time before the program executes. All declared names in their respective scopes are therefore known in advance.
Statements and expressions differ from each other in that the former does not produce a value a result, whereas the latter does. So an expression may be used anywhere a value is expected, and a statement may not be used in those places.
An expression statement is one where the statement is a single expression, or several included in an expression that requires zero or more sub-expressions. While the expression(s) produce a result, the statement does not.
Here's an expression:
x = foo() + 2
A full expression statement could be explicitly shown by adding a semicolon to the end.
x = foo() + 2;
The first example can be wrapped in a set of parens, because the parens as a grouping operator expects an expression, often provided as several expressions joined by the comma operator.
The second example can not be wrapped in parens (if you include the semicolon) because then it is a statement, and does not produce a value, which the grouping operator expects to receive and return as its own value.
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var.
While most statements do involve a keyword, not all do. Most notably, the block statement has no keyword. Instead it uses a set of curly braces to delimit its start and end.
The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
There are three kinds of functions in JS. If you're talking about the ones that use the function keyword, then the may be either a declaration or an expression depending on its context.
If the function is used where an expression would be expected, then it's evaluated as an expression that returns a new function object. If not, then it is expected to be a declaration, which basically creates a variable with the function object assigned to it. As a declaration, a function name is required (for the variable name). As an expression, it's optional.
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
If the resulting value is ignored, it would be useless, given that example. But here's another expression statement.
foobar();
Now we have a side effect from the function call, which is most likely desired and useful.
Let's talk about expressions first. As you say, an expression is something that evaluates to a value. A function is a value. A function call, on the other hand, is an expression.
I don't agree with the characterization of a statement as something that "performs an action". As you say, calling a function involves running the function body, which consists of statements and declarations, so it performs actions "on the inside".
A better way to look at it is that expressions, statements, and declarations are syntactic categories. They arise from trying to describe the structure of the JavaScript grammar. See e.g. the ECMAScript 8 specification on expressions, statements, and declarations.
An expression statement like 20 + 5 * 2 / 3; is indeed useless because it has no effects, and the only point of a statement is its effects. But there are other kinds of much more useful expression statements:
a function call: foo();
assignment: x = 42; (= is an operator and can be used in expressions)
increment/decrement: i++; (similarly, ++ is an operator)
Statements other than expression statements tend to start with a special keyword to avoid syntactic ambiguity: The parser wants to be able to tell what kind of construct it is dealing with right from the start. Hence we get:
if statements: if (EXPR) STMT
while statements: while (EXPR) STMT
return statements: return; or return EXPR;
etc.
However, there are some statements that don't start with a keyword:
the empty statement: ;
a block: { ... }
Finally, declarations. In JavaScript the distinction between statements and declarations is somewhat arbitrary. The grammar distinguishes between the two, but in practice you can often treat them the same (e.g. the contents of a block statement are defined as a sequence of statement list items, and a statement list item is defined to be either a statement or a declaration). Declarations include:
function declarations: function foo() { ... } (including variants such as generators (function* foo() { ... }) and asynchronous functions (async function foo() { ... }))
let and const
class declarations
(But for some reason var foo; is classified as a statement, not a declaration.)

JavaScript: declarations vs expressions vs statements

For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true. However, none of the articles and SO questions I read provided me with a cheatsheet of sorts to distinguish between the 3 (or the 2, expressions vs statements).
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var. The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
And then there are declarations, is every declaration also a statement ?
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
I would be more than glad if someone could ask the above questions (or at least some of them), or if someone could provide me with some sort of a cheatsheet. Why is there so little material on a topic that appears to be so simple in such a popular language ?
There are standard definitions of these terms that all languages, including JS, follow. My takes on them are the following:
An expression produces a value and can be written wherever a value is expected.
A statement on the other hand is is a standalone unit of execution. It does not return anything.
A declaration is a statement in which a value is assigned to a variable.
All declarations are statements, but not all statements are declarations.
Most statements and all declarations contain expressions.
Javadoc also gives nice, succinct definitions:
An expression is a construct made up of variables, operators, and method invocations, which are constructed according to the syntax of the language, that evaluates to a single value.
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution.
Now, your theory on keywords being necessarily involved is incorrect. Here is a statement that includes a keyword:
break;
And here is one that does not:
foo();
In the first example I execute a break, whereas in the second one I call a function. Both are statements, however only one includes any special keyword.
A function is not a statement. A function call is a statement, as demonstrated above. In the case of a function that returns something, the call can also be a declaration:
var bar = foo();
And for your final question, the reason there is so little material out there on this is because this is merely an issue of semantics. People do not linger on the exact definitions of these terms.
For further clarification, I recommend taking a look at this blog post by Axel Rauschmayer that specifically talks about the difference between statements and expressions in JS.
For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true.
A declaration is any construct that "declares" a variable name into existence at compile/load time before the program executes. All declared names in their respective scopes are therefore known in advance.
Statements and expressions differ from each other in that the former does not produce a value a result, whereas the latter does. So an expression may be used anywhere a value is expected, and a statement may not be used in those places.
An expression statement is one where the statement is a single expression, or several included in an expression that requires zero or more sub-expressions. While the expression(s) produce a result, the statement does not.
Here's an expression:
x = foo() + 2
A full expression statement could be explicitly shown by adding a semicolon to the end.
x = foo() + 2;
The first example can be wrapped in a set of parens, because the parens as a grouping operator expects an expression, often provided as several expressions joined by the comma operator.
The second example can not be wrapped in parens (if you include the semicolon) because then it is a statement, and does not produce a value, which the grouping operator expects to receive and return as its own value.
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var.
While most statements do involve a keyword, not all do. Most notably, the block statement has no keyword. Instead it uses a set of curly braces to delimit its start and end.
The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
There are three kinds of functions in JS. If you're talking about the ones that use the function keyword, then the may be either a declaration or an expression depending on its context.
If the function is used where an expression would be expected, then it's evaluated as an expression that returns a new function object. If not, then it is expected to be a declaration, which basically creates a variable with the function object assigned to it. As a declaration, a function name is required (for the variable name). As an expression, it's optional.
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
If the resulting value is ignored, it would be useless, given that example. But here's another expression statement.
foobar();
Now we have a side effect from the function call, which is most likely desired and useful.
Let's talk about expressions first. As you say, an expression is something that evaluates to a value. A function is a value. A function call, on the other hand, is an expression.
I don't agree with the characterization of a statement as something that "performs an action". As you say, calling a function involves running the function body, which consists of statements and declarations, so it performs actions "on the inside".
A better way to look at it is that expressions, statements, and declarations are syntactic categories. They arise from trying to describe the structure of the JavaScript grammar. See e.g. the ECMAScript 8 specification on expressions, statements, and declarations.
An expression statement like 20 + 5 * 2 / 3; is indeed useless because it has no effects, and the only point of a statement is its effects. But there are other kinds of much more useful expression statements:
a function call: foo();
assignment: x = 42; (= is an operator and can be used in expressions)
increment/decrement: i++; (similarly, ++ is an operator)
Statements other than expression statements tend to start with a special keyword to avoid syntactic ambiguity: The parser wants to be able to tell what kind of construct it is dealing with right from the start. Hence we get:
if statements: if (EXPR) STMT
while statements: while (EXPR) STMT
return statements: return; or return EXPR;
etc.
However, there are some statements that don't start with a keyword:
the empty statement: ;
a block: { ... }
Finally, declarations. In JavaScript the distinction between statements and declarations is somewhat arbitrary. The grammar distinguishes between the two, but in practice you can often treat them the same (e.g. the contents of a block statement are defined as a sequence of statement list items, and a statement list item is defined to be either a statement or a declaration). Declarations include:
function declarations: function foo() { ... } (including variants such as generators (function* foo() { ... }) and asynchronous functions (async function foo() { ... }))
let and const
class declarations
(But for some reason var foo; is classified as a statement, not a declaration.)

What does the colon mean in this JavaScript snippet (not an object literal)?

I apologize for posting a duplicate-looking question, (I know, that there is a bunch of similar titled questions here), but none of the questions already present seems to suit my case.
In short, what does the colon do here:
<script>
'use strict';
foo: 1;
//whatever else
</script>
I supposed this to be a syntax error, but it's not. And it's not a label, I think, since adding a line break foo; throws Uncaught SyntaxError: Undefined label 'foo' (though a doc page suggests exactly this, that it's a label).
I suppose this is some recent addition to the JavaScript syntax, since I have never heard of such use of the colon.
If anyone wonders, why I'm asking this, this is my explanation: I was reading an MDN doc page and there is an example:
var func = () => { foo: 1 };
// Calling func() returns undefined!
It shows, that the curly braces in this case are treated as block delimiters and not an object literal. So I supposed, that somehow foo: 1 on its own must be syntactically legal. And indeed it is.
There is a question, which is supposed to cover every use of the colon in JavaScript, but it doesn't mention this, and no answer there does this either.
If you'd have read further down the page you linked, you would see why it was written like that.
var func = () => { foo: 1 };
This is an attempt to return an object from a arrow function.
That doesn't work for reasons explained here:
This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo is treated like a label, not a key in an object literal). (source)
So the returned value needs to be wrapped in parentheses:
var func = () => ({foo: 1});
To actually answer your question:
It's a label.
You can't just take the foo: 1 out of context like that.

ES6 Arrow function without curly braces

I'm having a hard time understanding the following ES6 syntax. I read the docs quite a bit and it seems like there is more than one change happening here:
const renderInput = props =>
<div>
<label>{props.placeholder}</label>
</div>
Would the above be equivalent to:
const renderInput = function renderInput(props) {
return <div>
<label>{props.placeholder}</label>
</div>
}
?
Yes, that is correct. When you have only one expression, and it's the expression you wish to return from the function, you may omit the curly brackets.
Since <div><label>{props.placeholder}</label></div> is, in fact, a single expression (it gets transpiled to React.createElement(......) or something like that), and you wish to return it from renderInput, that is indeed how you use the no-brackets version of the arrow function.
If you had wished to use variables or do some other computation (conditions, for loops, etc), you wouldn't have been able to omit the brackets.

JavaScript if conditional expression with 3 parameters?

this my very first question on stackoverflow, so please forgive me if I am not getting all the etiquette yet.
I am trying to work with a previous script written in JavaScript. There is an if conditional expression in the code that I do not understand. The reason it is confusing to me is because it has 3 arguments. I have never seen an if conditional expression like this in any language, or even in the JavaScript "if" tutorial on http://www.w3schools.com/js/js_if_else.asp. The code snippet I am working with looks like this
if (this.css(alldivs[i], "contentdiv", "check")){ //check for DIVs with class "contentdiv"
setting.contentdivs.push(alldivs[i])
alldivs[i].style.display="none"}
My question is: What does if(foo, bar, "check") mean? Is this an old deprecated string comparison function in JavaScript? Why are there 3 variables in the if conditional expression instead of 2?
What are the advantages of the previous code, compared to something like:
if (this.css(alldivs[i] === "contentdiv")
Thank you for your help.
What does if(foo, bar, "check")
When you have a conditional with comma separated expressions, only the last one matters (the previous ones are also executed, though).
Then, the code is equivalent to:
foo;
bar;
if("check") { /*...*/ }
But you have this:
if (this.css(alldivs[i], "contentdiv", "check"))
That means:
Run this.css(alldivs[i], "contentdiv", "check"), where this is an object which has a the method css (a method is a function which is a property of an object).
Check the returned value.
Maybe you will understand it better this way:
var temp = this.css(alldivs[i], "contentdiv", "check");
if(temp) { /* ... */ }
Let's break down what's happening here. In this line:
if (this.css(alldivs[i], "contentdiv", "check"))
You have two things going on.
You have a function call this.css(alldivs[i], "contentdiv", "check").
You have an if() that checks the return value from that previous function call
This would be equivalent to this expanded code:
var returnVal = this.css(alldivs[i], "contentdiv", "check");
if (returnVal) {
setting.contentdivs.push(alldivs[i]);
alldivs[i].style.display="none";
}
This:
if (this.css(alldivs[i], "contentdiv", "check")) {
Would be equivalent to this:
var temp = this.css(alldivs[i], "contentdiv", "check");
if (temp) {
So you see, it's not an if taking three parameters. It's an if with one parameter which happens to be a function call that takes three arguments.
It's hard to know what answer is going to help you, as your question is about code that doesn't appear in your sample. In this case:
if (this.css(alldivs[i], "contentdiv", "check"))
The condition is based on the return value of the call to this.css. In the sample you seem interested in:
if(foo, bar, "check")
The answer is that it's always going to evaluate as True because of the way the Comma Operator behaves in JavaScript.

Categories

Resources