文档标识:[C-180416-M-180425]
知识来源:W3School ECMAScript 语法
内容链接均来源于互联网,如有侵权,请联系删除。
ECMAScript 知识概要(2)
运算符
- 等性运算符
ECMAScript 提供了两套等性运算符:等号和非等号用于处理原始值,全等号和非全等号用于处理对象。
- 等号与非等号
等号由双等号表示,即==
,当两个运算数相等时,返回true;非等号由感叹号加等号表示,即!=
,当两个运算数不相等时,返回true。这里为了确定运算数相等,会对运算数进行类型转换,规则如下:
a. 如果一个运算数是布尔值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
b. 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
c. 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
d. 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
同时还需要注意,以下规则:
a. 值 null 和 undefined 相等,即null == undefined (true)
。
b. 在检查相等性时,不能把 null 和 undefined 转换成其他值。
c. 如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
d. 如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
e. NaN 和 NaN 不相等,即NaN == NaN (false)
,因为满足 c 的规则。
总结: 运算数是数字,则均转为数字比对;运算数是布尔,自动转为数字;比对对象时,另一个运算数是字符串则转字符串,都是对象则比较引用值;运算符其中一个为null、undefined、NaN时,都返回false,而null与undefined相等,NaN出现就一定不相等。
- 全等号与非全等号
全等号由三个等号表示,即===
;非全等号由一个感叹号加两个等号表示,即!==
。与等号非等号的区别,顾名思义,全等号与非全等号就是全部相等,在进行比较时,运算数不会进行类型转换,可以理解为严格的相等。
这里需要注意的是:
a. 值 null 和 undefined 不全等,即null === undefined (false)
。
b. NaN 出现就一定不相等的规则仍然适用, 即NaN !== NaN (true)
。
- 条件运算符
这个运算符在C语言里面称为“三元运算符”,由一个问号和一个冒号组成,格式为:
条件表达式 ? 真值表达式 : 假值表达式
这里通常会将真假值表达式的值赋给变量,例如:
var expValue;
expValue = (4 > 5) ? (4 - 5) : (4 + 5);
// 相当于一个条件判断
if (4 > 5){
expValue = 4 - 5;
}
else{
expValue = 4 + 5;
}
真假值表达式里面可以再嵌套三元运算符,但不建议嵌套过多层,影响代码阅读。
赋值运算符
赋值运算符是使用最为广泛的运算符,就是一个等号,即=
。但这个和数学等式的运算顺序正好相反,是从右往左进行运算的。
主要了解下复合赋值运算符,即其他运算符与赋值运算符一起使用,达到省略一个操作数的目的,主要有:
乘法/赋值(*=)
除法/赋值(/=)
取模/赋值(%=)
加法/赋值(+=)
减法/赋值(-=)
左移/赋值(<<=)
有符号右移/赋值(>>=)
无符号右移/赋值(>>>=)
以上操作复合赋值运算符都是省略了第一个运算数,例如:a += b
等同于a = a + b
。逗号运算符
主要用于声明变量,作用是在一条语句里执行多个运算(就是为了在一个表达式里挤下更多代码),例如:
var a, b, c;
// 或者用在for循环
for(var i = 0, j = 0; i < 10; i++, j++)
也有其他用途,但是没有什么必要使用,例如:
var a;
a = (1+2, 3+4, 5+6);
// a = 11
a = 1+2, 3+4, 5+6;
// a = 3
这是因为逗号运算符是从左到右的运算顺序,且括号和赋值运算符的优先级大于逗号运算符,第一个例子最后计算的5+6
,所以a的值为11;第二个例子a在一开始就赋值运算,后面的加性表达式虽然计算了但没有把值付给变量。看吧,的确没什么用。
语句语法
ECMAScript的语句和所有语言一样,由一个或多个关键字组合,完成给定任务。如果把软件程序比作高楼大厦,语句就是一块砖头、一条钢筋,由这些基础语句的组合成数据结构,组件,模块等,最终完成整个程序。
- if 条件判断语句
if语句是所有语句使用最多的一种,和之前的条件运算符做的事情本质上是一致。语法格式主要为:
// 条件判断可以是任何表达式,最好返回值是布尔型数值,当然不是的话,ECMAScript会自动进行类型转换。
// 条件判断为真,执行代码块1的内容;条件判断为假,执行代码块2的内容。
if (条件判断){
代码块1
}
else{
代码块2
}
//
// 当然如果需要连续判断条件,也可以串联几个if 语句。
if (条件1){
代码块1
}
elseif (条件2){
代码块2
}
else{
代码块3
}
强烈建议养成良好的编程习惯,即将代码块使用中括号括起,即使只有一条语句。当然,python 程序员可能不会立马习惯。
- 循环(迭代)语句
循环语句有好几种,通常用于循环获取数组内元素用于计算,或完成重复运算任务。
- do-while 语句
do-while 语句是后测试循环,即退出条件在执行循环内部的代码之后计算。这意味着在计算表达式之前,至少会执行循环主体一次。(通俗理解就是,撸起袖子先做了再判断要不要继续做。)语法格式如下:
do{
代码块
}
while (条件)
- while 语句
while语句是前测试循环。和do-while相反,它是先判断条件,满足条件后才执行代码块,显得更理性。语法格式如下:
while (条件){
代码块
}
- for 语句
for 语句是前测试循环,而且在进入循环之前,能够初始化变量,并定义循环后要执行的代码。语法格式如下:
for (初始化变量表达式; 条件; 单次循环后表达式){
代码块
}
这个语句的几部分需要详细说明:
初始化变量表达式: 这部分主要是用于初始化变量的,可以在此处定义局部变量,不过建议所有变量的定义都统一在函数顶部定义,这部分可以被省略,没有也能工作;
条件: 这部分就和所有循环语句一样,用于判断循环是否能够继续,不能省略;
单次循环后表达式: 这部分是在执行完代码块后才运算的, 一般是对循环变量的运算,也可以被省略;
结论:for 语句是完全能代替while 语句,把初始化变量表达式
和单次循环后表达式
省略即可,但是真要这样做为什么不直接用while 语句。
- for-in 语句
for-in 语句是严格的迭代语句,用于枚举对象的属性。也就是其他语言的foreach 语句,换了个表达。好处是能够把迭代对象的元素们直接拿出来,坏处是没办法直接控制拿的数量。语法格式如下:
for (对象变量 in 对象集合){
代码块
}
举个例子:
// 存放水果名称的数组
var fruit = ['apple', 'banana', 'pear'];
//
for (eatOne in fruit){
console.log(eatOn);
}
// 分别输出:apple banana pear
如果是for 循环的话:
// 存放水果名称的数组
var i,
fruit = ['apple', 'banana', 'pear'];
//
for (i = 0; i < fruit.length; i++){
console.log(fruit[i]);
}
// 分别输出:apple banana pear
很明显看出for 语句要编写更多的代码,而且如果迭代对象不是数组而是对象的话,for-in 语句使用起来会比for 语句更流畅。
- 标签语句
标签语句就是在代码处打一个标签,表示一个点,方便后面调用跳出。语法格式如下:
label:
code
如果不使用大括号对标签范围进行限定,那么标签的范围只包括最接近它的一条语句。通常配合break
和 continue
语句一起使用。
注意:ECMAScript的标签和C语言里的标签还是有区别的,C语言的标签是标记可以理解为标记的行号,使用goto
语句跳转至指定行,且无法与break
和 continue
一起使用。
- break语句
break语句的作用,主要是用于:1.打破循环并跳出(不再执行循环) 2.跳出分支(switch-case结构)。例如:
var i, choose = 1;
// 用于循环
for (i = 0; i < 10; i++){
if (i == 5){
break;
}
}
// 用于选择分支
switch(choose){
case 1: {
break;
}
default:{
break;
}
}
配合标签使用,可跳出多层循环:
var i, j,
num = 0;
OUTER:
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
if (i == 5 && j == 5){
break OUTER;
}
num ++;
}
}
console.log(num); //输出55
如果没有标签的存在,想要跳出多层循环,只能在每一层循环里都加上条件来判断break
,或者在一个有返回值的函数里使用return
语句结束函数体(显然不太合理)。
- continue 语句
continue 语句用法基本和 break语句一致,区别是:continue 语句只能用于循环,而且是跳过当前循环一次(后续循环继续进行)。例如:
var i = 0, num = 0;
while (i < 10){
i++;
if (i == 5){
continue;
}
num++;
}
console.log(i, num);// 输出10 9
配合标签使用,可达到break
语句的效果:
var i, j,
num = 0;
OUTER:
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
if (i == 5 && j == 5){
continue OUTER;
}
num ++;
}
}
console.log(num); //输出95
这里可以看出continue OUTER
实际与单独一个break
语句效果一样, 跳出了里层循环。
- with语句
with语句用于设置代码在特定对象中的作用域。语法格式为:
with (表达式){
代码块
}
感觉和VB(Visual Basic)里的with语句一样,为了省略对同一个对象引用的多次书写。例如:
function Fruit(){
this.Name = 'apple';
this.Color = 'red';
}
// 实例
var apple = new Fruit();
with (apple){
console.log('This is a fruit named ' + Name);
console.log('and its color is ' + Color);
}
// 输出 This is a fruit named apple and its color is red
不过一般不建议使用with语句,毕竟这样写也没节省多少时间,如果对象的属性名称和外部定义变量名重复了,还容易引起歧义。
- switch 分支语句
switch 语句本质上和if 语句类似,都是条件判断语句,但是if 语句更为灵活, switch 语句在判断分支时要求所有 case 分支的判断类型需要一致,且不能是表达式。语法格式如下:
switch(表达式){
case 值1:{
代码块
break;
}
case 值2:{
代码块
break;
}
...
default:{
break;
}
}
一般来说,default
语句写在所有case
语句之后的,表示除了上述情况,其他情况适用于default
里的代码。default
块里面可以不加break
,但是如果把default
放在了case
语句之前且没有添加break
,那么满足default
情况后会把后一个case
里的代码一并执行,例如:
var i = 80;
switch(i){
case 50:{
console.log(50);
break;
}
default:{
console.log(99);
}
case 70:{
console.log(70);
break;
}
}
// 输出:99 70
再次注意:case
语句的表达式只能是一个具体的值,而不能当作一个表达式,比如case i < 10:
这种语句是无法使用的。ECMAScript允许使用字符串作为case
的条件值,也允许使用变量代替数字、字符、字符串等条件值。
有时候会特意省略case
里的break
语句,以便连续几个case
条件执行内容一致,例如:
var score = 85;
switch(score - score % 10){
case 100:
case 90:{
console.log('You got A');
break;
}
case 80:
case 70:{
console.log('You got B');
break;
}
case 60:{
console.log('You got C');
break;
}
default:{
console.log('You got D');
break;
}
}
// 输出: You got B