In javascript, expressions are phrases, and statements are the whole sentence or command. Just as an English statement ends with a period, javascript ends with a semicolon.
The expression calculates a value, but the statement makes something happen.
One way to "make something happen" is to calculate expressions with side effects. Expressions with side effects such as assignments and function calls can be used as separate statements. This usage of expressions as statements is also called expression statements. Similar statements include declaration statements, which are used to declare new variables or define new functions.
A javascript program is a collection of a series of executable statements. By default, the javascript interpreter is executed in sequence in order of writing. Another way to "make something happen" is to change the default execution order of the statement:
1. Conditional statement: The javascript interpreter can determine whether to execute or skip these statements, such as if and switch statements.
2. Loop statement: statements that can be executed repeatedly, such as while and for statements
3. Jump statement: You can let the interpreter jump to other parts of the program to continue execution, such as break, return and throw statements
Next, this article will introduce various statements and their syntax in JavaScript. This chapter summarizes these sentences at the end. A javascript program is nothing more than a collection of statements separated by separation, so once you master the javascript statements, you can write a javascript program.
1. Expression statement
Assignment statements are a relatively important expression statement. Their function is to change the value of a variable, just like executing an assignment statement: for example
The code copy is as follows:
greet = "hello" + name;
i *= 3;
The increment operator (++) and the decreasing operator (--) are related to the assignment statement. Their function is to change the value of a variable, just like executing an assignment statement.
The code copy is as follows:
counter++;
The important function of the delete operator is to delete an object's properties (or elements of an array) and all it is generally used as statements, not as part of a complex expression.
The code copy is as follows:
delete ox;
Function calls are another major category of expression statements, for example
The code copy is as follows:
alert(greet);
window.close();
Although these client functions are expressions, they have a certain impact on the web browser. So we think it's also a statement, and it doesn't make sense to call a function without side effects unless it's part of a complex expression or assignment statement, for example. It is impossible to discard a cosine value at random;
Math.cos(x);
Instead, to get the cosine value, you have to assign it to a variable so that this value can be used in the future:
var cx = Math.cos(x);
Again, each line of code ends with a semicolon.
2. Compound statements and empty statements
Several expressions can be concatenated together with a comma operator to form an expression. Similarly, JavaScript can also tell you that multiple statements are united together to form a compound statement. Just wrap multiple statements in curly braces. Therefore, the following lines of code can be used as a separate statement anywhere in JavaScript you want to use a statement.
The code copy is as follows:
{
x = Math.PI;
cx = Math.cos(x);
console.log("cos(π)=" + cx);
}
There are several points to note about statement blocks: First, statement blocks do not require semicolons. Element statements in blocks must end with semicolons, but statement blocks do not.
Second, the lines in the statement block are indented, which is not necessary, but neat indentation can make the code more readable and easier to understand.
Third, JavaScript has no block-level scope, and the variables declared in the statement block are not privately owned by the statement block. (Refer to the first section of Chapter 3, 10)
The practice of combining many statements into a large statement block is very common in JavaScript programming. Similar expressions usually contain subexpressions, many javascripts contain other substatements. In terms of form, javascript usually allows a statement block to contain a substatement. For example: the while loop body can contain only one statement. Using a statement block, you can put any number of statements into this block, and this statement block can be used as a statement.
In javascript, when you want multiple statements to be used as one statement, use a conforming statement instead. An empty statement (empty statement) is exactly the opposite, it allows to contain 0 statements. The empty statement looks like this:
;//semicolon
The javascript interpreter obviously does not perform any actions when executing an empty statement, but practice has proved that empty statements are sometimes useful when creating a loop with an empty loop body, such as the following for loop
The code copy is as follows:
//Initialize an array a
for (i = 0; i < a.length; a[i++] = 0);
In this loop, all operations are completed in the expression a[i++]=0, and no loop body is needed here. However, javascript requires that the loop body contains at least one statement, so only a separate semicolon is used here to represent an empty statement.
Note that the semicolons in the right side of the for loop, while loop or if statement are inconspicuous, which may cause some fatal bugs, which are difficult to locate. For example, the execution result of the following code is likely to be an effect that the author does not want:
The code copy is as follows:
if((a==0)||(b==0)); //This line of code does nothing...
o = null; //This line of code will always be executed
If you use an empty statement for special purpose, it is best to add comments in the code, which can clearly indicate that this empty statement is useful.
The code copy is as follows:
for (i = 0; i < a.length; a[i++] = 0) /*empty*/;
3. Declaration statement
var and function are declaration statements that declare or define variables or functions. These statements define and assign identifiers (variable names and function names) to them, which can be used anywhere in the program. Declaration statements do nothing themselves, but it has an important meaning: by creating variables and functions, the semantics of the code can be better organized.
The following sections will talk about var statements and function statements, but do not contain all the contents of variables and functions.
i.var
The var statement is used to declare one or more variables. Its syntax is as follows:
var name_1[ = value_1][, ..., name_n[ = value_n]]
The keyword var is followed by a list of variables to be declared. Each variable in the list can have an initialization expression that can be used to specify its initial value. For example:
The code copy is as follows:
var i; //A simple variable
var j = 0; //A variable with initial value
var p, q; //Two variables
var greet = "hello" + name; //More complex initialization expression
var x = 2.34,y = Math.cos(0.75),r, theta; //Many variables
var x = 2,y = x * x; //The second variable uses the first variable
var x = 2,
f = function(x) {return x * x}, //Each variable has one row exclusive
y = f(x)
If the var statement appears in the function body, then it defines a local variable, and its scope is this function. If you use a var statement in the top-level code, then it declares a global variable, which is visible throughout javascript. In Chapter 3, Section 10, it is mentioned that global variables are properties of global objects. Then, unlike other global object properties, variables declared by var cannot be deleted through delete.
If the variable in the var statement does not specify an initialization expression, the value of this variable is initially undefined. Therefore, the value of the variable before the declaration statement is undefined.
It should be noted that the var statement can also be used as a component of the for loop or for/in loop. (Same as variable declarations declared before loops, declared variables here will also be "advanced"), for example:
The code copy is as follows:
for (var i = 0; i < 10; i++) console.log(i);
for (var i = 0, j = 10; i < 10; i++, j--) console.log(i * j);
for (var i in o)console.log(i);
Note that it doesn't matter if you declare the same variable multiple times.
ii.function
The keyword function is used to declare functions. We have learned function expressions (4.3). Function definitions can be written into a form of a statement. For example: Two definitions are written in the following example code:
The code copy is as follows:
var f = function f(x) {return x + 1;} // Assign the expression to a variable
function f(x){return x + 1;} //Sentence containing variable names
The syntax of function declaration is as follows:
The code copy is as follows:
function funcname([arg1[, arg2[..., argn]]]) {
statements
}
funcname is the name identifier of the function to be declared. The function name is followed by the parameter list, separated by commas. When calling a function, these identifiers refer to the actual parameters passed to the function.
The function body is composed of javascript statements, with no limit on the number of statements and is enclosed in curly braces. When defining a function, the statements in the function body are not executed, but are associated with the new function object to be executed when calling the function. Note that curly braces in function function statements are necessary, which is different from the statement blocks used by while loops and other statement locks. Even if the function body has only one statement, curly braces are still required to wrap it up.
The code copy is as follows:
function hyteus(x, y) {
return Math.sqrt(x * x + y * y);
}
hyteus(1, 2) //=>2.23606797749979
function facial(n) { //A recursive function
if (n <= 1) return 1;
return n * facial(n - 1);
}
facial(11) //=>39916800
Function declarations usually appear at the top of javascript code and can also be nested within other functions. But when nested, function declarations can only appear at the top of the nested function. That is to say: the function definition cannot appear in if, while, or other statements.
Like the var statement, variables created by function declaration statements cannot be deleted. However, these variables are not read-only, and the variable values can be rewritten.
4. Conditional statements
A conditional statement is to execute or skip certain statements by determining whether the value of the specified expression is to be valued. These statements are "decision points" of the code, sometimes called "branches". If the javascript interpreter is executed following the "path" of the code. The conditional statement is the fork point on this path. When the program reaches this point, you must select a path to continue execution.
i.if statement
If statement is a basic control statement. To be precise, it allows the program to execute conditionally. There are two forms of this statement: the first is
The code copy is as follows:
if (expression)
statement
In this form, if the value of expression is true, execute the statement statement, and if it is false, do not execute the statement. For example,
The code copy is as follows:
if (username == null) //If username is null or undefined
username = "jack wong"; //Define it
It should be noted that it is necessary to enclose the garden brackets of the expression if statement.
JavaScript syntax stipulates that if keywords and expressions with garden brackets must be followed by a statement. However, multiple statements can be combined into one using statement blocks. Therefore, the form of the if statement looks like this:
The code copy is as follows:
if (!address) {
address = "";
message = "please mailing address"
}
The second form of the if statement introduces the else clause, and executes the else logic when the value of expression is false.
The code copy is as follows:
if (expression)
statement1
else
statement2
For example, the following code
The code copy is as follows:
if (n == 1)
console.log("1 new message");
else
console.log("you have" + n + "new message");
When using if/else statements in nested use of if statements, you must be careful to ensure that the else statement matches the correct if statement. Consider the following code:
The code copy is as follows:
i = j = 1;
k = 2;
if (i == j)
if (j == k)
console.log("i equals k");
else
console.log("i dosent equal j"); //Error! !
In this example, the inner if statement constitutes the clauses required by the outer if statement. However, the matching relationship between if and else is not clear (only indentation gives a little hint) and in this example, the hint given by indentation is wrong, because the javascript interpreter understands it so.
The code copy is as follows:
if (i == j) {
if (j == k)
console.log("i equals k");
else
console.log("i dosent equal j");
}
Like most programming languages, the if and else match rules in JavaScript are that else always match the nearby if statement. In order to make the example readable, easier to understand, and more convenient for maintenance and debugging, curly braces should be used.
The code copy is as follows:
if (i == j) {
if (j == k) {
console.log("i equals k");
} else { //Crape braces make the result of the code clearer
console.log("i dosent equal j");
}
}
Many programmers have the habit of enclosing the body of if and else statements in curly braces (just like in a matching statement like a while loop). Even if there is only one statement per branch, doing so can avoid the ambiguous problem of the program just now.
ii.else if
The if/else statement selects one of the two branches by judging the calculation result of an expression. What should I do when there are many branches in the code? One solution is to use the else if statement. else if is not a real javascript statement, it is just a way to write multiple if/else statements together.
The code copy is as follows:
if (n == 1) {
//Execute code block 1
} else if (n == 2) {
//Execute code block 2
} else if (n == 3) {
//Execute code block 3
} else {
//The previous conditions are false, then the code block 4 is executed
}
There is nothing special about this kind of code. It consists of multiple if statements, and each if statement's else clause contains another if statement. The syntax equivalent code can be completed using the nested form of if statements, but compared with this, it is obvious that the writing of else if is clearer and preferable.
iii.switch
During the execution of the program, an if statement creates a branch, and can use else if to handle multiple branches. Then, when all branches depend on the value of the same expression, else if is not the best solution. In this case, it is a very wasteful practice to repeatedly calculate expressions in multiple if statements.
The switch statement is suitable for handling this situation. The keyword switch is followed by an expression enclosed in garden brackets. Then there are code blocks enclosed in curly braces.
The code copy is as follows:
switch (expression) {
statements
}
However, the complete syntax of the switch statement is more complicated than this. The case is followed by an expression and a colon. Case is very similar to a markup language, except that this markup language does not have a name.
It is only associated with the expressions that follow it. When executing this switch statement, it first calculates the value of the expression, and then finds whether the expression of the case clause is the same as the value of the expression. (The same is compared with the "===" operator). If the case is matched, it will execute the corresponding code. If a matching case cannot be found, it will execute the code block in the "default:" tag. If there is no "default:" tag, switch will skip all code blocks.
The switch statement is very easy to confuse, and the introduction with examples will be clearer. The following switch statement is equivalent to the if/else statement just now.
The code copy is as follows:
switch (n) {
case 1: //If n ===1 starts from here
//Execute code block 1
break;
case 2:
//Execute code block 2
break;
case 3:
//Execute code block 3
break;
default:
//Execute code block 4
break;
}
It should be noted that the keyword break is used at the end of each case statement. We will introduce the break statement later. The break statement can make the interpreter jump out of the switch statement or loop statement. In switch, case only indicates the starting point of the code to be executed, but does not specify the end point. If there is no break statement, the switch statement starts executing from the code at the matching case tag of the expression value, and executes subsequent statements in turn until the end of the entire switch code block. Of course, if you use a switch statement in a function, you can use return to replace break. Return and break are both used to terminate the switch statement, which will also prevent a case statement from continuing to execute the next case statement block.
The following statement is close to actual combat, and it converts the value into a string according to the type of the value.
The code copy is as follows:
function convert(x) {
switch (typeof x) {
case 'number': //Convert numbers to hexadecimal
return x.toString(16);
case 'string':
return '"' + x + '"'; //Return two strings with double quotes.
default: //Use ordinary methods to convert other types
return String(x);
}
}
console.log(convert(100255114)) //=>5f9c58a
Note that in the above two examples, the case keyword is followed by a direct number and string, which is the most common usage of switch in practice, but the ECMAScript standard allows each keyword to follow arbitrary expressions.
The switch statement first calculates the expression after the switch keyword, and then calculates the expression after each case in order from top to bottom, knowing that the value of the expression executed to the case and the value of the expression of the switch are equal. Since the matching operation for each case is actually a "===" identity operator comparison, not "==", the matching of expression and case does not do any type conversion.
Every time a switch statement is executed, not all case expressions can be executed. Therefore, case expressions with side effects should be avoided, such as function calls expressions and assignment expressions. The safest way is to use constant expressions in case expressions.
As mentioned earlier, if the switch expression does not match all case expressions, the statement block marked "default:" will be executed. If there is no "default:" tag, the entire switch statement will be skipped. In the previous example, the "default:" tag appears at the end of the switch and is behind all case tags. Of course, this is the most reasonable and most commonly used way of writing. In fact, the "default:" tag can be placed anywhere within the switch statement.
5. Loop.
To understand conditional statements, you can think of the code in javascript as branch paths. Looping statements are looping statements that allow some code to be executed repeatedly. There are four loop statements in JavaScript: while, do/while, for, and for/in. The following sections will explain them at once. The most commonly used loop is the traversal of array elements. (7.6 will discuss this loop and special loop methods defined by array classes in detail.)
i.while
If statement is a basic control statement used to select branch statements that execute the program. Like if, the while statement is also a basic loop statement, and its syntax is as follows:
The code copy is as follows:
While (expression)
statement
Before executing a while statement, the javascript interpreter first calculates the value of the expression. If its value is a false value, the program will skip the logical statement in the loop body and execute the next statement in the program. If its value is true, then the logic in the loop body statement is executed, and then the value of the expression expression is calculated. The loop will continue until the value of the expression is false. In other words, when the expression is true, the statement will be executed in a loop. Note that using while(true) will create a dead loop.
Generally speaking, we don't want javascript to perform the same operation repeatedly. In almost every loop, one or more variables will change iteratively with the loop. It is precisely because these variables are changed that the statement operations performed in each loop are different. Moreover, if changing the variable is used in expression, the value of the expression of each loop is also different. This is very important. The expression responsible for the initial value of the true value is always the true value, and the loop will not end. The example below shows that while loop outputs values 0-9.
The code copy is as follows:
var count = 0;
while (count < 10) {
console.log(count);
count++;
}
It can be found that in this example, the initial value of the variable count is 0, and during the loop, its value is incremented by 1 each time, when the loop is executed ten times. The value of the expression is programmed false, and then while will end, and the javascript interpreter will execute the next statement of the program. Most loops have a counter variable like count. Although counters often use variable names like ijk, if you want to make the code more readable, you should use more specific syntax names.
ii.do/while
The do/while loop is very similar to the while loop, except that it detects the loop expression at the tail of the loop rather than at the top, which means that the loop body is executed at least once. The syntax of the do/while loop is as follows:
The code copy is as follows:
do
statement
while(expression);
Do/while loops are not as commonly used as while loops. This is because it is not common in practice to want to execute loops at least once. Here is an example of a do/while loop
The code copy is as follows:
function printArray(a) {
var len = a.length,
i = 0;
if (len == 0)
console.log("empty array");
else
do {
console.log(a[i]);
} while (++i < len);
}
printArray([1,5,2,6])
There are two syntax differences between do/while loops and normal while loops. First, the do loop requires that the keyword do must be used to identify the beginning of the loop, use while variable to identify the end of the loop and enter the loop condition to judge; secondly, unlike the while loop, the do loop uses a semicolon ending. If the while loop body is enclosed in curly braces, the while loop does not end with a semicolon.
iii.for
The for statement provides a more convenient loop statement control structure than while. The for statement simplifies the commonly used loop mode. Most loops have specific counter variables. This variable is initialized before the loop starts, and then check its value before each loop. Finally, the counter variable is self-incremented, otherwise it will be modified after the cycle is over and before the next judgment. In this type of loop, the three key operations of the counter are initialization, detection, and update. The for statement explicitly declares these three operations as part of the loop syntax, each using an expression to represent it. The syntax of the for statement is as follows:
The code copy is as follows:
for (initialize; test; increment)
statement
The three expressions of initialize, test, and increment are separated by semicolons. They are responsible for initializing operations, cyclic condition judgment and updating counter variables. Putting them on the first line of the loop makes it easier to understand what the for loop is doing, and also prevents forgetting to initialize or increment the counter variable.
The easiest way to explain how a for loop works is to list an equivalent while loop
The code copy is as follows:
initialize
while (test) {
statement
increment;
}
In other words, the initialize expression is executed only once before the loop starts. The initialization expression should have side effects (usually an assignment statement). JavaScript also allows initialization expressions with var variable declaration statements, so that a variable can be declared and initialized. Before each loop, the test expression will be executed, and the result of the expression will be judged to determine whether to execute the loop body. Before each loop, the test expression will be executed and the result will be determined whether the loop body will be executed. If the test result is the true value, the statement in the loop body will be executed. Finally, execute the increment expression. Also for the sake of usefulness, the increment expression here must also have side effects. Generally speaking, it is either an assignment expression or an expression composed of "++" and "--" operators.
The above while loop can be written using a for loop
The code copy is as follows:
for (var count = 0; count < 10; count++)
console.log(count)
Of course, some loops are more complex, and multiple variables are iterated at a time in the loop. In JavaScript, this case must be used with a comma operator, which combines the initialization expression and the autoincrement expression into one expression for use in a for loop.
The code copy is as follows:
var i, j;
for (i = 0, j = 10; i < 10; i++, j--)
console.log(i * j);
So far, the loop variables in the sample code are all numbers. Of course, numbers are the most commonly used, but not necessary. The following code uses a for loop to traverse the table data results and return the last object in the linked list (that is, the first object that does not contain the next attribute)
The code copy is as follows:
function tail(o) { //Return the last node object of the linked list
for (; o.next; o = o.next) /*empty*/ //Execute traversal based on whether o.next is the true value
return o;
}
It should be noted that this code does not contain initialize expressions, and people and one of the three expressions in the for loop can be ignored, but two semicolons are indispensable. If the test expression is omitted, it will be a dead loop. Also with the while(ture) type, one way to write a dead loop is for(;;).
iiii.for/in
The for/in statement uses the for keyword, but it is a different type of loop than the regular for loop. The syntax of the for/in loop is as follows
The code copy is as follows:
for (variable in object)
statement
A variable is usually a variable name, or an expression that can produce lvalues or a variable declared through a var statement. Anyway, it is a value that applies to the left side of the assignment expression. object is an expression, and the result of this expression is an object. Similarly, a statement is a statement or block of statements that form the body of the loop.
Using a for loop to iterate through array elements is very simple
The code copy is as follows:
var a = [1, 3, 5, "44"];
for (var i = 0; i < a.length; i++) //i represents the index of array elements
console.log(a[i]) //Output elements of each array
The for/in loop is used to conveniently traverse object member properties
The code copy is as follows:
for (var p in o) // Assign the name of the attribute to the variable p
console.log(o[p]); //Output the value of each attribute
In the process of executing the for/in statement, the javascript interpreter first calculates the object expression. If the expression is null or undefined, the javascript interpreter will skip the loop and execute subsequent code. If the expression is equal to a primitive value, this primitive value will be converted to the wrapper object (Section 3.6). Otherwise, the expression itself is already an object. JavaScript enumerates the properties of the object in turn to execute the loop. However, before each loop, javascript calculates the value of the variable expression and assigns the attribute name (a string) to it.
It should be noted that as long as the for/in loop, the value of varibale can be regarded as the lvalue of the assignment expression, and it can be any expression. This expression is calculated every loop, which means that the value it calculates may be different each time it loops. For example, you can use the following code to copy all object properties into an array:
The code copy is as follows:
var o = {x: 1,y: 2,z: 3};
var a = [],i = 0;
for (a[i++] in o) /*empty*/;
document.write(a)//=> x,y,z
JavaScript arrays are just a special object, so the for/in loop can enumerate data indexes like enumerating object properties. For example, adding this code after the above code can enumerate the data index 0, 1, 2:
The code copy is as follows:
var o = {x: 1,y: 2,z: 3};
var a = [],i = 0;
for (a[i++] in o) /*empty*/;
document.write(a)//=> x,y,z copy object properties into an array
for(i in a)
document.write(i) //=>Enum data index 0 1 2
In fact, the for/in loop does not traverse all properties of the object. Only the "enumerable" attributes will be traversed to (see 6.7). Since the built-in methods defined by the JavaScript language core are not "enumerable". For example, all objects have toString(), but the for/in loop does not enumerate the property toString(). In addition to built-in methods, there are many built-in objects that are not enumerable. All attributes and methods defined in the code are enumerable (Section 6.7 will be mentioned, but there are special means in ECMAScript5 that can make attributes not enumerable).
Objects can inherit the properties of other objects, and the line inherits custom properties (6.2.ii) can also be enumerated using for/in.
If the for/in loop body deletes an unenumerated property, then this property will not be enumerated again. If the loop body defines new properties of the object, these properties are not usually enumerated (but some implementations of javascript can enumerate the properties added in the loop body).
The order of attribute enumeration
The ECMAScript specification does not specify in which order the for/in loop enumerates the properties of the object. But in fact, the mainstream browser manufacturer javascript implementation enumerates the properties of simple objects in the order of attribute definitions, and the properties defined first are enumerated first. If an object is created in the form of a direct quantity, it will be enumerated in the order in which the properties in the direct quantity appear. (Some network and javascript libraries rely on this enumeration order, while browser manufacturers mostly do not modify this order). In the following cases, the enumeration order depends on the specific implementation (not interaction)
1. Objects inherit enumerable attributes
2. Object has properties of integer array index
3. Use delete to delete the existing properties of the object
4. Use Object.defineProperty() or similar methods to change the object properties
6. Jump
In JavaScript, a type of statement is a jump statement. From a statement understanding, it can make javascript execution jump from one position to one position.
The break statement is to jump to the end of a loop or other statement. The continue statement terminates the execution of this loop and starts the execution of the next loop. Statements in javascript can be named or labeled, break and continue can identify target loops or other statement tags.
The return statement allows the interpreter to jump out of the execution of the function body. And provide the return value of this call. The throw statement triggers or throws an exception, which is used with the try/catch/finally statement, which specifies the exception handling code logic. This is a complex jump statement. When an exception is thrown, the program will jump to the nearest closed exception star. This exception program can be in the same function or in the call stack at a higher level.
Next, describe each jump statement
i. Tag statement
A statement can be labeled, and the label is composed of the identifier and colon before the statement:
identifier:statement
By defining a tag for a statement, you can refer to this statement by its tag name anywhere in the program. You can define labels for multiple statements, although it is only more useful when defining labels for statement blocks, such as loop statements or conditional judgment statements. By defining a tag name for the loop, you can use break and continue inside the loop body to exit the loop or directly challenge to the start of the next loop. break and continue are the only statements in JavaScript that can use statement tags (this chapter will be discussed next). The following example, where the while loop defines a tag, and the continue statement uses this tag:
The code copy is as follows:
mainloop: while (token != null) {
//Ignore this code...
continue mainloop; // Jump to the next loop
//Ignore the code here...
}
The indentifier used to make the tag here must be a legal javascript identifier, not a reserved word. The namespace of a tag is different from the namespace of a variable or function, so the same identifier can be used as the statement label and as the variable or function name. A statement tag is defined only within the statements in which it works (of course it can be in its clauses). A statement label cannot be duplicated with the statement label inside it, but statement labels with the same name can appear when two codes are not nested with each other. A statement with a label can also have a label, that is, any statement can have many labels.
ii.break
The purpose of using break statements alone is to immediately exit the most memory loop or switch statement. Its syntax is as follows:
break;
Because it can exit loops and switch statements, this form of break can only appear in such statements.
We have seen the fruit break statement in the example of the switch statement. In a loop, no matter what the reason, you can exit early with break as long as you don't want to continue executing the entire loop. When the loop termination conditions are very complex, it is much simpler to use break statements to achieve such condition judgments in the function body than to write this complex termination condition directly in the loop expression.
In the following example, the entire array element is looped to find a specific value. When the entire array traversal is completed, the loop is normally exited. If the array element that needs to be found, the loop is exited using the break statement:
The code copy is as follows:
for (var i = 0; i < a.length; i++) {
if (a[i] == target) break;
}
JavaScript also allows break keywords to be followed by a statement tag (only identifiers, no colons)
break labelname;
When break and tags are used together, the program will jump to the end of the statement block identified by this tag, or directly terminate the execution of the closed statement block. When there is no closed statement block specifying the tag used by break, a syntax error will occur. When using this form of break statement, the labeled statement should not be a loop or switch statement, because the break statement can "bounce" any closed statement block. The statement here can be a set of statements composed of curly braces, using the same label to identify a set of statements.
Line wrapping cannot be done between the break keyword and labelname. Because javascript can automatically complete the omitted semicolons for statements, if there is a line break between the break keyword and the tag, the javascript interpreter will think that you are using the simplest form of break without tags, so it will add the number after break.
When you want to use break to break to break out of non-near loops or switch statements, you will use the tagged break statement. Here is the sample code:
The code copy is as follows:
var matrix = getData(); //Get a 2D array from somewhere
//Sum all elements in the matrix
var sum = 0,
success = false;
//Start from the signature so that the program will be released when an error is reported.
compure_sum: if (matrix) {
for (var x = 0; x < matrix.length; x++) {
var row = matrix[x];
if (!row) break compure_sum;
for (var y = 0; y < row.length; y++) {
var cell = row[y];
if (isNaN(cell)) break compure_sum;
sum += cell;
}
}
success = true;
}
//The break statement jumps to this
//If the success = false condition reaches here, it means there is an error in the matrix we gave
// Otherwise, sum all elements in the matrix
Finally, it should be noted that no matter whether the break statement has a label or not, its control cannot cross the boundary of the function. For example: For a function definition statement with a tag, it cannot be redirected to the outside of the function through this tag inside the function.
iii.continue statement
The continue statement is very similar to the break statement, but it does not exit the loop, but instead executes the next loop. The syntax of a continue statement is as simple as the syntax of a break statement
continue;
Continue statements will also have tags
continue lebname;
Regardless of whether the continue statement has a tag or not, it can only be used in the loop body, and a syntax error will be reported when used elsewhere.
When the continue statement is executed, the current loop logic terminates, and the next loop is executed. In different types of loops, the behavior of continue is also different.
1.在while循环中,在循环开始处指定expression会重复检测,如果检测结果为true,循环体会从头执行。
2.在do/while循环中,程序的执行至今跳转到循环的结尾处,这时会重新判断循环条件,之后才会继续下一次循环。
3.在for循环中,首先会计算自增表达式,然后再检测test表达式,用以判断是否执行循环体。
4.在for/in循环中,循环开始遍历下一个属性名,这个属性名赋给了指定的变量。
需要注意continue语句在while和for循环中的区别,while循环直接进入下一轮的循环条件判断,但for循环首先计算器increment表达式,然后判断循环条件。之前的章节讨论了和while循环“等价”的for循环行为。但由于continue在这两种循环中行为表现不同,因此使用while循环不可能完美的模拟等价的for循环。
下面这段代码展示了不带标签的continue语句,产生一个错误的时候跳过当前循环的后续逻辑
The code copy is as follows:
for (i = 0; i < data.length; i++) {
if (!data[i]) continue; //不能处理undefined数据
total += data[i];
}
和break语句类似,带标签的continue语句可以用在嵌套的循环中,用以跳出层次嵌套的循环体逻辑。同样和break语句类似,在continue语句和labname之间不能有换行。
iiii.return
回想一下,函数调用的一种表达式,而且所有的表达式都有值。函数中的return语句即是指函数调用后的返回值。这里是return语句的语法:
return expression;
return语句只能在函数体内出现,如果不是的话会报语法错误。当执行到return语句的时候,函数终止执行,并返回expression的值给调用程序。 For example:
The code copy is as follows:
function square(x) {return x * x} //一个包含return的语句函数
square(4) //执行为16
如果没有return语句,则函数调用仅依次执行函数体内的每一条语句直到函数结束,最后返回调用程序。这种情况下,调用表达式的结果是undefined。return语句经常作为函数内最后的一条语句出现,但并不是说一定一定要放在函数的最后,即使在执行return语句的时候还有很多代码没有执行到,这时候函数也还返回调用程序。
return语句可以单独使用而不必带有expression,这样的话函数也会想调用程序返回undefined.例如:
The code copy is as follows:
//如果参数是null或者undefined则立即返回
if (!o) return;
//其它逻辑
由于javascript可以自动插入分号,因此,return关键字和它后面的表达式之间不能有换行。
iiiii.throw语句
所谓异常(excepion)是当发生了某种异常情况或错误时产生的一个信号。抛出异常,就是用信号通知发生了错误或异常状况。捕获异常是指处理这个信号,抛出异常,就是用信号通知发生了错误或异常状况。捕获异常是指处理这个信号,即采取必要的手段从异常中汇丰。在javascript中,当产生运行时错误或者程序使用throw语句时就会显式的抛出异常。使用try/catch/finally语句可以捕获异常,下一节会对它作详细介绍。
throw语句的语法如下:
throw expression
expression的值可以是任意类型的。可以抛出一个代表错误码的数组,或者包含可错误消息的字符串。当javascript解释器抛出异常的时候,通常采用Eeeor类型或其子类型,当然也可以使用它们。一个error对象有一个那么熟悉表示错误类型,一个message属性用来传递构造函数的字符串(参照第三部分的Error类),在下面的例子中,当使用非法参数调用函数时就抛出一个Error对象:
The code copy is as follows:
function fa(x) {
//如果输入的参数是非法的,则抛出一个异常
if (x < 0) throw new Error("x不能是负数。");
//否则计算出一个值,正常地返回它
for (var f = 1; x > 1; f *= x, x--) /*empty*/;
return f;
}
当抛出异常时,javascript解释器会立即停止当前正在执行的逻辑,并跳转至就近的异常处理程序。异常处理程序用try/catch/finally语句的catch从句编写的。如果抛出的异常没有一条关联catch从句,解释器会检测更高层的闭合代码块,看它是否关联相关的异常处理程序。以此类推,直到扎到一个异常处理的程序为止。
如果抛出的异常函数没有处理它的try/catch/finally语句,异常将向上传播到调用该函数的代码。这样的话,异常就会沿着javascript方法的词法结构和调用栈向上传播。如果没有找到任何异常处理的程序,javascript将吧异常当成程序错误来处理,并报告给用户。
iiiiii.try/catch/finally语句
try/catch/finally语句是javascript的异常处理机制。其中try从句定义了需要处理的异常所在代码块。catch语句跟随在try从句之后,当try块从某处发送了异常时,调用了catch内的代码逻辑。catch从句跟随finnlly块,后者防置了清理代码,不管try块中是否产生了异常,finnally块内的逻辑总会执行。尽管catch和finally都是可选的,但try从句只杀二者之一与组成完整的语句。try、catch和finally语句块都需要花括号括起来,这里的花括号是必须的。即使从句中只有一条语句也不能省略花括号。
下面的代码说明了try/catch/finlly的语法和使用目的:
The code copy is as follows:
try{
//通常来讲,这里的代码会从头执行到尾而不会产生任何问题,
//但有时会抛出一个异常,要么是由throw语句直接抛出异常
//要么通过调用一个方法间接抛出异常
}
catch(e){
//当且仅当try抛出了异常,才会执行这里的代码
//这里可以通过局部变量e来获得对Error对象或者抛出的其它值的引用
//这里的代码可以基于某种原因处理这个异常,也可以忽略这个异常。
//还可以通过throw语句重新抛出异常
}
finally{
//不管try语句块是否抛出看异常,这里的逻辑总会执行,终止try的语句块方式有:
//1)正常终止,执行完语句块的最后一条语句
//2)通过break,continue或return语句终止
//3)抛出一个异常,异常被catch从句捕获
//4)抛出一个异常,异常未被捕获,继续向上传播
}
我们注意到,关键字catch后跟随了一对圆括号,圆括号内是一个标识符。这个标识符和函数参很像。当捕获一个异常时,把这个异常相关的值(比如Error对象)赋值给这个参数。和普通的变量不同,这条catch子句中的标识符具有块级作用域,它只在catch语句块内有定义。
这里有一个关于try/catch语句更实际的例子,这里使用了前面章节中提到factorial()方法,并使用客户端javascript方法prompt()和alert()来输入和输出
The code copy is as follows:
try {
//要求用户输入一个数字
var n = Number(prompt("请输入一个正整数", ""));
//假设输入是合法的,计算这个阶乘
var f = factorial(n);
//显示结果
alert(n + "!=" + f);
} catch (ex) {
//如果输入不合法,将执行这里的逻辑
document.write(ex); //告诉用户发送了什么。
}
这里的try/catch语句并不包含finally从句。尽管finally不像catch那样经常使用,但有时候它还是非常有用。然而,我们需要更详尽的解释它的行为。不管try语句块中的代码执行完成了多少,只要try语句中有一部分代码执行了,finally从句就会执行。它通常在try从句的代码后用于清理工作。
关注下面这个例子
The code copy is as follows:
try {
print("Outer try running..");
try {
print("Nested try running...");
throw "an error";
} catch (e) {
print("Nested catch caught " + e);
throw e + " re-thrown";
} finally {
print("Nested finally is running...");
}
} catch (e) {
print("Outer catch caught " + e);
} finally {
print("Outer finally running");
}
// Windows Script Host 作出该修改从而得出WScript.Echo(s)
function print(s) {
document.write(s);
}
Output:
The code copy is as follows:
Outer try running..
Nested try running...
Nested catch caught an error
Nested finally is running...
Outer catch caught an error re-thrown
Outer finally running
7.其它语句类型。
本节讨论剩余的三种javascript语句:width,debugger和use strict
i.with语句
3.10讨论了作用域链(scope chain),一个可以按序检索的对象列表,通过它可以进行变量名的解析。width语句可以用来临时扩展作用域链:它具体有如下语法:
with (object)
statement
这条语句将object添加到作用域链头部,然后执行statement,最后把作用域链恢复到原始状态。
在严格模式下(5.7.iii)是禁止使用width的,在非严格模式下也是不推荐使用width语句的,尽可能的避免使用width语句。那些使用width语句的javascript非常难优化,而且比没有使用width的语句,它运行速度更慢。
在对象嵌套层次很深的时候,常会使用with语句来简化代码的编写。例如客户端javascript中,可能使用下面的这种表达式来访问表单的一个html元素
document.forms[0].address.value
如果这段代码多次出现,则可以使用with将form对象添加至作用域链的顶层。
The code copy is as follows:
with(document.forms[0]){
//直接访问表单元素
name.value="";
address.value="";
email.value ="";
}
这种方法简化了大量的输入,不用再为每个变量添加document.forms[0]前缀。这个临时对象挂载在作用域链上,当javascript需要解析诸如address标识符时,就会在这个对象中查找。当然,不使用with的语句代码可以写成这样。
The code copy is as follows:
var f = document.forms[0];
f.name.value = "";
f.adress.value = "";
f.email.value = "";
不要忘记,只有在查找标识符的时候才能用到作用域链,创建新的变量时候不使用它,看一下下面的代码:
The code copy is as follows:
with(o) x = 1;
如果对象o有一个属性x,那么这行代码给这个属性赋值1。如果o没有定义属性x,这段代码和不使用with的代码x=1是一模一样的。它给一个局部变量或者全局变量x赋值,或者创建全局对象的一个新属性。with语句提供了一种读取o属性的快捷方法,但并不会创建o的属性。
ii.debugger语句
debugger语句通常什么也不做。然而,在调试程序可用并运行的时候,javascript解释器将会(非必须)以调试模式运行。实际上,这条语句产生一个断点(breakpoint),javascript代码执行会停止在断点的位置,这时可用使用调速器输出变量的值,检查调用栈等。
例如加上调用函数f()的时候使用了未定义的参数,因此f()抛出一个异常,但无法定位到到底哪里出了异常。为了有助于调试这个问题,需要修改f():
The code copy is as follows:
function f(o){
if (o === undefined) debugger; //这段代码用来临时调试
console.log(1) //函数的其它部分
}
f();
这时候,当调用f()没有传入参数,程序将停止执行,这时候通过调用调速器检测调用栈并找出错误的原因。
在ECMAScirpt5中,debugger语句已经正式加入到专门语言里,但在很长的一段时间里,主浏览器的厂商已经将其实现了。注意,可用的调速器是远远不够的,debugger语句不会启动调试器。但如果调试器已经在运行,这条语句才会正在产生断点。例如,使用Firefox插件firebug,首先启动firebug,这样debugger语句才能工作。
iii.“use strict”
“use strict”是ECMASCript5引入的一条指令。指令不是语句(但非常接近于语句),“use strict”和普通语句之前有两个重要区别:
1.它不包含任何语言的关键字,指令仅仅是一个包含一个特殊字符串直接量的表达式(可以是使用单引号也可以是双引号)。
2.它只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前。但它不必一定出现在脚本的首行或者函数体内的首行。因为“use strict”指令之前之后或之前都可能有其它字符串直接量的表达式语句,并且javascript的具体实现可能将它们解析为解释器自有的指令。在脚本或者函数体内第一条常规语句之后,字符串直接量表达式语句只当做普通的表达式语句对待,它们不做指令解析,它们也没有任何副作用。
使用“use strict”指令的目的是说明(脚本或函数中)后续代码解析为严格代码(strict code)。如果顶层(不在任何函数内)代码使用了“use strict”指令,那么它们就是严格代码。如果函数体定义处的代码是严格代码或者函数体使用了“use strict”指令,那么函数体的代码也是严格代码。如果eval()调用所处的代码是严格代码或者eval()要执行的字符串使用了“scrict code”指令,则eval()内的代码是严格代码。
严格代码以严格模式执行。ECMAScript5中的严格模式是该语言的一个受限的子集。它修正了语言的重要缺陷,并提供健壮的差错功能和增强安全机制。严格模式和非严格模式区别如下(前三条尤其重要)
•严格模式中禁止使用with语句
•严格模式中,所有的变量要先声明,如果给一个未声明的变量、函数、函数参数、catch从句参数或全局的对象的属性赋值。就会抛出一个引用错误异常(在非严格模式中,这种隐式声明全局变量的方法是给全局变量新添加一个新属性)
•严格模式中,调用的函数(不是方法)中的一个this值是undefined。(在非严格模式中,调用的函数中的this值总是全局变量)。可以利用这种特性来判断javascript实现是否支持严格模式。
The code copy is as follows:
var hasStrictMode = (function() {
"use strict";
return this === undefined
}());
•同样,在严格模式中,当通过call()和apply()来调用函数时,其中的this值就是通过call()或apply()传第一个参数(在非严格模式中,null和undefined值被全局对象转换为对象的非对象值锁代替)
•在严格模式中,给只读属性赋值和给不可扩展的对象创建成员都将抛出一个类型错误异常(在非严格模式中,这些操作只是简单的操作失败,不会报错)。
•在严格模式中,传入eval()代码不能再调用辰星所在的上下文中声明变量或定义函数,在非严格模式中是可以这样做的。相反,变量和函数的定义是在eval()创建的作用域中,这个作用域在eval()返回时就弃用了。
•在严格模式中,函数里的arguments对象拥有传入函数值的静态副本。在非严格模式中,agreements对象具有“魔术般”的行为,arguments里的数组元素和函数都指向同一个值的引用。
•在严格模式中,当delete运算符后面跟随非法的标识符(比如变量、函数、函数参数时)将会抛出一个语法错误,(在非严格模式下,这种delete什么也没做,并返回false)
•在严格模式中,在一对象直接量中定义两个或多个同名属性将产生一个语法错误(非严格模式下不会报错)
•在严格模式下,不允许八进制整数直接量。(以0为前缀,而不是0x为前缀)在非严格模式中是允许直接八进制直接量的
•在严格模式下,标识符eval和arguments当做关键字,他们的值是不能更改的。不能给这些标识符赋值,也不能把它们声望为变量,用做函数名,用做函数参数或用做catch块的标识符。
•在严格模式中限制了对调用栈的检测能力,在严格的模式的函数中,arguments,caller和arguments.callee都会抛出一个类型错误异常。严格模式的函数同样具有caller和arguments属性,当访问这两个属性时抛出类型错误异常。
8.javascript语句小结:
javascript语句语法:
| Statement | grammar | use |
| break | break[label]; | 退出最内侧循环或者退出switch语句,又或退出label指定的语句 |
| case | case expression: | 在switch语句标记一条语句 |
| Continue continue | continue [label]; | 重新开始最内层的循环或从新开始label指定的循环 |
| debugger | debugger; | 断点器调试 |
| default | default; | 在switch标记默认语句 |
| do/while | do statement while(expression); | while循环的一种替代形式 |
| empty | ; | Do nothing |
| for | for(init;test;incr)statement | 一种简写的循环 |
| for/in | for(var in object)statement | 遍历一个对象属性 |
| function | function name([param[],...]){body} | 声明一个函数 |
| if/else | if (expr)statement1[else statement2] | 执行statement1或者statement2 |
| label | label:statement | 给statement指定一个名字:label |
| Return | return [expression]; | 从函数返回一个值 |
| switch | switch(expression){statements} | 用case或者“default:”语句标记多个分支语句 |
| throw | throw expression | throw an exception |
| try | try {statements} [catch {hander satements}] [finally {cleanup satements}] | 捕获异常 |
| use strict | "use strict" | 对脚本和函数使用严格模式 |
| var | avr name=[=expr][,...] | 声明并初始化一个或多个变量 |
| while | while (expression) statement | 基本的循环结构 |
| with | with(object) statement | 扩展作用域链(不赞成使用) |