目录
1. 操作符
1.1 算术运算符
算数运算符和我们在数学中的学的一样,主要用于数值的运算,JavaScript中提供的算数运算符有下面这些:
操作符 | 作用 | |
---|---|---|
+ | 加 | |
- | 减 | |
* | 乘 | |
/ | 除(斜杠) | |
% | 取余数 | |
( ) | 提高优先级 |
-
特殊情况-字符型数据运算
//减、乘、除、取余运算时,首先会将字符串转换成数字,然后再进行运算。 console.log('28' - '18'); // 10 console.log('32' / '4'); // 8 console.log('3' * '4'); // 12 console.log('12' % '5'); // 2 // 数值和字符运算 console.log(12 + ''); // '12' console.log(12 + 3 + '4'); // '154' console.log('4'+ 12 + 3); // '4123' //特殊情况 console.log('123abc' - '123'); //NaN
-
特殊情况-浮点数进行运算
console.log(0.1 + 0.2) //0.30000000000000004
1.2 赋值运算符
简单的赋值操作符由等号(=)表示,它的作用就是把右侧的值赋值给左侧的变量,如下所示:
var num = 7; //刚开始班里有7个人
如果在等号(=)前面再添加算术运算符的话,就可以完成复合赋值操作。如下所示:
var num = 7; //刚开始班里的人数
num = num + 9 //后来有来了9个
第二行代码可以用一个复合赋值来代替:
var num = 7; //刚开始班里的人数
num += 9 //后来有来了9个
每个算术操作符都有对应的复合赋值操作符,如下表所示:
操作 | 普通写法 | 简写形式 |
---|---|---|
普通赋值 | var age = 20 | var age = 20 |
加法赋值 | age = age + 1 | age += 1 |
减法赋值 | age = age - 1 | age -= 1 |
乘法赋值 | age = age * 2 | age *= 2 |
除法赋值 | age = age / 2 | age /=2 |
求余赋值 | age = age % 3 | age %= 3 |
1.3 自增自减操作符
i++ ++i
-
在不参与运算的情况下:它们都是自增1
-
在参与运算的情况下,++写在后面,先参与运算,然后加1;++写在前面,在参与运算前,i先加1,然后再参与运算。
// 在不参与运算的情况下,无论 ++ 写在操作数(age)的前面还是后面,结果都是 age 自身加一。 var age = 18; age++; ++age; console.log(age); // 在参与运算的情况下,++ 写在操作数后面,age 先参与运算,然后再自身加一。 // ++ 写在操作数前面,age 先自身加一,然后再参与运算。 var age1 = 18; var num1 = 82 + age1++; console.log(num1, age1); // 100, 19 var age2 = 18; var num2 = 82 + (++age2); console.log(num2, age2); // 101, 19
i-- --i
-
在不参与运算的情况下,都是自减1
-
在参与运算的情况下,--写在后面,先参与运算,然后减1;--写在前面,在参与运算前,i先减1,然后再参与运算。
// 在不参与运算的情况下,无论 -- 写在操作数(age)的前面还是后面,结果都是 age 自身减一。 var age = 18; age--; --age; console.log(age); // 16 // 在参与运算的情况下,-- 写在操作数后面,age 先参与运算,然后再自身减一。 // -- 写在操作数前面,age 先自身减一,然后再参与运算。 var age1 = 18; var num1 = 82 + age1--; console.log(num1, age1); // 100, 17 var age2 = 18; var num2 = 82 + (--age2); console.log(num2, age2); // 99, 17
1.4 逻辑运算符(重点)
运算符 | 含义 |
---|---|
&& | 与(且) |
|| | 或 |
! | 非 |
逻辑与(&&)
逻辑与操作符由符号 &&
表示,有两个操作数,如下例所示:
var result = true && false; //false
逻辑与的真值表如下:
第一个操作数 | 第二个操作数 | 结果 |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
当然,逻辑与的操作数不仅仅是布尔值,还可以应用于任何类型的操作数。此时,它遵循下列规则:
-
如果两个操作数被转换成布尔值第一个是
true
,则返回第二个操作数; -
如果两个操作数被转换成布尔值第一个为
false
,则返回第一个操作数;
console.log(false && true); // false
console.log('abc' && 1); // 1
console.log(0 && 1); // 0
console.log('' && 0); // ''
逻辑与操作属于短路操作,即如果第一个操作数是 false
,那么无论第二个操作数是什么值,结果都不可能是true了。我们来看个例子:
var found = true;
var result = (found && undefinedVariable); //这里会发生错误
alert(result); //这一行不会执行
在上面的代码中,当执行逻辑与操作时会发生错误,因为变量undefinedVaribale没有定义。由于变量found的值是true,所以逻辑与操作符会继续对变量undefinedVariable求值。但undefinedVaribale尚未定义,所以会报错。下面我们来改一改上例中的代码:
var found = false;
var result = (found && undefinedVariable); //这里不会发生错误
alert(result); //这一行会执行
在这个例子中,警告框会显示出来。无论变量undefinedVariable有没有定义,都不会对它求值,因为第一个操作数的值是false。也就是说如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。
逻辑或(||)
逻辑或操作符由两个竖线符号(||)表示,由两个操作数,如下所示:
var result = true || false; //true
逻辑或的真值表如下:
第一个操作数 | 第二个操作数 | 结果 |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
与逻辑与操作符一样,逻辑或的操作数也不仅限于布尔值,它也可以是其他类型的操作数。此时,它遵循下列规则:
-
如果两个操作数被转换成布尔值第一个是
true
,则返回第一个操作数; -
如果两个操作数被转换成布尔值第一个为
false
,则返回第二个操作数;
console.log(false || true); // true
console.log('abc' || 1); // 'abc'
console.log('' || 0); // 0
与逻辑与操作符一样,逻辑或操作符也是短路操作符。也就是说,如果第一个操作数的求值结果为true,就不会对第二个操作数求值了。示例如下:
var found = true;
var result = (found || undefinedVariable); //这里不会发生错误
alert(result); //这一行会执行
这个例子更前面的例子一样,变量undefinedVariable也没有定义。但是,由于变量found的值是true,而变量undefinedVariable永远不会被求值,因此结果就会输出“true”。如果把found的值改为false,就会导致错误:
var found = false;
var result = (found && undefinedVariable); //这里会发生错误
alert(result); //这一行不会执行
逻辑非(!)
逻辑非操作符由一个叹号(!)表示,可以应用于 ECMAScript 中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值。逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。逻辑非操作符遵循下列规则:
-
如果操作数被转换成布尔值之后是true,直接返回布尔值:false;
-
如果操作数被转换成布尔值之后是false,直接返回布尔值:true;
下面举几个例子:
alert(!new Object()); //false
alert(!""); //true
alert(!"hello world"); //false
alert(!0); //true
alert(!23); //false
alert(!null); //true
alert(!NaN); //true
alert(!undefined); //true
1.5 关系运算符
操作符 | 作用 |
---|---|
> | 大于号 |
< | 小于号 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 等于 |
=== | 全等于 |
!= | 不等于 |
!== | 不全等于 |
小于(<)、大于、小于或等于、大于或等于这几个关系操作符用于对两个值进行比较,比较的规则与我们在数学课上学的一样。这几个操作符都返回一个布尔值,看下面的例子:
var result = 5 > 3; //true
var result = 5 < 3; //false
当参与比较的操作数是非数值类型时,则会先进行数据类型转换,然后再参与比较。比较规则如下:
-
如果两个操作数都是数值,则执行数值比较。
-
如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
-
如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
我们来看一个例子:
var result = "Brick" < "alpha"; //true
很多人会认为,在比较字符串值时,小于的意思是“在字母表中位置靠前”,而大于则意味着“在字母表中的位置靠后”,但实际上完全不是那么回事。在比较字符串时,实际上比较是连个字符串中对应位置的每个字符在ASCii编码表中对应的编码值(字母B的编码值为66,字母a的编码值是97)。再看一个例子:
var result = "23" < "3"; //true
当比较字符串“23”是否小于“3”时,结果居然也是true。这是因为两个操作数都是字符串,而字符串比较的是字符编码(“2”的字符编码是50,而“3”的字符编码是51)。如果是将一个操作数改为数值呢:
var result = "23" < 3; //false
此时,字符串“23”会被转换成数值23,然后再与3进行比较,因此就会得到合理的结果。在比较数字和字符串时,字符串都会被转换成数值,然后再进行比较。这个规则对上面的例子是使用的,可是,如果那个字符串不能转换成一个合理的数值呢?比如:
var result = "a" < 3; //false,因为 "a" 被转换成了NaN
由于字母“a”不能转换成合理的数值,因此就被转换成了 NaN
。根据规则,任何操作数与 NaN
进行关系比较,结果都是 false
。于是就出现了下面的情况:
var result1 = NaN < 3; //false
var result2 = NaN >= 3; //false
按照常理,如果一个值不小于另一个值,则一定是大于或等于那个值。然而,在与 NaN
进行比较时,这两个比较操作的结果都返回了 false
。
连比的写法
比如,我们想看看 2
这个数字,是不是在 3
和 15
之间,你可能会像下面这样写:
alert(3 < 2 < 15) //true
结果与预想的结果好像不符,这是为什么呢?其实这种写法是错误的。
这是因为,计算机会先比较 3 < 2
,得到的结果是 false
。然后再比较 false < 15
,false
会被隐式转换为0
,所以 0 < 15
的结果是 true
。
正确的写法应该先拆开,中间用一个 &&
连接。也就是说:3 小于 2 且 2 小于15 。
alert(3 < 2 && 2 < 15) //false
==和===的用法
-
对于基本数据类型来说: ==当类型相等时,判定值是否相等,当类型不相等时,转换成相同的类型后,比较值是否相等。 ===只有当类型相等时,判定值是否相等。
!==运算符(不等值或不等型)
console.log(30 !== 30); //false
console.log('20' !== '20'); //false
console.log(11 !== 30); //true
console.log('202' !== '20') //true
1.6 条件运算符(三元运算符)
语法:
表达式 ? 如果表达式结果为true,执行这里的代码1 : 如果表达式结果为false,执行冒号后面的代码2 ;
执行顺序:
-
判断条件表达式是否为
true
。 -
如果为
true
,执行问号(?
)后面的代码。 -
如果为
false
,执行冒号(:
)后面的代码。
1.7 运算符优先级
常用运算符优先级从高到底
1. ( )优先级最高
2. 一元运算符 ++ -- !
3. 算数运算符 先* / % 后 + -
4. 关系运算符 > >= < <=
5. 相等运算符 == != === !==
6. 逻辑运算符 先&& 后||
7. 赋值运算符
// 练习1:
4 >= 6 || '人' != '好谷' && !(12 * 2 == 144) && true
// 练习2:
var num = 10;
5 == num / 2 && (2 + 2 * num).toString() === '22'
2. 流程控制语句
2.1 if-else语句
根据条件返回的结果(真或假或其它预定义的),来判断下一步要执行的语句。JavaScript提供了两种条件判断语句:if...else
和 switch
。
if (如果明天不下雨) {
我就出去玩;
}else {
我就在家写作业;
}
条件可以是任何返回结果是 true
或 false
的表达式。如果条件表达式返回的是 true
,语句1 会被执行;否则,语句2 被执行。
如果有多个判断条件,可以使用 else if
来进行判断,就像下面这样:
if (如果明天不下雨) {
我就出去嗨;
} else if (如果爸妈不在家) {
我就在家玩游戏;
} else if (如果没有带书包){
我就睡觉;
} else {
我就乖乖地在家写作业;
}
2.2 switch语句
switch 语句允许用一个表达式的值或一个变量和 case
标签后面的值相匹配。如果匹配成功,就执行这个 case
标签后面的代码。
语法:
switch (一个表达式的值或一个变量) {
case 常量1:
要执行的代码1
break;
case 常量2:
要执行的代码2
break;
...
default:
要执行的代码
break;
}
swit ch :开关 , case :选项
执行顺序:
-
首先会判断第一个
case
后面的值是否与表达式的结果相等; -
如果相等,就会执行
case
后面代码,当遇到break
时,switch
语句停止执行; -
如果不匹配,接着判断下一个
case
后面的值; -
如果所有的
case
都不匹配, 程序会去执行default
后面的代码; -
switch比较的值是===等关系。
注意:default 语句不是必须的,在不需要的时候可以不写。如果需要的话,应该写在switch语句的最后。
多学一招
switch 语句和 if else if 语句的区别
-
一般情况下,它们两个语句可以相互替换
-
switch...case 语句通常处理 case为比较确定值的情况, 而 if…else…语句更加灵活,常用于范围判断(大于、等于某个范围)
-
switch 语句进行条件判断后直接执行到程序的条件语句,效率更高。而if…else 语句有几种条件,就得判断多少次。
-
当分支比较少时,if… else语句的执行效率比 switch语句高。
-
当分支比较多时,switch语句的执行效率比较高,而且结构更清晰。
2.3 break语句
break语句可以在循环体或判断语句中,只要代码遇到break,就会立马结束当前循环或者判断。
2.4 for语句
语法:
for(var i = 0; i <= 10; i++){
循环体代码
}
执行顺序:
-
首先进行变量初始化(
var i = 0
),通常被用于初始化一个计数器,该表达式可以使用 var 关键字声明新的变量,这个变量帮我们来记录次数。; -
判断条件表达式是否成立(
i <= 10
); -
如果条件成立,则执行循环体内的代码,执行完之后,执行
i++
,让i
自增 1 ,接着再次判断条件表达式是否成立,如此循环往复,直到条件表达式不成立为止; -
如果条件不成立,则循环体内的代码不会执行,循环结束。
应用
-
100以内数值的和
-
双层for循环(打印直角三角形)
2.5 continue语句
continue语句的作用是终止本次循环,接着进行下一次循环。
举例子:过7游戏
//过7游戏
for(var i = 1; i < 100; i++){
if(i % 7 == 0){
console.log("过");
continue;
}
console.log(i);
}
2.6 while语句
语法:
while(条件表达式){
循环体内的代码
}
执行顺序:
-
首先判断条件表达式是否成立;
-
如果成立,执行大括号中的代码,然后再次判断条件表达式是否成立;
-
如果不成立,就不执行大括号中的代码,循环结束。
举例子
// 当条件表达式结果为true,会一直执行while循环体内的代码。 // 当条件表达式的结果为false,while循环不再执行。
2.7 do-while语句
语法:
do{
循环体;
}while(条件表达式);
执行顺序:
-
程序一开始,直接进入循环体内,执行一遍循环体内的代码;
-
判断条件表达式是否成立,如果条件成立,那么继续执行循环体内的代码;
-
如果条件表达式是否成立,那么循环体内的代码就不再执行,循环结束;
注意:do-while 循环在条件不满足的情况下会比 while 循环多执行一次循环体内的代码。
2.8 布尔类型的隐式转换
流程控制语句会把后面的值隐式转换成布尔类型
转换为true 非空字符串 非0数字 true 任何对象
转换成false 空字符串 0 null undefined NaN false
// 结果是什么?
var a = !!'123';
举例
var message;
// 会自动把message转换成false
if (message) {
// todo...
}
2.9 练习打印金字塔和九九乘法表
金字塔:
分析金字塔组成:由空格和星星*组成的三角形。 分析*和空格的分布规律(假设最上面的一个星星作为金字塔的第一层)。
每层星星前的空格 = 金字塔层数 – 当前层数。例如当前行数为第3层,则空格数=5-3=2。 每层中星星的数量 = 当前层数*2 -1。例如当前为第4层,则星星数= 4*2-1=7。
乘法口诀:
假设最上面的一层作为第1层,乘法运算的规律:
① 被乘数的取值范围在“1~每行中的列数”之间。如表格第3行中被乘数的值在1~3之间。
② 乘数的值 = 表格的行数。如表格第3行中乘数的值就为3。
找规律,假设最上面的一层作为第1层,乘法运算的规律:
① 被乘数的取值范围在“1~每行中的列数”之间。如表格第3行中被乘数的值在1~3之间。
② 乘数的值 = 表格的行数。如表格第3行中乘数的值就为3。