JavaScript程序由语句组成,语句遵守特定的语法规则。
以下是一些常用的语句讲解:
1、block,块语句,用一对花括号定义,常用于组合0~多个语句。一般不常单独使用,而是与if/while等结合使用。
语法:
{
语句1;
语句2;
···
语句n;
}
例:
{
var i = 2;
console.log(i);
}
if(true){
console.log('ok');
}
需要注意的是,当一个完整的语句是以左花括号开头的时候,会被理解为block,而不是对象自变量。
{a:0,b:1}; //SyntaxError:Unexpected token :
var obj = {a:1,b:1}; //ok
还有一点要注意的是:在js中,没有块级作用域。
for(var i=0;i<3;i++){
var str = 'hi';
console.log(str);
}
相当于:
var i=0;
for(;i<3;i++){
var str = 'hi';
console.log(str);
}
i; //2
str; //'hi',在for循环外依旧可以直接访问for循环语句块内声明的变量
虽然没有块级作用域,但是js拥有函数作用域,即在函数中声明的变量,是不能直接在函数外访问到的。
funcion func(){
var a = 1;
console.log(a);
}
func(); //1
a; //undefined
2、var,变量声明语句,用来声明变量。需要注意以下的用法:
var a=b=1; //a=1,b=1
但是这样使用实际上b并没有用var声明,因此会自动提升为全局变量。
function func(){
var a=b=1;
}
console.log(typeof a); //'undefined'
console.log(typeof b); //'number'
为了避免这个问题,同时声明多个变量时应该用逗号分隔,即:
var a=1,b=1;
3、try/cacth语句,用于异常捕获和处理。
try{
throw 'test';
}catch(e){
console.log(e);
}finally{
console.log('finally');
}
其流程是先执行try块中的代码;若抛出异常,则由catch从句去捕获并执行,若没有异常,则忽略catch语句;不管有没有异常,最终都会执行finally语句。
try/catch语句可以有三种形式:try/catch(没有finally语句),try/finally(没有catch语句),try/catch/finally。
try/catch嵌套:(try语句块中的报错会跳到最近的一层catch处理;内部的报错若没有处理,在交给外层的catch处理之前需要先执行内部的finally语句块;若内部报错已在内部处理,则不会再交给外部catch处理)
示例a:
try{
try{
throw new Error 'oops';
}finally{
console.log('finally');
}
}catch(e){
console.error('outer',e.message);
}
//执行结果:
//'finally'
//'outer' 'oops'
示例b:
try{
try{
throw new Error 'oops';
}catch(e){
console.error('inner',e.message);
}finally{
console.log('finally');
}
}catch(e){
console.error('outer',e.message);
}
//执行结果:
//'inner' 'oops'
//'finally'
示例c:
try{
try{
throw new Error 'oops';
}catch(e){
console.error('inner',e.message);
throw e;
}finally{
console.log('finally');
}
}catch(e){
console.error('outer',e.message);
}
//执行结果:
//'inner' 'oops'
//'finally'
//'outer' 'oops'
4、function,函数语句,用来定义函数对象。
//函数声明
func(); //true
function f(){
//do sth.
return true;
}
//函数表达式
func(); //TypeError
//do sth.
return true;
}
函数声明和函数表达式最主要的一点区别在于:函数声明会被预先处理,或者叫函数前置,因此可以在函数声明之前调用函数;而函数表达式则不能在表达式之前调用函数。
除这两种方法之外还以用new Function的方法来创建函数对象。
5、for…in,for…in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。
var p;
var obj = {x:0,y:1};
for(p in obj){
console.log(p);
}
//执行结果:
//x
//y
for…in语句有几点问题:
- a、顺序不确定,具体的顺序依赖于引擎的实现;
- b、对象属性具有属性描述器,若其中的enumerable标签为false时,属性不会在for in 中出现;
- c、for in 会受原型链的影响,若对象原型链上原型的某些属性的enumerable为true的话,也会在for in 中出现。
6、switch语句,是一种条件分支语句。使用switch语句需要注意的是除非特定需求,否则每个case语句后都应该使用break来跳出分支,若不加break,则switch语句在执行完正确匹配的分支后会继续执行后面的分支。
var val=2;
switch(val){
case 1:
console.log(1);
break;
case 2:
console.log(2);
break;
default:
console.log(0);
break;
}
//执行结果:
//2
var val=2;
switch(val){
case 1:
console.log(1);
case 2:
console.log(2);
default:
console.log(0);
}
//执行结果:
//2,0
var val=2;
switch(val){
case 1:
case 2:
case 3:
console.log(123);
break;
case 4:
case 5:
case 6:
console.log(456);
break;
default:
console.log(0);
break;
}
//执行结果:
//123
7、循环语句,包括for语句,while语句,do…while语句
while(true){
//do sth.
}
do{
//do sth.
}while(true)
var i;
for(i=0;i<n;i++){
//do sth.
}
8、if/else语句,判断语句
if(a){ //a == true
//do sth.
}
else if(b){ //b == true
//do another thing
}
else{ //a != true
//do other things
}
9、with语句,用于设置代码在特定对象中的作用域。
var obj = {x:1};
with(a){
console.log(x); //1,相当于a.x
}
注意,with语句有以下几点缺陷:
a、让JS引擎优化更难
b、可读性差
c、可被变量定义代替(对于深层次的对象访问时,可以定义一个变量代替要访问的变量,进而访问其属性,而不是用with)
d、严格模式下被禁用
事实上js目前已经不建议使用with了。