Javascript-5语句

js第五章语句

5.2 复合语句和空语句

复合语句:用花括号将多条语句括起来,当一条语句使用
1
2
3
4
5
6
7
8
9
{
x = Math.PI;
cx = Math.cos(x);
console.log("cos(Pi)= " +cx);
}
//注意
1. 语句块结尾不需要分号
2. 语句块中的行都要有缩进,但非必需,增加可读性
3. Js无块级作用域,语句块中声明的变量非语句块私有
空语句
1
2
3
4
5
;
创建一个具有空循环体的循环时,空语句有时候是很有用的
for(i = 0;i<a.lenth;a[i++]=0) ;

if((a==0)||(b==0));//那么这时候空语句就不是帮忙的了,因为这句话什么也没做

5.3 声明语句

  • 声明语句:这些语句定义标识符(变量名和函数名)并给其赋值

var

1
2
3
4
5
 var x = 2.34, y = Math.cos(0.75),r,theta; //很多变量
var x = 2, y = x*x; //第二个变量使用了第一个变量
var x = 2,
f = function(x){return x*x}, //每个变量独占一行
y = f(x);
  • var语句出现在函数体内,定义的是全局变量,作用于是这个函数
  • 在顶层代码中使用var语句,他声明的是全局变量,在整个javaScript程序中都是可见的
  • var声明的变量无法通过delete删除
  • 若var的变量为指定初始化,则初始为undefined
  • 变量声明语句会被提前至脚本或者函数的顶部。但是初始化的操作则还在原来的var语句的位置执行,在声明语之前变量的值是undefined
  • 重复生命变量是合法的

let

  • 声明局部变量
  • 用法类似var ,但是所声明的变量,旨在let命令所在的代码块内有效,而且有暂时性死区的约束
  • let不允许在相同作用域内,重复声明同一个变量

const

  • 与let类似,但不能重复赋值

function

1
2
var f = function(x){ return x+1; }	//将表达式赋值给一个变量
function f(x) { return x+1; } //含有变量名的语句
  • 注意
    • 定义函数时,不执行函数体内的语句,他和调用函数时待执行的新函数对象相关联
    • 即使是函数体只包含一条语句,仍然要用花括号
    • 函数声明语句通常出现在JavaScript代码的顶层,也可以出现在所嵌套函数的顶部。也就是说,函数定义不能出现在if语句、while循环或者其他任何语句中
    • 函数声明、函数名称和函数体均提前:脚本中的所有函数和函数中所有嵌套的函数都会在当前上下文中其他代码之前声明
    • 无法delete

5.4条件语句

if

  • JavaScript 使用if(){…} else{ }
  • else 可选,若语句块中只含有一条语句,可以省略
  • 如果还要更加细致的判断条件,可以使用多个if else 的组合

switch

1
2
3
4
5
6
7
8
9
10
11
12
switch(n){
case 1:
//bla
break;
....


....
default:
//执行代码
break;
}
  • 注意:
    • 如果没有default标签,switch语句将跳过它左右的代码块
    • case关键词跟随任意的表达式
    • 可以使用return 来代替break
    • “default:”标签可以放置在switch的任何地方,但最常用出现在switch的末尾

while /do while/for 不讲了

for /in

1
2
for(variable in object)
statement
  • variable 是一个适用于赋值表达式左侧的值
  • object 是一个表达式,这个表达式的计算结果是一个对象
  • statement 是一个语句或者语句块,是这个循环的主体
  • 以任意顺序遍历一个对象除了Symbol以外的可枚举属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var o = {
name:'Rechel',
age:22,
city:'Shanghai'
};
for(var key in o){
console.log(key);
}
//结果就是: name , age, city

var a = ['a','b','c'];
for(var i in a)
{
console.log(i) //'0','1','2'
console.log(a[i])//'a','b','c'
//因为再数组中,他的index下标就是数组的属性
}

