表达式和运算符
运算符的分类
1、算数操作符
2、逻辑操作符
3、赋值操作符
4、比较操作符
5、三元操作符
什么是表达式?
将同类型的数据(如常量、变量、函数等) , 用运算符号按一定的规则连接起来的、有意义的式子称为表达式
每种表达式有不同的运算符
表达式种类
算数表达式
算数运算符
加 +
减 -
**乘 ***
除 /
取余 %
加减的符号和数学一致,乘法是*号,除法是/号
优先级与数学中优先级相同 先乘除后加减
js
console.log(3+3); //6
console.log(3-3); //减
console.log(2*4); //乘
console.log(10/2); //除
默认情况下,乘除法的优先级要高于加法和减法;必要时可以使用圆括号来改变运算的顺序
js
console.log(1 + 2 * 3);//7
console.log((1 + 2) * 3);//9
console.log(1 + 2 / 4);//1.5
console.log(((1 + 2) * 3 + 4) / 2);//6.5
字符串拼接
加号有“加法”和“连字符”两种作用
如果加号两边的操作数都是数字,则为“加法”,否则为连字符
js
let a = "tian";
let b = "黛玉"
// +号两边任意一边出现字符串,那么为拼接功能,最终得到字符串
console.log("a" + "b");//字符串ab
console.log(a + "b");//tianb
console.log("10" + 10);//1010
console.log(20 + "20");//2020
console.log(30 + 10 + "3");//403
console.log("3" + 30 + 10 );//33010
console.log("3" + (30 + 10) );//340
应用
js
//比如经过一系列运算得来的变量
let c = 300;
xxx.style.width = c + "px";
加法的特殊性
- 当一侧为
String
类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。 - 当一侧为
Number
类型,另一侧为原始类型,则将原始类型转换为Number
类型。 - 当一侧为
Number
类型,另一侧为引用类型,将引用类型和Number
类型转换成字符串后拼接。 - 以上 3 点,优先级从高到低,即
3+'abc'
会应用规则 1,而3+true
会应用规则2。
js
console.log(true + 1); // 布尔值与数字运算的时候会 首先把 true 转换为数字 1, 然后执行 1 + 1
console.log(null + 1); //首先把 null 转换为数字 0, 然后执行 0 + 1
js
console.log(true + false); //1
console.log(true + true); //1
console.log(false + 3); //3
console.log(3 + undefined); //NaN
//无论哪种运算,只要出现了undefined参与运算,结果都是NaN。
js
console.log( [] + 0);
console.log( [1] + 0);
console.log( [1,2] + 0);
//这样的加法没有什么意义,了解一下即可
%:取余
取余运算也叫作“求模运算”,用百分号%表示
a % b 表示求a除以b的余数,它不关心整数部分,只关心余数
js
console.log(8 % 5); //3
console.log(24 % 5); //4 模 去余数
console.log(31.5 % 5); //1.5 小数不参与模运算
console.log(5 % 5); //0
console.log(3 % 9); //3
console.log(2 % 20); //2
除了加法
我们在使用 - * / 如果两边运算不是数字,转换数字去运算(隐式类型转换)
会先将非
Number
类型转换为Number
类型。
js
console.log("100" - 10); //90
js
console.log("tian" - "黛玉");//NaN(not a number)
// NaN不是一个数字,但它是一个数字类型
// 一般在做一些非法的运算会出现NaN
js
console.log("3" - 2); //1
console.log("3" - "2"); //1
console.log("3" - "2"); //1
console.log("4" * "2"); //8
console.log("4" * "2"); //8
console.log("4" / "2"); //2
console.log("4" % "2"); //0
// 不纯的字符串和undefined是不能帮你进行隐式转换的,结果都是NaN, 没办法计算
console.log(3 * undefined); //NaN //数学运算中,undefined不能进行隐式转换
console.log(3 * "2天"); //NaN
console.log("tian" % 2); //NaN
有关IEEE754
在JavaScript中有些小数运算产生“丢失精度”问题
js
0.1 + 0.2; //.30000000000000004
JavaScript使用了IEEE754二进制浮点数算术标准,这会使个别小数运算产生丢失精度的问题
解决办法
在进行小数运算时,要调用数字的toFixed()方法,保留指定的小数位数.
js
console.log( (0.1 + 0.2).toFixed(2) ); //保留两位 可以使用Number转一下
console.log( Number((0.1 + 0.2).toFixed(2)) );
赋值表达式
赋值运算符
简单赋值: =
复合赋值: +=、-=、*=、/=、%=
自增 ++
自减 --
JS中,-表示赋值,==判断是否相等(不判断类型),===判断是否全等
js
// 在定义变量的时候 只能使用 = 赋值 赋值运算符会将等号右边的数值,赋予等号左边的变量
let a = 10;
//赋值元素也输出值
console.log(a = 4); //4 变量a既能输出4 也能给a赋值 这个赋值语句有返回值 返回值就是等号右边的
//这就意味着可以连续使用赋值运算符
let a, b, c;
a = b = c = 15;
console.log(a); //15
console.log(b); //15
console.log(c); //15
//公司一般不允许使用 只出现在面试题中
//在重新赋值的有很多的赋值符号可以选择 快捷赋值在原数值基础上进一步运算
a += 5; //a = a + 5
js
a += "5"; //105
js
a -= 3; //a = a - 3
a *= 2; //a = a * 2
a /= 2; //a = a / 2
a %= 2; //a = a % 2
console.log(a);
关于模的小案例(三个颜色循环切换)
html
<style>
#btn {
width: 100px;
height: 30px;
border: 1px solid green;
line-height: 30px;
text-align: center;
font-size: 16px;
font-weight: bold;
cursor: pointer;
user-select: none;
transition: 0.8s;
}
#btn.pink {
background-color: pink;
}
#btn.green {
background-color: green;
}
#btn.purple {
background-color: purple;
}
</style>
</head>
<body>
<div id="btn">按钮</div>
<script>
//获取
let oBtn = document.getElementById("btn");
//先存储所有名字
let colorArr = ["pink", "green", "purple"];
//最开始使用哪一个
let index = 0;
oBtn.onclick = function () {
this.className = colorArr[index];
index = (index + 1) % 3;
};
</script>
前置自增和后置自增
前置 ++a 与 后置a++都是对a进行递增的操作,
两者使变量最终的结果一样
但是 过程(参与了其他表达式) 不一样
前置 : 先 赋值 再 +1
后置 : 先 +1 再赋值
js
let num1 = 10;
num1++;
//++num1;效果一样 类似于a=a+1 a+=1
console.log(num1);
自带类型转换
js
let num1 = "5";
num1 ++; //6
num1 +=1; //51
console.log(num1);
js
let num1 = "5";
num1 ++;//51
console.log(num1);
前置++ 和 后置++的区别
参与了其他表达式
js
let num1 = 10;
let num2 = num1++; // let num2 = num1; num1 = num1+1;
console.log(num1);//11
console.log(num2);//10
js
let num1 = 10;
let num2 = ++num1; // num1 = num1 + 1; let num2 = num1;
console.log(num1);//11
console.log(num2);//11
小练习
js
let num1 = 10;
let num2 = num1++ + 1;
console.log(num2); //11
num2 = ++num1 + 1;
console.log(num2); //13
js
let num1 = 6
let num2 = num1++ + ++num1 + 3 + num1++;
console.log(num1); //9
console.log(num2); //25
JS中的数学运算符就这么几个,如果我想算n次幂怎么办?像这样 4的三次方
那我们就先学一个API,
js
Math.pow(4,3); //64
这是一个新的API,记住就行了,后面的课程将会告诉你,Math是一个内置对象,pow是它的一个方法。
Math就是数学,pow就是power乘方。
开根号
js
Math.sqrt(81); //9
例子:
js
let a = Math.pow(3,2 + Math.pow(3,4));
console.log(a);
关系表达式
关系运算符
> 、<、>=、<=、==、===、!=、! ==
大于 > , 小于 < 两个符号和数学相同
大于等于运算符是 >=,小于等于运算符是 <=
== 相等,只比较值是否相等
=== 全等,比较值的同时比较数据类型是否相等
!= 不相等,比较值是否不相等
!== 不全等,比较值的同时比较数据类型是否不相
返回值: boolean型
js
let a = 10;
let b = 20;
console.log( 8 >= 8 ) //true >=表示或者 8>8或者8=8
console.log( 8 <= 8 ) //true
console.log(a > b); //-->只会返回布尔值
console.log(a < b);
console.log(a >= b);
console.log(a <= b);
console.log(a== b );//等于
console.log(a!= b );//不等于
如果想比较两个值是否相等,此时应该使用==运算符
JavaScript中等号=表示赋值,而并不是相等。判断相等应该使用==运算符
js
console.log(3 == 3 ); //true
console.log( 3 === 3 ); //true
console.log( 3 = 3); //错误语句
等于和全等的区别
两个等号 == 运算符不比较值的类型,它会进行隐式转换后比较值是否相等
三个等号 === 运算符,不仅比较值是否相同,也比较类型是否相同
js
let a = "10";
let b = 10;
// 等于 只要求值一样,数据类型不一样也没事
console.log( a == b ); //true
//全等于 要求数据类型和值都一样
console.log( a === b ) //false
- 没有特殊要求,任何时候都使用全等
js
console.log(1 == true); // true
console.log(1 === true); // false
console.log("" == 0); // true
console.log(0 == false); // true
console.log(0 === false); // false
console.log(0 == undefined); //true
console.log(0 === undefined); //false
console.log(null == undefined); // true
console.log(null == undefined); //false
//基础数据类型的NaN 连自己都不相等
console.log(NaN == NaN);//false
console.log(NaN === NaN);//false
复杂数据类型在进行比较时,只比较地址是否一致,不进行值比较
js
var a = {name:"tian"}
var b = {name:"tian"}
var c = ["tian","黛玉"];
var d =["tian","黛玉"];
console.log(a === b);//false
console.log(c === d);//false
js
let a = {name:"tian"};
let b = a;
console.log(a === b);//true
不相等和不全等
!=表示不相等,!==表示不全等
js
5 != 6; // true
5 !== 6; //true
5 != '5'; //false
5 !== '5'; //true
连续判断(连比)
js 中没有数学中的连不等式,会将连不等式分步处理
js
let num = 8;
console.log( 3 < num < 6 ) // true
//执行过程 :
3 < num < 6
3 < num ===> true
true < 6 ===> 1 < 6 ===> true
字符串的比较
字符串在进行比较时,强制将字符串的 第一个字符 转换为 ASCII码 , 进行比较
常用 ASCII 码:
- 0-9 48-57
- a-z 97-122
- A-Z 65-90
js
console.log( "ab" < "ba" ) // true
// 比较 a 和 b 的ASCII码, 即 97 < 98 为 true
js
console.log( "30" > "4" ) //false
// 比较 3 和 4 的ASCII码,即 3 > 4 为 false
逻辑表达式
逻辑运算符
&& 与 并且
遇假则停取值 (只要有一个条件不成立,返回false )
|| 或 或者
遇真则停取值
! 非 取反
一定会得到布尔值
**&&两边都为真 才是真 口诀:都真才真 否则都是假 **
例子
css
命题1: "地球是个圆的" 真的
命题2: "tian超帅" 真的
命题1 且 命题2 真
css
命题1:“1+1=3” 假的
命题2:“地球是方的” 假的
命题1 且 命题2 假的
js
//布尔值的逻辑运算
let x = true && false;
console.log(x);//false
js
let y = false && false;
console.log(y);//false
js
let z = true && true;
console.log(z);//true
js
let t = false && true;
console.log(t); //false
||两边都假 否则都真
例子
css
命题1: 1 + 1 = 2 真的
命题2:“你很帅” 存在歧义
命题1 或者 命题2 总结果是真
js
let x = true || true;
console.log(x);//true
js
let y = false || false;
console.log(y);//false
js
let z = true || false;
console.log(z); //true
js
let t = false || true;
console.log(t) //true
!取反
!取反运算符是一个感叹号,用于将布尔值变为相反值,即true变成false,false变成true。
对于非布尔值,取反运算符会将其转为布尔值。
如果对一个值连续做两次取反运算,等于将其转为对应的布尔值,与Boolean函数的作用相同
js
let x = !true;
let y = !false;
console.log(x);//false
console.log(y);//true
js
let x = !!false;
console.log(x);//false
js
!0 //true
!undefined //true
!'' //true
! ' imooc' //true
逻辑运算会按照两个数据对应的布尔值去运算
JavaScript 每个数据 在做真假判断的时候都有自身对应的布尔值
哪些数据转换成布尔值的时候是ture?
哪些数据转换成布尔值的时候是false?
false
0
undefined
null
""
NaN
js
console.log(Boolean("0") );//true
console.log(Boolean(" ") );//true 空字符串中带空格也为true
console.log(Boolean("false") );//true
console.log(Boolean("null") );//true
console.log(Boolean(2 - 2) );//false
说明:两个操作数的情况,在有一个操作数不是布尔值的情况,逻辑与操作就不一定返回布尔值,此时它遵循下列规则:
- 1、如果第一个操作数隐式类型转换后为true ,则返回第二个操作数。
- 2、如果第一个操作数隐式类型转换后为false ,则返回第一个操作数。
逻辑与短路运算
计算运算且运算的时候,
比如a && b,a如果就是一个false,
那么就不会管b是什么,直接输出false就行了,等于说直接输出a。
js
//从布尔值的结果推断程序要不要往后走 后面对程序真假有影响就会往下走
let x = 1 && 2;
console.log(x);//2
js
let x = 2 && 1;
console.log(x);//1
js
console.log(20 * "abc" && num1);//NaN
js
//后面结果已经没有
let x = null && 2;
console.log(x);
逻辑或的短路运算
|| 逻辑或的短路也是类似的,a||b
计算机发现a是真,那么返回a;如果a是假,返回b
js
let x = "10" || 5; //前面真,扔前面
console.log(x); //10
js
let x = 5 || undefined
console.log(x);//5
js
let x =undefined || 5 //前面假,扔后面
console.log(x);//5
js
let x = undefined ||null;
console.log(x); //null 前面假,扔后面
js
3 && 6 //6
undefined && 15 //undefined
15 && undefined //undefined
nul1 && 2 //null
''&& 16 //""
NaN && undefined //"NaN"
使用逻辑运算符控制流程
js
let a = 10;
a || alert(1);//遇真停止取值
js
let a = 1;
function yun(){
alert(1);
}
a && yun();//前面为真 运行后面的
js
let yun = undefined;
yun && yun();
//如果没值不报错 有值返回函数执行
逻辑运算顺序
逻辑运算的优先级是:非→与→或
js
!true || false // false
3 && 4 || 5 && 6 //4 //先运算逻辑与 再运算逻辑或
2 && 1 || 5 ;
5 && null || 0 && 9//0
综合表达式
运算优先级
参考资料 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
运算顺序:非运算→数学运算→关系运算→逻辑运算
js
1 + 2 * 4 - 2 //7
1 + 2 *(4 - 2) //5
5 < 3 + 3 //true 3+3是数学运算 <是关系运算
3 > 2 && 8 > 3 + 4 // true 3+4先运算
3 > 2 && 8 > 3 + 5 // false 3+5先运算
!13 < 5 - 3 //true !13先运算 转为false --> false < 2
!13 < 5 - 5 //true !13先运算 转为false --> false < 0
验证变量a是否介于5到12之间
js
5 <= a <= 12 // 错误
a >= 5 && a <= 12 //正确
闰年判断
公历闰年的简单计算方法(符合以下条件之一即可)
1.能被4整除且不能被100整除。
2.能被100整除也能被400整除。
js
1892年 // 是
1896年 // 是
1900年 // 不是
1904年 // 是
1992年 // 是
1996年 // 是
2000年 // 是
2004年 // 是
//闰年每四年一闰 逢00结尾还必须能被400整除
js
//要让用户输入一个年份
let year = Number(prompt("请输入年份"));
// 根据两个条件进行判断
// ① 能被4整除,且不能被100整除
// ② 能被100整除,且能被400整除
alert( year % 4 == 0 && year % 100 != 0 || year % 100 == 0 && year % 400 == 0);
特殊情况 :
js
console.log( 2 || 10 && alert(1) ) // 2
以上代码不会弹窗 , 虽然 && 的优先级大于 || , 但计算机的解析原理是惰性的,从优先级最低的符号看有没有必要执行, 此处 || 运算符后面的代码不管是什么 , 最后返回的值都是 2 ,所以 || 右边的内容不被执行
总结
1.表达式有哪几种?每种表达式分别有哪些运算符?
算数运算符
加 + 减 - 乘 * 除 / 取余%
关系运算符
大于 > 小于< 大于或等于>= 小于或等于<= 等于 == 不等于!= 全等于=== 不全等于!==
逻辑运算符
非! 与&& 或||
赋值运算符
赋值 = 快捷赋值 += -= *= /= %= 自增运算 ++ 自减运算--
2.每种表达式中运算顺序是什么?综合运算顺序是什么?
算数运算符 先算乘除取余 再算加减 如果需要改变运算顺序 写圆括号
关系运算符 运算顺序相同
逻辑运算符 运算顺序 非! > 与&& > 或||
赋值运算符 先自增和自减 因为是单目运算 然后进行其他普通赋值运算
3.难点
什么是短路计算? 3 &&13的结果是多少? 3 ||13呢?
a++ 和 ++a的区别?
js
let a = 3;
let b = 4;
alert(a++ + b++ + ++a + ++b) //18
//先执行到a++操作 当执行到++a时 a的值已经变成了4 而++a先自增,再进行计算 所以a变成5