4 JavaScript运算符和表达式
JavaScript描述了一组用于操作数据值的运算符,包括一元运算符(++ --)、逻辑运算符、算术运算符、关系运算符、三目运算符及赋值运算符。ECMAScript 中的运算符适用于很多值,包括字符串、数值、布尔 值、对象等。
表达式: 表达式由一个或多个操作数通过操作符组合而成,就是由数据和运算符组成的一个式子。 例如:x+y;x/10; x+23/2+y; x%y等都是表达式。
操作数: 表达式中的变量成为操作数。
运算符: 表达式中起运算作用的符号称为运算符。
简而言之:用来做运算的符号就是运算符;由运算符连接起来的式子叫表达式。
4.1 算术运算符
运算符 | 运算规则 | 运算符 | 运算规则 |
---|---|---|---|
+ | 加法 | * | 乘法 |
+ | 连接字符串 | / | 除法 |
- | 减法 | % | 取余数 |
** | 幂(ES7) |
JS里面的算数运算规则:
任意数据类型和字符串进行加法运算,都是字符串的拼接 ;
任意数据类型和NaN进行四则运算,结果都是NaN ;
当true和false参与运算,true转换为1,false转换为0 ;
除+运算外,数值类型字符串参与运算,都转换为数值;但是非数值类型字符参与运算,结果都是NaN ;
除+运算外,空字符串转换为0,null转换为0 ;
0可以作为除数,得到结果都是无穷大 ;
0参与取余运算,得到结果都是NaN。
4.2 一元运算符
递增和递减运算符概述:
如果需要反复给数字变量添加或减去1,可以使用递增(++)和递减( – )运算符来完成。
在 JavaScript 中,递增(++)和递减( – )既可以放在变量前面,也可以放在变量后面。放在变量 前面时,我们可以称为前置递增(递减)运算符,放在变量后面时,我们可以称为后置递增(递 减)运算符。
递增和递减运算符必须和变量配合使用。
++在前,整体是一个新值,++在后,整体是一人旧值。
-
++
var num1 = 5; num1++; var num2 = 6; console.log(num1 + ++num2); // 13,前置++ var num3 = 6; console.log(num1 + num3++); // 12,后置++
前置和后置的区别:
在没有赋值操作,前置和后置是一样的。但在赋值操作时,如果递增或递减运算符前置,那么前置 的运算符会先累加或累减再赋值,如果是后置运算符则先赋值再累加或累减。运算的时候也是一样;
var a = 1; var b = ++a + ++a; console.log(b);//5
var a = 1; var b = a++ + ++a; console.log(b);//4
var a = 1; var b = a++ + a++; console.log(b);//3
var a = 1; var b = ++a + a++; console.log(b);//4
其他类型应用一元运算符的规则:
var box = '89'; box++; //90,数值字符串自动转换成数值
var box = 'ab'; box++; //NaN,字符串包含非数值转成NaN
var box = false; box++; //1,false 转成数值是0,累加就是1
var box = 2.3; box++; //3.3,直接加1
4.3 逻辑运算符(布尔运算符)
逻辑运算符通常用于布尔值的操作,一般和关系运算符配合使用,有三个逻辑运算符:逻辑与(AND)、逻辑或(OR)、逻辑非(NOT)。
-
&&
:与运算两个操作数同时为 `true,结果为 true,否则为 false
-
||
:或运算两个操作数有一个为 true,结果为 true,否则为 false。
-
!
:非运算逻辑值取反。
var a = 1;
var b = true || ++a;
console.log(b); // true
var c = false && ++a;
console.log(c); // false
逻辑与运算符属于短路操作,顾名思义,如果第一个操作数返回是false,第二个数不管是true 还是 false 都返回的false。
和逻辑与运算符相似,逻辑或运算符也是短路操作。当第一操作数的求值结果为true,就不会对第 二个操作数求值了。
逻辑非运算符可以用于任何值。无论这个值是什么数据类型,这个运算符都会返回一个布尔值。它 的流程是:先将这个值转换成布尔值,然后取反。
注:JavaScript虽说也有& 和 |,但是这里不是做逻辑运算符,而是位运算符
4.4 关系运算符(比较运算符)
比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值 (true / false)作为比较运算的结果。
运算符 | 运算规则 | 运算符 | 运算规则 | 运算符 | 运算规则 |
---|---|---|---|---|---|
== | 相等 | < | 小于 | > | 大于 |
!= | 不等于 | >= | 大于等于 | <= | 小于等于 |
比较原则:
- 若一个是数值字符串,一个是数值,字符串会自动转换成数值进行比较。
- 若两个都是数值字符串,则比较首个数字的大小。
- 布尔值的false和true会转换成0和1。
- 两个操作数都是数值,则数值比较。
- 两个操作数都是字符串,则比较两个字符串对应的字符编码值。
在相等和不等的比较上,如果操作数是非数值,则遵循以下规则:
一个操作数是布尔值,则比较之前将其转换为数值,false 转成0,true 转成1;
一个操作数是字符串,则比较之前将其转成为数值再比较;
不需要任何转换的情况下,null 和undefined 是相等的;
一个操作数是NaN,则==返回false,!=返回true;并且NaN 和自身不等;
在全等和全不等的判断上,比如值和类型都相等,才返回true,否则返回false。
特殊值对比表:
表达式 | 值 | 表达式 | 值 | 表达式 | 值 |
---|---|---|---|---|---|
null == undefined | true | ‘NaN’ == NaN | false | 5 == NaN | false |
NaN == NaN | false | false == 0 | true | true == 1 | true |
undefined == 0 | false | null == 0 | false | true == 2 | false |
‘100’ == 100 | true | ‘100’ === 100 | false |
相等运算符 == :判断两个操作数是否相等。不同的数据类型会自动转换为相等的数据类型再做比较。
等同运算符=== :全等(值和类型),严格意义的相等,两个操作数的值和他们的类型必须完全一致。
var result = '55' == 55; // true
var result = '55' === 55; // false 值相等,类型不相等
var result = 55 === 55; // true
4.5 赋值运算符
用来把数据赋值给变量的运算符。前面我们使用的 = 其实也是一个运算符,被称之为 赋值( assignments )运算符。
运算符 | 运算规则 | 运算符 | 运算规则 | 运算符 | 运算规则 |
---|---|---|---|---|---|
= | 赋值 | *= | 乘后赋值 | **= | 幂后赋值 |
+= | 加后赋值 | /= | 除后赋值 | ||
-= | 减后赋值 | %= | 取模(余数)后赋值 |
在JavaScript中,赋值运算符是“=”,其含义就是把赋值运算符的右边的数值或表达式的值赋给赋值运算符 的左边的变量或表达式。
例如:
var t=5; // 其意义就是把数值5赋给变量t;
var k=x+y+5; // 其意义就是把表达式x+y+5最后的值赋给变量k。
var box = 100;
box += 100; // 200,+=代替box+100
4.6 三目运算符
三目运算符,又叫三元条件运算符,三元条件运算符其实就是后面将要学到的if 语句的简写形式。
根据条件在两个语句中执行其中的一个,使用符号 ?:
语法如下:条件表达式?语句1:语句2
参数说明:
-
条件表达式,结果会被作为布尔值处理
-
语句1:如果条件表达式返回true则执行
-
语句2:如果条件表达式返回false则执行
4.7 运算符的优先级
运算符 | 描述 |
---|---|
[ ] ( ) | 字段访问、数组下标、函数调用、表达式分组 |
++ – | 一元运算符 |
* / % | 乘法、除法、取模 |
+ - + | 加法、减法、字符串拼接 |
<< >> >>> | 移位 |
< <= > >= instanceof | 小于、小于等于、大于、大于等于、instanceof |
== != === !== | 等于、不等于、严格相等、非严格相等 |
& | 按位与 |
上接运算符 | 上接描述 |
---|---|
^ | 按位异或 |
| | 按位或 |
&& | 逻辑与 |
|| | 逻辑或 |
?: | 条件 |
=oP= | 赋值、运算赋值 |
. | 多重求值 |
5 JavaScript流程控制语句
任何复杂的程序逻辑都可以通过”顺序”、”条件(分支)”和”循环”三种基本的程序结构来实现。
-
顺序程序结构就是从上往下顺序执行语句;
-
程序默认就是由上到下顺序执行的 条件(分支)程序结构就是根据不同的情况执行不同的语句;
-
循环程序结构就是某些语句要循环执行多次。
5.1 条件语句
if语句即条件判断语句,一共有三种格式:
-
单分支的条件语句;
-
双分支的条件语句;
-
多分支的条件语句。
条件语句用于基于不同的条件来执行不同的动作。
5.1.1 单分支的条件语句
if(){} 语句 - 只有当指定条件为 true 时,使用该语句来执行代码:
if (/* 条件表达式 */) {
// 执行语句
}
5.1.2 双分支的条件语句
if()…else 语句 - 当条件为 true 时执行语句1,当条件为 false 时执行语句2
if (/* 条件表达式 */){
// 成立执行语句
} else {
// 否则执行语句
}
//语法
if (条件表达式){
语句1;
}else {
语句2;
}
注意: 放在if之后的括号里的返回值为boolean类型的表达式或boolean值,即这个表达式的返回值只能是 true或false。如果if表达式的值为true,则执行语句1;如果表达式的值为false,则执行语句2。
5.1.3 多分支的if条件语句
if()…else if()…else 语句 - 使用该语句来选择多个代码块之一来执行.
if (/* 条件1 */){
// 成立执行语句
} else if (/* 条件2 */){
// 成立执行语句
} else if (/* 条件3 */){
// 成立执行语句
} else {
// 最后默认执行语句
}
//语法
if (条件表达式) {
语句1;
} else if (条件表达式) {
语句2;
} ...
else{
语句n;
}
注:if语句()中的表达式会自动转换成布尔值。满足条件即执行对应语句,然后语句就结束;如果都不满足,则执行else语句块;当然else语句块可以不存在。
5.1.4 switch多条件选择语句
switch语句又称开关语句,它与多重if语句类似,前者用于等值判断,后者用于区间值和等值判断。 switch语句的作用是根据表达式的值,跳转到不同的语句。switch 语句用于基于不同的条件来执行不同 的动作。
语法:
switch (expression) {
case 常量1:
语句;
break;
case 常量2:
语句;
break;
case 常量3:
语句;
break;
…
case 常量n:
语句;
break;
default:
语句;
break;
}
首先设置表达式,随后表达式的值会与结构中的每个case 的常量表达式做比较。如果存在匹配,则与该 case 关联的代码块会被执行。
使用 break 来阻止代码自动地向下一个 case 运行。default 关键词来规定匹配不存在时做的事情,也就 是说,当没有匹配的值时,执行default下的语句。
switch 语句在比较值时使用的是全等操作符, 因此不会发生类型转换(例如,字符串’10’ 不等于数值 10)
工作原理: 首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。 如果存在匹配,则与该 case 关联的代码块会被执行。 请使用 break 来阻止代码自动地向下一个 case 运行。default 关键词来规定匹配不存在时做的事情;相当于if里的else。
注意: 1、每个case语句下的break语句一般不可以省略,break语句表示退出switch语句,如果省 略,则会继续执行下一个case语句中的代码,直到遇到break语句跳出switch语句。 2、default语 句可以出现在switch语句中任何地方,如果放在最后,其中的break语句可省略。default语句也可 省略。 3、每个case语句没有先后顺序之分,但建议按照常量表达式的值从小到大的顺序。 4、 switch语句用于等值判断,也就是说表达式的结果是个具体的值;而多重if选择结果的表达式的值 是个区间,比如大于100而小于200。
5.2 循环程序结构
循环程序的结构有三要素:循环的初始值、循环条件(循环的结束值)和循环的迭代,所谓循环的迭代就是 如何从初始值到结束值,比如是每次加1还是每次加2,诸如此类等。当然,一个循环程序还有包含一个 循环体。
5.2.1 while 语句
while循环会在指定条件为真时循环执行代码块,它是一种先判断,后运行的循环语句,也就是说,必须 满足条件了之后,方可运行循环体。用于不太确定循环次数的场合。
// 当循环条件为true时,执行循环体,
// 当循环条件为false时,结束循环。
while (循环条件) {
//循环体
}
5.2.2 do…while循环
do…while 循环是 while 循环的变体,在检查条件是否为真之前,该循环会至少执行一次do下的代码块 (循环体),然后如果条件为真的话,就会重复这个循环,否则退出该循环体。常用于至少执行一次循环 体,再判断要不要继续循环的场合。
do {
// 循环体;
} while (循环条件);
5.2.3 for语句
for 语句是应用最广泛、功能最强的一种循环语句。大部分情况下,for 循环可以代替 while 循环、do while 循环。 for 语句是一种在程序执行前就要先判断条件表达式是否为真的循环语句。假如条件表达式的结果为假, 那么它的循环语句根本不会执行。for 语句通常使用在知道循环次数的循环中。
(while和do…while一般用来解决无法确认次数的循环。for循环一般在循环次数确定的时候比较方 便。)
for 语句语法格式:
for(条件表达式1; 条件表达式2; 条件表达式3) {
语句块;
}
for 循环中 3 个条件表达式的含义如下:
表达式 | 形式 | 功能 | 举例 |
---|---|---|---|
条件表达 式 1 | 赋值语句 | 循环结构的初始部分,为循环变量赋初 值 | int i=1 |
条件表达 式 2 | 条件语句 | 循环结构的循环条件 | i>40 |
条件表达 式 3 | 迭代语句,通常使用 ++ 或 – 运算符 | 循环结构的迭代部分,通常用来修改循 环 变量的值 | i++ |
for 关键字后面括号中的 3 个条件表达式必须用“;”隔开。for 循环中的这 3 部分以及大括号中使循环体必 需的 4 个组成部分完美地结合在一起,简单明了。
for 循环语句执行的过程为:首先执行条件表达式 1 进行初始化,然后判断条件表达式 2 的值是否为 true,如果为 true,则执行循环体语句块;否则直接退出循环。最后执行表达式 3,改变循环变量的 值,至此完成一次循环。接下来进行下一次循环,直到条件表达式 2 的值为 false,才结束循环。
5.2.4 for…in语句
for…in 语句用于遍历数组或者对象的属性(通常我们使用for/in 语句循环遍历对象的属性,在数组中可 以遍历数组中的所有元素)。 for…in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。
for…in遍历数组:
// 定义一个数组
var arr = [13,21,34,42,53,63];
// 普通for循环遍历
for(var i = 0;i < arr.length;i++){
console.log(arr[i]);
}
// 使用for..in遍历数组
for(var i in arr){
console.log(arr[i]);
}
for…in遍历对象:
// 创建一个对象
var person = {
name : "jack",
age : 12,
height: 178
}
//列举对象属性名及其值
for(var pro in person){
console.log(pro+" "+person[pro])
}
在JavaScript语言中,支持循环语句的相互嵌套,即在一个循环语句中嵌套另一个循环语句,也就是说, for循环语句可以嵌套for语句,也可以嵌套while循环语句,或者do…while循环语句,其他的循环语句也 是一样的。
需要注意的是,break和continue语句用在循环嵌套中,这两条语句只对离它最近的循环语句有效。比如 如果break语句用在内层的循环语句中,则只退出内层的循环,对外层循环没有影响。
5.3 跳转语句
break:立即跳出整个循环,即循环结束,开始执行循环后面的内容(直接跳到大括号)。
continue:立即跳出当前循环,继续下一次循环(跳到i++的地方)。
注:continue 语句只能用在循环中;break能用在循环或 switch 中。
5.4 调试
-
过去调试JavaScript的方式
alert()
console.log()
-
断点调试
断点调试是指自己在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可 以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显 示错误,停下。
-
调试步骤
浏览器中按F12–>sources–>找到需要调试的文件–>在程序的某一行设置断点
-
调试中的相关操作
Watch: 监视,通过watch可以监视变量的值的变化,非常的常用。 F10: 程序单步执行,让程序一行一行的执行,这个时候,观察watch中变量的值的变化。 F8:跳到下一个断点处,如果后面没有断点了,则程序执行结束。
tips: 监视变量,不要监视表达式,因为监视了表达式,那么这个表达式也会执行。
代码调试的能力非常重要,只有学会了代码调试,才能学会自己解决bug的能力。