about
This article was started by the WowBar team at GitHub
Author: yvongyang
Catalog
-
Statements and Expressions
The main difference between expressions and statements in JavaScript is that a statement executes an action and an expression produces a value.Meaning is that an expression must produce a value after execution, while a statement does not necessarily produce a value.Statements are mainly used to perform actions, and programs are composed of a series of statements.
For example: ```js
//expression
name
1 + x
getNames()//statement
var name = 'yang';
function getNames() {}
var foo = getNames() {};The next section does not cover expressions, but lists the categories of expressions. The statement section describes the usage and examples of the statements. If you are clear about the expressions and the contents of the statements, you can skip to the last section of this chapter - the comparison of expressions and statements.
-
Expression
Expressions are divided into basic expressions (including basic keywords), as well as left-value expressions and operators.
##### 1. Basic expression
- this keyword
- Literal (null, Boolean literal, numeric literal, string literal)
- Initialize literal amount (array literal amount [], object literal amount {}, regular expression literal amount/ab+c/i)
- Function expression
- Class Expression
- Grouping Operator ()
- Template Literal Volume `. ${...}. `
##### 2. Left value expression
- Property Accessors
- new
- Meta attribute: new.target
- super
- function call
- Argument,...Arguments)
- import
##### 3. Operators
- Monary
delete, void, typeof, +, -, ~, !
- arithmetic
+, -, /, *, %, A++, A--, ++A, --A
- compare
<, >, <=, >=, in, instanceof, `==`, `===`, `!==`, `!===`
- condition
condition ? ifTrue : ifFalse
- assignment
=, -=, +=, *=, /=, &=, |=, deconstruction assignments such as [a, b] = [1, 2], {a, b} = {a: 1, b: 2}, etc.
- comma
,
- Displacement, Binary, Binary Logic
<<, >>, >>>; &, ^, |; &&, ||etc.
-
Sentence
Statements are divided into declarative statements, process control statements, and other statements.
The process control statements are divided into basic process control statements, iteration statements, jump statements and conditional statements.The details are as follows.##### 1. Declaration statement
- ##### 1.1 Variable declaration 1.1.1 var statement > Declare a variable and initialize it to a value > ```js > var a; > var a = 2; > var a = 2, b = 3; // Initialization of multiple variables > ``` var Declared variables can be promoted, meaning that regardless of where they are actually declared, they are treated as variables declared at the top of the current scope.See example 4 below.It is recommended that variables be always declared, regardless of whether they are in a function or global scope, as shown in examples 1, 2, and 3.<br> var Declared function expressions cannot be promoted. //For undeclared variables, you can use `typeof` to detect their existence without error. ```js // Example 1: The scope of a declared variable is in the context of its declared location, while an undeclared variable is global; // It is recommended that variables always be declared, whether they are in a function or a global scope function x() { y = 1; // ReferenceError exception thrown in strict mode var z = 2; } x(); console.log(y); // Print "1" console.log(z); // Throws ReferenceError: z not declared outside x // Example 2: Declared variables are created (promoted) before any code execution, and undeclared variables are created only when assignment is performed; console.log(a); // Throw ReferenceError. console.log('still going...'); // Never execute. console.log(a); // Print "undefined" or "" (different browser implementations). var a; console.log('still going...'); // Print "still going...".
// Example 3: A declared variable is a non-configurable property of its context, and a non-declared variable is configurable (if deleted) var a = 1; b = 2; delete this.a; // TypeError is thrown in strict mode, otherwise execution fails without any hint. delete this.b; console.log(a, b); // Throw ReferenceError. // The'b'attribute has been deleted. // Example 4: Variable promotion var x = y, y = 'A'; console.log(x + y); // undefinedA // It will actually be converted to: var x; var y; x = y; y = 'A'; ``` 1.1.2 let statement > Declares a variable with a block-level scope and can be initialized. > ```js > let x; > let x = 1; > let x = 1, y = 2; > ``` **and var The difference between keyword declaration variables is that:** 1. `var ` A declared variable can only be a global or an entire function block.`let/const` Declared variables are used only in the block or subblock they declare; (Example 1)) 2. ` let/const ` Will not be created at global declaration time `window` Object's properties, while var Meeting.(Example 2) 3. `let/const` You cannot repeat declarations (errors) within the same block scope or function.`var` Yes; (Example 3, 4) 4. `var` Declared variables are initialized to `undefined`,`let/const` Declared variables are not initialized until their definitions are executed.Quantity will be initialized to `undefined`,`let/const` Declared variables are not initialized until their definitions are executed. ```js // Example 1 function varTest() { var x = 1; { var x = 2; // Same variable! console.log(x); // 2 } console.log(x); // 2 } function letTest() { let x = 1; { let x = 2; // Variable console.log(x); // 2 } console.log(x); // 1 } // Example 2 var x = 'global'; let y = 'global'; console.log(this.x); // "global" console.log(this.y); // undefined // Example 3 if (x) { let foo; let foo; // SyntaxError thrown. } // Example 4: case is not wrapped in `{}'and does not form a block scope, so two `foo` are declared in the same block, so an error occurs. let x = 1; switch(x) { case 0: let foo; break; case 1: let foo; // SyntaxError for redeclaration. break; } // Example 5 function do_something() { console.log(bar); // undefined console.log(typeof foo); // ReferenceError, typeof is also not secure var bar = 1; let foo = 2; } // Example 6 function go(n) { // n here is defined! console.log(n); // Object {a: [1,2,3]} for (let n of n.a) { // ReferenceError console.log(n); } } go({a: [1, 2, 3]}); ``` 1.1.3 const > Declares a variable in a block scope and must initialize a value.and let Usage is basically the same except that the value of the declared variable cannot be changed. ```js let a = 1; a = 2; console.log(a); // 2 const c = 1; c = 2; // Uncaught SyntaxError: Invalid or unexpected token ``` - ##### 1.2 Function declaration > Each function is a Function Object, unlike other objects, is callable;<br> > If the function does not return Statement returns undefined;<br> > Function is the way of value transfer (object is reference transfer);<br> > Es6 Beginning in strict mode, the function scope in the block is this block.Do not use block-level functions in non-strict mode. **There are three ways to define functions:** **Function declaration:** Generator function declaration **Constructor:** Common Constructor Function, Generator constructor GeneratorFunction. (Defining a function in a way that does not recommend a constructor, where the body of the function is a string, can cause other problems) **Function expression:** Function expression, function generator expression, arrow function expression //Writing examples: ```js // Function declaration defines function function getName(name1, name2, ...) { // Sentence } // Constructor Definition Function var getName = new Function('name1', 'name2', 'return "myName:" + name1'); getName('yang'); // "myName:yang" // Function expression defines a function var getName = function(name1, name2) { return 'myName:' + name1; } // Function expression (function bar() {}) ``` **Function declarations differ from expressions:** 1. The main difference is that function expressions can omit function names, that is, create anonymous functions. 2. The function expression does not omit the function name, the function name can only be used within the function body, and the function name declared by the function can be used within its scope. 2. Function declarations can be promoted, and function expressions cannot be promoted, so expressions cannot be used before they are called. 3. Functional expressions can be used as IIFE(Function expression called immediately). ```js var y = function x() {}; alert(x); // throws an error // IIFE: Called when a function is used only once (function() { // Sentence })(); ``` **Function expression name Attributes:** //The variable assigned by the function expression has a name attribute, and if this variable is assigned to another variable, the value of the name attribute will not change. ```js // Anonymous function: The value of the name property is the name of the variable being assigned (hidden value) var func = () => {} // func.name // "func" // Non-anonymous function: The value of the name property is the name of the function (explicit value) var funb = function haha() {} // funb.name // "haha" var fund = func; // fund.name // "func" ``` 1.2.1 function > ```js > // Maximum number of pass parameters varies from engine to engine > function name(param1, param2, ...) { > // Sentence > } > ``` 1.2.2 Function generator declaration function* > Define a generator function and return a Generator Object. Generator Object: By generator function The object returned conforms to the iterator and iterator protocols. ```js function *gen() { // Sentence yield 10; x = yield 'foo'; yield x; } ``` //Generator functions can be paused when they are executed and then resumed from the pause. //Calling a generator function does not immediately execute the statements inside it, but instead returns an iterator object for the generator. //When the iterator's next() method is called, the statements within it execute until the first subsequent yield ing occurs, followed by the value to be returned by the iterator. next() Returns an object with two attributes: value and done,value Represent this time yield The return value of the expression, done Boolean type indicating whether the generator has finished executing and returned. //When the return statement is called in the generator function, the generator immediately becomes complete, that is, the next() method calls to return an object with a true done, followed by a return as the value returned by the current call to next(). ```js function* yieldAndReturn() { yield "Y"; return "R";//Explicit return, you can see that done also immediately becomes true yield "unreachable";// Will not be executed } var gen = yieldAndReturn() console.log(gen.next()); // { value: "Y", done: false } console.log(gen.next()); // { value: "R", done: true } console.log(gen.next()); // { value: undefined, done: true } ``` yield* Represents the transfer of execution rights to another generator function (the current generator pauses execution), called next() Method, if a parameter is passed in, the parameter is passed to the last executed yield Variables to the left of the statement: ```js function* anotherGenerator(i) { yield i + 1; yield i + 2; yield i + 3; } function* generator(i){ yield i; yield* anotherGenerator(i);// Transfer of executive power yield i + 10; } var gen = generator(10); console.log(gen.next().value); // 10 console.log(gen.next().value); // 11 console.log(gen.next().value); // 12 console.log(gen.next().value); // 13 console.log(gen.next().value); // 20 ``` //Generator functions cannot be used as constructors or errors will be reported. `function*Expression` and `function*statement` Has similar grammar, the only difference is `function*Expression` The function name can be omitted. ```js var x = function*(y) { yield y * y; }; ``` 1.2.3 async function > Define a return AsyncFunction Asynchronous function of object. > Asynchronous function refers to a function that is executed asynchronously through an event loop and is executed through an implicit Promise Returns the result. > Js Each asynchronous function in is AsyncFunction Object, which is not a global object, needs to be `Object.getPrototypeOf(async function(){}).constructor` Obtain > ```js > async function name(param1, param2, ...) { > // Sentence > } > ``` //You can include the await directive, which pauses the execution of the asynchronous function and waits for Promise to execute, then proceeds with the asynchronous function and returns the result. await Can only be used in asynchronous functions, otherwise an error will be reported. async/await To simplify the use of multiple Promise Behavior of the moment, like a combination generators and promises. //Override the promise chain using the async function: ```js // Promise function getProcessedData(url) { return downloadData(url) // Returns a promise object .catch(e => { return downloadFallbackData(url) // Returns a promise object }) .then(v => { return processDataInWorker(v); // Returns a promise object }); } // When Async:return, the return value of async function is implicitly passed to Promise.resolve. async function getProcessedData(url) { let v; try { v = await downloadData(url); } catch (e) { v = await downloadFallbackData(url); } return processDataInWorker(v); } ``` - ##### Class 1.3 declarations ES6 Classes in are similar to classes in other languages and are inherited based on prototypes.However ES6 Classes in are based on existing custom types of grammatical sugars. typeof Detection classes can be found as function. ```js // Simple class declaration class PersonClass { constructor(name) { this.name = name; } sayName() { console.log(this.name); } } // Custom types implement the above code function PersonType(name) { this.name = name; } PersonType.prototype.sayName = function() { console.log(this.name); } ``` //The example above shows that the constructor in a class is actually equivalent to a PersonType function of a custom type, and the sayName method in the class is the method on the prototype of the constructor. **Define two forms of classes: class declarations and class expressions.** //Class declarations and code for class expressions are enforced strict patterns. //Like function expressions, class expressions can omit class names.If the class name is not omitted, the class name in the class expression can only be used inside the class body. //Subsequently, we will talk about classes separately. #### 2. Process Statements - ##### 2.1 Basic Statements 2.1.1 Block statement > Combine 0 or more statements, Can be used with label Use together. > `{Statement combination} Or label identifier: {Statement combination}` //Example block statement: //Example 2 is error-free because a block-level scope exists and the output is 1. ```js // Example 1 var a = 1; { var a = 2; } console.log(a); // Output: 2 // Example 2 const a = 1; { const a = 2; } console,log(a); // Output: 1 // Example 3 label: { const a = 1; } ``` //Block statement return value example: //The value returned by the block is the return value of the last statement in the block, but since the value of the statement is not available, it is OK to know. ```js var a; function b() {return 'yang';} try { throw 'haha'; } catch(e) { } // Output: undefined var a; function b() {return 'yang';} // Output: ƒ b() {return 'yang';} ``` 2.1.2 Empty statement > No statement will be executed > `;` //Example empty statement: ```js // An empty statement with a for loop (empty statements are best commented to avoid confusion) for (let i = 0; i < 5; i++) /* Empty statement */; // if statement if (one); // do nothing else if (two); // do nothing else all(); ``` - ##### 2.2 Iteration Statement 2.2.1 while/do...while > ```js > while (condition) > statement // Available block statements to execute multi-line statements > > do > statement // Available block statements to execute multi-line statements > while (condition); > ``` `while` Can be in a `condition`(Conditional expression) If the value is true, loop until the expression value is false;`do...while` Executes a loop of the specified statement until `condition`(Conditional expression) value is false,and `while` Statement differs in execution `statement` Post-detection `condition`,therefore `statement` Execute at least once. //Examples of differences between the two: ```js var i = 1; do { console.log('do..while', i); i++; } while (i < 1); // Output: // "do...while" // 1 var j = 1; while (j < 1) { console.log('while', j); j++; } // No output ``` 2.2.2 for/for...of/for...in/for await...of >1.**for: ** Create a loop with three optional expressions enclosed in parentheses and separated by semicolons followed by a statement executed in the loop (usually a block statement, i.e. `{}` Wrapped statement). >> ```js >>// initialization is an expression (including an assignment expression) or a variable declaration, and if there is no statement to execute, an empty statement `(;)`is used. >> for ([initialization]; [condition]; [final-expression]) >> statement >> ``` >2.**for...of: ** Loop through iterative objects ( Array, Map, Set, String, TypedArray, arguments Object, etc.) The value to iterate over. >> ```js >> for (variable of iterable) { >> //statements >> } >> ``` >3.**for...in: ** Iterates the enumerable properties of an object in any order.(except Symbol Outside) >> ```js >> for (variable in object) >> statement >> ``` >4.**for await...of: ** Create an iteration loop on an asynchronous or synchronous Iterable object that executes statements for the values of each different property. >> ```js >> for await (variable of iterable) >> statement >> >>``` **for : ** //If the intermediate optional conditional expression (`condition`block) is omitted, you must ensure that you jump out of the loop (`break statement') or you will end up in an infinite loop. //If you omit all expressions, make sure you jump out of the loop and modify the increment so that the `break statement` is true under certain conditions. (see example 2) ```js // Example 1 var arr = []; for (var i = 0; i < 9; i++) { arr.push(function() { console.log(i); }); } console.log(arr.forEach(item => console.log(item()))); // Output: // [9, 9, 9, 9, 9, 9, 9, 9, 9] // Example 2 var i = 0; for (;;) { if (i > 3) break; console.log(i); i++; } // Example 3 for (var i = 0; i < 9; i++); console.log(i); // 9 ``` **for...of: ** ```js // Iterate Array let iterable = [10, 20, 30]; for (let value of iterable) { value += 1; console.log(value); } // Output: // 11 // 21 // 31 // Iterative String let iterable = 'boo'; for (let value of iterable) { console.log(value); } // b // o // o // Iterate Map let iterable = new Map([['a', 1], ['b', 2]]); for (let [key, value] of iterable) { console.log(value); } // 1 // 2 ``` **for...in: ** for...in A loop traverses only enumerable attributes, not non-enumerable attributes, such as String Of indexOf() Method, or Object.toString() Method. //Generally, it is best not to add, modify, or delete attributes on objects during an iteration because there is no guarantee that these modified attributes will be accessed. ```js Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; let iterable = [3, 5, 7]; iterable.foo = 'hello'; for (let i in iterable) { console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" } for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // logs 0, 1, 2, "foo" } } for (let i of iterable) { console.log(i); // logs 3, 5, 7 } ``` > Be careful: >- for...in Visit Array The elements are not necessarily accessed in order, depending on the execution environment, and the index of the array is accessed, including other attributes as well as inherited attributes in addition to the index. >- for...of Statement traverses data that can be iterated over by an object, so use it to traverse Array The value in is better; >- for...in When traversing enumerable properties, you can use the `getOwnPropertyNames()` perhaps `hasOwnProperty()` Determines whether the object is an attribute of itself. **for await...of: ** //The Asynchronous Generator (or Iterative Asynchronous Iterable Objects) has implemented the Asynchronous Iterator Protocol with a `for await...of `loop: ```js async function* asyncGenerator() { var i = 0; while (i < 3) { yield i++; } } (async function() { for await (num of asyncGenerator()) { console.log(num); } })(); // 0 // 1 // 2 ``` - ##### 2.3 Conditional Statement 2.3.1 if > Conditional Judgment > ```js > if (condition) > statement1 > [else if (condition) > statement2] > [else > statement3] > //Brackets indicate optional > ``` 2.3.2 switch > Evaluate an expression if its value is equal to case Clause Matching Executes case Statements associated with clauses. > ```js > switch (expression) { > case value1: > // Execute this statement when the result of expression matches value1 > [break;] > ... > [default: > // If expression does not match the value above, execute the statement here > [break;]] > // Brackets indicate optional > ``` - ##### 2.4 Jump Statement 2.4.1 break Sentence > Abort the current loop (or switch Statement or label Statement) directly executes the statement following the aborted statement. > `break [label];` > label (Optional)—Tag-related identifier if break Statement is not in a loop or switch Statement, then this item is required. ```js // Example 1: break statement in loop var i = 0; while (i < 6) { i += 1; if (i == 3) break; console.log(i); } // Output: // 1 // 2 // Example 2: break statement and marked block statement outer_block: { inner_block: { console.log('1'); break outer_block; } console.log ('haha') //Skipped } ``` 2.4.2 continue Sentence > Terminates the statement executing the current (or label) loop and executes the next iteration loop directly. > `continue [label];` //The difference from the `break` statement is that `continue` does not terminate the iteration of the loop: //In a while loop, the control flow jumps back to conditional judgment; //In the for loop, the control flow jumps to the update statement. ```js // Example 1: continue statement in loop var i = 0; while (i < 6) { i += 1; if (i == 3) continue; console.log(i); } // Output: // 1 // 2 // 4 // 5 // 6 // Example 2 var a = 0; var b = 8; checkAB: while(...) { checkB: while(...) { continue checkB; //Jump to checkB every time to start execution } } ``` 2.4.3 throw Sentence > A user-defined exception was thrown.Execution of the current function will be stopped(throw The following statement will not execute),And control will be passed to the first one in the call stack catch Block.If no function is called catch Block, the program will terminate. > `throw expression;` ```js throw "Error"; // An exception with a value of string was thrown throw 42; // An exception with an integer 42 value was thrown throw true; // An exception with a value of true was thrown ``` 2.4.4 try...catch Sentence > Marks the block of statements to try and specifies a response thrown when an exception occurs. > ```js > try { > try_statements > } > [catch (exception_var_1) {}] > [catch (exception_var_2) {}] > // exception_var_1, exception_var_2 holds the value specified by the throw statement (e. g. E in catch(e), which can be used to obtain thrown exception information and is only used inside the catch clause. > [finally {}] > // Executed after the try block and catch block and before the next try declaration, always with or without exception throws > ``` * Can nest one or more try Statement, if internal try Statement does not catch Clause, it will enter the wrapped try Statement's catch Clause. ```js try { try { throw new Error("oops"); } catch (ex) { console.error("inner", ex.message); } finally { console.log("finally"); } } catch (ex) { console.error("outer", ex.message); } // Output: // "inner" "oops" // "finally" // "outer" "oops" ``` * finally Block returns a value, regardless of try and catch Is there anything in the block return Statement, this value will become the entire try-catch-finally Return value of. ```js // The return in try-catch must be the return value of the function, or an error will occur (see the return statement below).In this case try-catch will be run in a function. (function() { try { try { throw new Error('oops'); } catch (ex) { console.error('inner', ex.message); throw ex; } finally { console.log('finally'); return; } } // `oops'will not be thrown out because it is return ed in finally catch (ex) { console.error('outer', ex.message); } })(); // Output: // inner oops // finally // undefined //Return value of the entire function ``` 2.4.5 return Sentence > Terminates the execution of a function and returns a specified value to the caller of the function. >`return [[expression]]` > Returns the value of the expression, or if the value of the expression is ignored undefined. //The use of line terminators (carriage return, line and segment separators) between the return keyword and the returned expression automatically inserts semicolons, such as: ```js return a + b; // Will be automatically converted to return; a + b; var a = 1; var b = 2; (function() { return a + b; })() // undefined // Will be automatically converted to (function() { return a + b; })() // 3 ``` //You can also return a function expression, which is the definition of a higher-order function, which is a function that takes a receiving function as a parameter or returns a function as an output. #### 3. Other statements 3.1 debugger > Call available debugging functions in your program, such as setting breakpoints. > `debugger` 3.2 Import/Export: export,import **export: ** Export functions, objects, or original values from a module so that other programs can pass through import Statement use. //There are two export modes: **Named Export** and **Default Export**.Multiple named exports can be defined in each module, but only one default export is allowed. //Import/export modules are all running in strict mode. //Export example: ```js export let name; // Export single attribute export const myName = 'yang'; // Export Constants export class ClassName {} // Export Class export default defaultName; // Export default properties export {name1, name2...} // Export List export {defaultName as default, name1 as Wang...} // Rename the export, export name1 as the default attribute, and rename name2 as Wang // Module redirection, importing and exporting modules with specified paths export * from ...; // Export all exported properties of the specified module except the default export value export {default} from ...; // Export default export values in specified modules export {name1, name2...} from ...; // Export some properties in the specified module export {import1 as name1, import2 as name2...} from ...; // Rename some properties in the export specified module ``` **import: ** Import bindings exported by another module. //In browsers, import statements can only be used in script tags that declare type="module".<br> //There is also a dynamic import() similar to the function, which does not require a script tag that relies on type="module".<br> //Static import is easier to benefit from code static analysis tools and tree shaking, while dynamic import() is useful when loading modules on demand. //Import example: ```js import * as names from 'export.js'; // Import the entire module content, using the names module name as the namespace import {myName, ClassName} from 'export.js'; // Import multiple interfaces import name from 'export.js'; // Import default interface (that is, export default exported interface) import defaultName, {name1, newName as name2} from 'export.js'; // Import default interfaces and multiple other interfaces at the same time, and rename some of them import defaultName, * as names from 'export.js'; // Import the default interface and multiple other interfaces at the same time. All other interfaces are imported and renamed names import 'export.js'; // Imported modules are imported as side effects (running only the global code in the module), without importing any interfaces in the module. var promises = import('export.js'); // Modules can be imported dynamically as functions are called.Called this way, a promise is returned. promises.then((module) => {}) ``` 3.3 label > Add a referential identifier before the statement, and break or continue Statement together. > `label: statement` ```js // Mark the block and use break foo: { console.log('face'); break foo; console.log('this will not be executed'); } console.log('swap'); // Use markup in for loop var str = ""; loop1: for (var i = 0; i < 5; i++) { if (i === 1) { continue loop1; } str = str + i; } console.log(str); // '0234' ``` //Function declarations can now be marked in non-strict mode, but not in strict mode.Generator functions cannot be marked in any mode. ```js L: function F() {} 'use strict'; L: function F() {} // VM170:2 Uncaught SyntaxError: In strict mode code, functions can only be declared at top level or inside a block. L: function* F() {} // VM175:1 Uncaught SyntaxError: Generators can only be declared at the top level or inside a block. ``` 3.4 with > with Sentence(Not recommended, just know it),Scope chain used to extend statements. > stay ECMAScript 5 This label has been disabled in strict mode.The recommended alternative is to declare a temporary variable to hold the properties you want. > ```js > with (expression) { > statement > } > ``` //Example: ```js var a, x, y; var r = 10; var Math = {}; with (Math) { a = PI * r * r; x = r * cos(PI); y = r * sin(PI / 2); } // Uncaught ReferenceError: PI is not defined // Because there is a Math variable in the scope, first find if the Math object in the variable has a PI attribute, and find that there is no error. // The'with'statement adds a variable Math object to the top of the scope chain and, when looking for the variable value PI, looks in the specified object Math and finds no error.When with finds an object, it first looks from the current scope, so it will be slow to find.And debugging can be cumbersome. ```
-
Expression statement
Any expression can be a statement, that is, an expression can be written wherever it is needed. Such a statement is called an expression statement, which is a special kind of statement.Conversely, we cannot write statements where we write expressions.
The following figure shows the syntax of the If statement in the ecma262 specification.Where there is a Statement, you can use Expression, which is an expression. For example, in the example below, the callback function calls an expression, which replaces the original statement and is also an expression statement.
Example: ```js // callback is an expression statement and is a special kind of statement if (true) callback() ```
-
compare
1. How can expressions and statements be distinguished?
1. To see whether a value judgment is generated, evaluating an expression will certainly return a value, and evaluating a statement may or may not have a return value;
2. See if there is a semicolon after it. The semicolon must be a statement. If there is no semicolon, it may be an expression or a statement.In the following two examples, the first reason for a successful log is that if statements should have an expression in parentheses, and true is a Boolean literal quantity in the expression.The second var a = 0 is a declaration statement, not an expression, and does not return a value, so an error will occur.
if (true) { console.log('Hi'); } // Output: // Hi if (var a = 0) { console.log('Hi'); } // Output: // Uncaught SyntaxError: Unexpected token 'var'
2. Similar expressions and statements
2.1 if statement and conditional expression
The if statement has the same meaning as a conditional expression; it is just a statement; it is simply an expression that returns a value.
var x; var y = -1; // if statement if (y >= 0) { x = y; } else { x = -y; } // Conditional expression x = (y >= 0 ? y : -y); // Brackets are not required and are easier to read
2.2 Function Declarations and Function Expressions
Function expressions have almost the same syntax as function declarations, but with the following differences:
- The function name can be omitted from the function expression, which is an anonymous function; the function name cannot be omitted from the function declaration.
- Function expressions can be used as IIFE (call function expressions immediately), and function declarations cannot be used as IIFE.
// Function expression: omit function name function () {} // Function expression: function name is not omitted // Write exactly as function declaration function foo() {}
A function expression without omitting a function name is not different from a function declaration, but it does not: a function expression produces a value, that is, a function; a function declaration causes an action, creating a variable whose value is a function.
A function name in a function expression that does not omit a function name can only be called from within the function itself, and calls outside the function will result in an error.Example:
var outSideFuncName = function inSideFuncName(x) { return x <= 1 ? 1 : x * inSideFuncName(x - 1); } outSideFuncName(5); // Output: 120 > outSideFuncName // Output: // ƒ inSideFuncName(x) { // return x <= 1 ? 1 : x * inSideFuncName(x - 1); // } > insideFuncName // Output: // Uncaught ReferenceError: inSideFuncName is not defined
2.3 Object Literal Expressions and Block Statements
We know that object literals are expressions, written as {key: value}, and block statements are statements wrapped in {}.When a block contains a label statement followed by an expression statement, the object literal expression may be exactly the same as the block statement.
Example:{ foo: bar(3, 5) }
The example above is both object literal quantity and block statement.As a block statement, the label statement labeled foo is inside the block, and the statement after the label is a function call expression. According to the previous definition of the expression statement, you can know that bar (3,5) is an expression statement.
So the {} we see in the program could be literal, it could be a block statement, and it's context sensitive.Take the following example:
> [] + {} "[object Object]" > {} + [] 0
Why are the two results inconsistent?The reason is that the previous {} is calculated as a literal quantity, followed by a block statement.The example also involves implicit conversion, so I'll cover it in a separate article.
Commas in 2.4 expressions and semicolons in statements
In JavaScript, statements are separated by semicolons, such as foo(); bar(); expressions can be separated by commas, such as foo(), bar(), and both expressions execute, only returning the value of the following expression.
> "a", "b" 'b' > var x = ("a", "b"); > x 'b'
3. Use object literals and function expressions as statements
We already know that expressions can be placed wherever they are needed, that is, expression statements.How do I distinguish an expression from a statement when there is no difference between some expressions, such as object literals and blocks in 2.3, function expressions and function declarations in 2.4?Generally, they are distinguished based on whether they appear in the context of an expression or a statement, with the exception of an expression statement.
Because an expression statement is a special kind of statement, its context is the statement context, in which case {} is treated as a block, and the grammar at the beginning of a function is treated as a function declaration.To avoid ambiguity, JavaScript syntax prohibits expression statements from starting with {and function.If you must use expressions that start with these two and treat them only as expressions, you can place expressions in the () grouping operator so that they appear in the context of the expression and do not change the result of the expression.
(Expression) - Grouping operator that wraps expressions and subexpressions in parentheses and returns the result of executing the expression.
Another way to ensure that an expression is parsed in the context of an expression is to use unary operators, such as!, or +.However, unlike (), unary operators change the result of an expression.See below for an example of calling a function expression immediately.
Let's look at the application of eval and call function expressions immediately.
eval
eval It parses its parameters in the context of the statement, so the example above will `{}` Parses into blocks, so inside is label Statement, thus outputting as `123`. After adding parentheses,`{}` And the context of its contents is expression, so `{foo: 123}` Treated as a literal expression and output as `{foo: 123}`. ```js > eval("{foo: 123}"); 123 > eval("({ foo: 123 })") {foo: 123} ``` - ##### Call function expressions immediately (IIFEs) ```js // Call function expression now > (function () { return "hello" }()) 'hello' > (function () { return "hello" })() 'hello' // Call function expression immediately after omitting parentheses > function () { return "hello" }() Uncaught SyntaxError: Function statements require a function name > +function () {console.log('hello')}() hello NaN // Returns NaN because the expression returns undefined, so + undefined is NaN > void function () {console.log('hello')}() hello undefined // Similarly, void undefined returns undefined ``` //It is important to note that when using IIFEs continuously, remember to add semicolons, otherwise errors will occur.Because subsequent IIFEs treat the results of previous IIFEs as function calls. //If you want to omit the semicolon, you can place the unary operator before the immediate call to the function expression because there is an automatic semicolon insertion.The automatic semicolon insertion mechanism, as I'll tell you later, buries a second foreshade here. ```js (function () {}()) (function () {}()) // VM613:1 Uncaught TypeError: (intermediate value)(...) is not a function (function () {}()); (function () {}()) // undefined void function () {}() void function () {}() // undefined ```