for/of

  • for…of 循环时ES6引入的额新的语法
  • 语法(与for/in相同)
    • for(variable of iterable{
      • ​ //statements
    • }
  • Variable: 在每次迭代中,将不同属性的值分配给变量
  • iterable:被迭代美剧其属性的对象
  • 使用对象:for…of 语句在可迭代对象(包括:Array,Map,Set,String,TypedArray,arguments对象等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
for/of .for/in 的区别
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Object.prototype.objCustom = function(){};
Array.prototype.arrCustom = function(){};
let iterable = [3,5,7];
iterable.foo = 'hello';
for(let i in iterable)
{
//这里为什么会出先这么多属性?
//因为iterable是一个数组对象,它自身包含了0,1,2,"foo"这些属性
//但是他同时也是Array对象,Object对象的一个实例,所以说会继承Object,Array的属性
console.log(i);//0,1,2."foo","arrCustom","objCustom"
}
for(let i in iterable)
{
//hasOwnProperty代表了这个对象的自身的属性,这时候继承的属性就不会出现
if(iterable.hasOwnProperty(i)){console.log(i);//0,1,2,"foo"}
}
for(let i of iterable)
{
console.log(i);//3,5,7
}
  • 主要区别在于他们的迭代方式
  • for…in 语句以任意顺序迭代对象的可枚举属性
  • for…of 显示的是数据

forEach循环(The Best)

  • for in 遍历的对象属性的名称
  • for of 遍历的是集合本身的元素
  • 更好的方式是直接使用iterable内置的forEach方法,它接受一个函数,每次迭代自动回调该函数
在array中使用forEach
1
2
3
4
5
6
7
var a = ['A','B','C'];
a.forEach(function(element,index,array){
//element:指向当前元素的值
//index: 指向当前的索引
//array : 指向Array对象本身
console.log(element+', index ='+ index);
})
在set中使用forEach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var s = new Set(['A','B','C']);
s.forEach(function(element,sameElement,set){
console.log(element);
console.log(sameElement);

})
A
A
-------------------
B
B
——————————————————
C
C
-------------------
//Set与Array类似,但Set没有索引,因此回调函数的前两个参数都是元素本身
forEach循环例子
  • Map的回调函数参数依次为value,key和map本身
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var m = new Map([[1,'x'],[2,'y'],[3,'z']]);
m.forEach(function(value,key,map){
console.log(value);//值
console.log(key);//索引
console.log(Map);//图本身
});
//结果
x
1
[Function: Map]
y
2
[Function: Map]
z
3
[Function: Map]

迭代器与生成器

  • 迭代器是通过使用next() 方法实现iterator protocol 的任何一个对象,该方法返回具有两个属性的对象
    • value,这是序列中的next值
    • done,如果已经迭代到序列中的最后一个值,则它为true
迭代器与生成器
+ 生成器是一种返回迭代器的函数,通过function关键字后的星号*来表示,函数中会用到新的关键词yield
+ 星号可以紧挨者关键字function,也可以在中间添加一个空格

示例

  • 关键词yield 可以返回任何和表达式,通过生成器函数批量给迭代器添加元素
1
2
3
4
5
6
function *myIterator(list){
for(let i = 0;i<list.lenth;i++)
{
yield list[i];
}
}

示例

示例

5.6跳转

标签语句

  • 语句是可以添加标签的,科在程序的任何地方通过标签名引用这条语句
    • identifier: statement
    • identifier 必须是一个合法的JS 标识符,而不能是一个保留字
    • 可以使用统一标识符作为语句标签和变量名或者函数名
    • 任何语句可以有很多个标签
  • break和continue是JS中唯二可用语句标签的语句!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
mainloop:while(token!=NULL)
{
//忽略这里的代码
continue mainloop;//跳转到下一次循环
}

var iNum = 0;
outermost:
for(var i = 0;i<10;i++)
{
for(var j = 0;j<10;j++)
{
if(i==5&&j==5)
{
break outermost;
}
iNum++;
}
}
console.log(iNum);//输出55

outermost:
for(var i = 0;i<10;i++)
{
for(var j = 0;j<10;j++)
{
if(i==5&&j==5)
{
continue outermost;
//跳到最外圈,开始跑,也就是说55-59这些数被吃掉了
}
iNum++;
}
}
console.log(iNum);//输出95

break语句

continue语句

return语句

  • return语句只能在函数体内出现
  • 执行到return 语句的时候,函数终止执行,并返回expression的值给调用程序
  • 如果没有return 语句,调用表达式的结果是undefined
  • JavaScript可以自动插入分号,return 关键字和她后面的表达式之间不能有换行

throw语句

  • 在Javascript中,当产生运行时错误或者程序使用throw语句时就会显示地抛出异常
  • throw expression
  • expression的值可以实任意类型的
    • 代表错误码的数字
    • 刻度的错误消息的字符串
    • Error类型和其子类型
      • 一个Error对象有一个name属性表示错误类型,一个message属性用来存放传递给构造函数的字符串

示例

  • 跳转-错误处理,错误处理时程序设计时必须要考虑的问题

示例

  • 有错误发生时,执行流程像这样
    • 先执行try{…}代码
    • 执行到出错的语句时,后续语句不再继续执行,转而执行catch(e){…}代码
    • 最后执行finally{…}代码
  • 没有错误发生时,执行流程像这样
    • 先执行try{…}代码
    • 因为没有出错,catch(e){…}代码不会被执行
    • 最后执行finally{…}代码
  • 最后请注意,catch和finally可以不必都出现
  • try,catch,finally 语句块都需要使用花括号,花括号是必须的

  • JavaScript 有一个标准的Error对象表示错误,在处理错误是,可以通过catch(e)捕获的变量e访问错误对象

1
2
3
4
5
6
7
8
9
10
11
try{
....
}catch(e){
if(e instanceof TypeError){
alert('Typr error!');
}else if(e instanceof Error){
alert(e.message);
}else{
alert('Error: '+e);
}
}

示例

示例

5.7其他语句类型

use strict

  • use strict 是说明严格模式
  • 只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前
  • 为了避免缺陷建议所有的JS代码都应该使用严格模式
    • 最简单的就是在JS代码的第一行上写上:’use strict’;
  • 严格模式和非严格模式中的区别
    • 严格模式中所有的变量都要先声明
    • 不能使用with语句
    • 调用的函数(不是方法)中的一个this值时undefined,在非严格模式中调用的函数中的this值总是全局对象

with语句,建议不要用

debugger语句

小结

示例

示例

-------------本文结束,感谢您的阅读-------------