一.运算符
运算符(Operators,也翻译为操作符),是发起运算的最简单形式。
运算符的分类见仁见智,我们的课程对运算符进行如下分类:
数学运算符(Arithmetic operators)
比较运算符(Comparison operators)
逻辑运算符(Logical operators)
赋值运算符(Assignment operators)
按位运算符 (Bitwise operators)
条件 (三元) 运算符(Conditional operator)
1. 数学运算符
加+ 减 - 乘 * 除 / 取余数 % 括号 ()
下面的结果都是3:
console.log(1+2);
console.log(8-5);
console.log(1.5*2);
console.log(12/4);
console.log(13%5);//13÷5=2……3 得几不重要,要的是余数
取余数这个运算,实际上也是除,要的是余数:
//取余数
console.log(12%3);//0
console.log(121%11);//0
console.log(5%8);//5
console.log(8%5);//3
console.log(5%5);//0
// 测试
console.log(1%0)
默认的计算顺序,先乘除,后加减。乘除取余是平级,先遇见谁,就算谁。
console.log(1+2*3);//7
console.log(1+2*3%3);//1
console.log(1+2%3*3);//7
我们可以用小括号来改变计算先后顺序,注意没有中括号和大括号,一律用小括号。
vara=4*(3+(1+2)*3);
console.log(a);
1.1. 隐式转换
所有带有字符串的运算都会尽可能的转为数字进行计算,加号比较特殊。(加好在字符串中有拼接的意思)
数学运算符的正统,是number和number的数学运算,结果是number。出于面试的考虑,有一些奇奇怪怪的数学运算.
发生隐式转换
数学运算中,只有纯字符串、布尔值、null能够帮你进行隐式转换
//隐式转换:就是没有写parseInt()、parseFloat()自己帮你转格式
console.log(3*"8");//24
console.log("3"*"8");//24
console.log("48"/"2");//24
console.log("24"%55);//24
console.log(3*null);//0
//隐式转换的时候null将被转为0
console.log(3*false);//0
//隐式转换的时候false将被转为0
console.log(3*true);//3
//隐式转换的时候true将被转为1
不能隐式转换
不纯的字符串和undefined是不能帮你进行隐式转换的,结果都是NaN, 没办法计算
console.log(3*"8天");//NaN
//数学运算中,不纯的字符串没法隐式转换
console.log(3*undefined);//NaN
//数学运算中,undefined不能进行隐式转换
加法的特殊性
加法比较特殊,因为+同时是加法和连字符的符号,所以加法在面对字符串的时候没有隐式转换,就是字符串拼接
数学运算,字符串拼接
任何数据类型加字符串都等于字符串
//加法对于字符串没有隐式转换
console.log(3+"8");//38
console.log(3+undefined);//NaN
console.log(3+null);//3
console.log(3+false);//3
console.log(3+true);//4
总结:
无论哪种运算,只要出现了undefined参与运算,结果都是NaN。
然后纯数字字符串("4")、false、true、null都能进行隐式转换。
加号比较特殊,面对纯数字字符串("4")没有隐式转换的
1.2 特殊数值的计算,
特殊的数字运算,就是NaN、Infinity参与的运算,很多公司在考,考你对面试的重视程度,因为这个知识实战中一辈子用不到
举几个例子
Infinity+1000//Infinity
Infinity-1000//Infinity
Infinity/1000//Infinity
Infinity*1000//Infinity
Infinity%1000// NaN
Infinity-Infinity//NaN
Infinity/Infinity//NaN
Infinity*Infinity//Infinity
0/0//NaN
6/0//Infinity
NaN/8//NaN
1.3 补充几个数学API
JS中的数学运算符就这么几个,如果我想算n次幂怎么办?
像这样 43
那我们就先学一个API,
一个数的n次幂
Math.pow(4,3);//
这是一个新的API,记住就行了,后面的课程将会告诉你,Math是一个内置对象,pow是它的一个方法。
Math就是数学,pow就是power乘方。
开根号
Math.sqrt(81);
例子:
vara=Math.pow(3,2+Math.pow(3,4));
console.log(a);
2.比较(关系)运算符
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于 判断两个值是否相等
!= 不等于判断两个值是否不相等
=== 全等于 判断两个值是否严格相等
!== 不全等 判断两个值是否严格不相等
正统的数字比较
关系运算符的正统,number和number进行数学运算,得到的答案boolean。
console.log(8>6);// true
console.log(7<5);// false
console.log(8>=7);//true
console.log(8>=8);//true
console.log(5<=8);//true
console.log(5<=5);//true
console.log(5<=4);//false
实例中结果是布尔类型,boolean类型只有两个值,就是true和false。表示真、假。
== 我们叫做“相等判断”,它会帮你进行一个隐式转换,尽可能的得到true的答案:
//==表示相等,会帮你进行隐式转换
console.log(6==8);//false
console.log(6==6);//true
console.log(6=="6");//true
console.log("6"==6);//true
===我们叫做“全等判断”,不仅仅比较数值是否相等,还比较类型是否相等,没有隐式转换
//===表示全等,不仅仅比较数值是否相等,还比较类型是否相等
console.log(6===6);//true
console.log(6==="6");//false
console.log("6"===6);//false
!= 是==的反面,如果==运算是true,那么!=就是false
!==是===的反面,如果===运算是true,那么!==就是false
console.log(6!="6");//false ,
//脑子要反着想一下,6=="6"结果是true,所以就是false
console.log(6!=="6");//true ,
//脑子要反着想一下,6==="6"结果是false,所以就是true
正统的运算讲完了,number和number进行关系运算,结果是boolean。
string 和 string 也能够进行关系运算,
比较的就是字符编码即unicode编码值顺序。
字符编码顺序,就是数字、大写字母、小写字母
"a"<"b"//true
"A"<"B"//true
"A"<"a"// true ,大写字母在字符集里面是在小写字母前面
"1"<"A"//true ,数字在字母前端
"blank"<"blue"//true 因为一位一位比,直到比出大小
"23"<"3"//true 因为是string和string比,比的是字符编码顺序
与数字进行关系运算时,纯数字字符串被转为数字,null转换为0,true转换转为1, false转换为0
null不能进行和0的相等判定
null<0.00001//true
null>-0.0001//true
null==0//false 具体原因,我们后面讲解Object的时候介绍
false==0//true
true==1//true
undefined==0;//false
"a"<3// false
"a">3// false 因为"a"会被转为NaN
"23"<3//false 因为"23"会被转为23
NaN不等于自己,不全等于自己
NaN==NaN//false
NaN===NaN//false
NaN!=NaN//true
NaN!==NaN//true
其他类型的比较
null==undefined//true
null===undefined//false
需要注意的是,我们已经了解了一些不正统的运算,所以千万不要连续使用关系运算符!!
比如我们想验证3大于2,2大于1:
3>2>1// false
原理:
(3>2) >1
= true > 1 因为true会被当做1来与1进行比较
= false
也就是说,不能连续使用关系运算符!!因为一旦连续使用了,实际上还是从左至右计算,所以就有上一步的boolean参与了下一步的运算。
总结:
如果比较的两个操作数都是数值,那么就进行数值比较
如果比较的两个操作数都是字符串,那么就会比较字符串编码值
如果有一个操作数是数字,另一个操作数就会被转换为数值进行比较
测试:
console.log(1<2<3);
3. 逻辑运算符
逻辑运算符就三个
且 或 非
&& 逻辑与运算 (且)
|| 逻辑或运算 (或)
! 逻辑非运算 (非)
正统的来说,参与逻辑运算的Boolean和Boolean,得到的结果也是Boolean值
值按照真值表来定
3.1 && 逻辑与的真值表
a && b
ab结果
真真真
真假假
假真假
假假假
都真才真,有假就假
例子
命题1: "地球是个圆的" 真的
命题2: "胡歌演技超棒" 真的
命题1 且 命题2 真
命题1:“1+1=3” 假的
命题2:“地球是方的” 假的
命题1 且 命题2 假的
//逻辑与运算符
console.log(true&&true);//ture
console.log(true&&false);//false
console.log(false&&true);//false
console.log(false&&false);//false
3.2 || 逻辑或,或者的意思
a || b
ab结果
真真真
真假真
假真真
假假假
有真就真,都假才加
命题1: 1 + 1 = 2 真的
命题2:“你很帅” 存在歧义
命题1 或者 命题2 总结果是真
//逻辑或运算符
console.log(true||true);//ture
console.log(true||false);//ture
console.log(false||true);//ture
console.log(false||false);//false
3.3 ! 就是'逻辑非', 就是相反的意思
//逻辑非运算符
console.log(!true);//false
console.log(!false);//true
console.log(!!!!!!!!!false);//ture
3.4 逻辑运算符的顺序
顺序: 非,与 或
true||false&&!true||false
解式 = true || false && false || false
= true || false || false
= true || false
= true
3.5 短路语法
逻辑运算符最最有意思的事情,就是所谓的“短路语法”。
逻辑与的短路运算
计算运算且运算的时候,比如a && b,a如果就是一个false,那么就不会管b是什么,直接输出false就行了,等于说直接输出a。
也就是说,本质上计算机进行a&&b运算的时候,不是在进行逻辑分析,而是在根据逻辑判断返回哪一个值
—— 短路语法。 要么a被短路,要么b被短路。
负性就是在隐式转换成布尔值的时候,转换为false 叫负性
false null 0 NaN "" undefined
正性的:除了上面的,全是正性的。也就是隐式转换为布尔值的时候,全部非true
false&&8//false
//因为计算机发现,且运算a已经是false了,直接输出false
null&&8//null
//因为计算机发现,且运算a已经是false性的了,直接扔出来null
true&&13//13
//因为计算机发现,且运算a是true,所以总结果就是看b,直接扔出b
12&&13//13
//因为计算机发现,12当做true,所以总结果看b,直接扔出b
13&&12//12
//因为计算机发现,13当做true,所以总结果看b,直接扔出b
undefined&&哈哈//undefined
//不报错,因为a已经是负性的了,所以直接扔出a,哈哈不管
哈哈&&undefined//报错
true&&NaN//NaN 扔后面
逻辑或的短路运算
|| 逻辑或的短路也是类似的,a||b
计算机发现a是真,那么返回a;如果a是假,返回b
0||18//18 前面假,扔后面
18||0//18 前面真,扔前面
undefined||NaN//NaN 前面假,扔后面
NaN||undefined//undefined 前面假,扔后面
例子:
88 || 99 && 66 || 55
解式:
= 88 || 66 || 55
= 88 ||55
= 88
undefined && ("3" != 3) || NaN && null
解式
= undefined && false || NaN && null
= undefined || NaN
= NaN
总结一下短路语法:
a&&b, 计算机要么执行a要么执行b。a真执行b,a假执行a;
a||b, 计算机要么执行a要么执行b。a真执行a,a假执行b。
测试:
console.log("0 || 1 = "+(0||1));
console.log("1 || 2 = "+(1||2));
console.log("0 && 1 = "+(0&&1));
console.log("1 && 2 = "+(1&&2));
例子:根据年龄判断用户是否成年
//第1步,用户输入一个年龄
varage=parseInt(prompt("请输入你的年龄"));
//第2步输出
// (age >= 18) && alert("你已经成年了!!");
// (age < 18) && alert("你没有成年啊!!!");
// 也可以这么写,程序是对的:
(age<18)||alert("你已经成年了");
(age>=18)||alert("你没有成年啊!!");
4. 赋值运算
= 赋值
+= 简便写法
-= 简便写法
*= 简便写法
/= 简便写法
%= 简便写法
++
--
赋值运算的参与者,一定是变量。赋值运算是先计算右边,然后将最终的值赋值给左边
vara=2;
a+=2;//这行语句等价于a = a + 2;
console.log(a);//4
vara=10;
a+=10+1;
console.log(a);// 21
varb=6;
b/=3;//等价于b = b / 3
console.log(b);//2
varc=100;
c%=10;//等价于c = c % 10;
console.log(c);//0
vara="我";
a+="爱";
a+="你";
console.log(a);
4.1 ++ 自增运算符
vare=10;
e++;//等价于e=e+1
console.log(e);//11
++可以与输出语句写在一起,++写在变量前和写在变量后不是一个意思
a++ : 先用a的原值参与运算,然后a自己加1;
++a :先给a自己加1,然后用a的新值参与运算
varf=10;
console.log(f++);//10 ,先引用原值,然后加1
等价于
//等价于
varf=10;
console.log(f);//先输出f
f++;//然后f加1
varg=10;
console.log(++g);//11 , 这次是先加1,然后输
++ 的特殊用法
vara=8;
console.log(4+a++);//12 , 先使用原来的a的值,就是4+8,输出12.然后a加1
console.log(a);//9
vari=9;
console.log(++i%5);//0 , 先把i加1,然后使用i,10%5=0
console.log(i);//10
vara=10;
varb=++a-1+a++;
console.log(b+" "+a);
// 赋值的顺序 在自右向左 计算的顺序, 自左向右
4.2 -- 自减运算符
与自增运算符相同
练习:
vara=(10*3-4/2+1)%2;
varb=3;
b%=a+3;
console.log(a++);// 1
console.log(--b);// 2
vara=123;
varb=234;
// 请交换a,b的值
// 普通写法.
// 利用中间变量
varc=a;
a=b;
b=c;
// 方法二
a=a+b;
b=a-b;
a=a-b;
5. 运算符的计算顺序
贴身的( ++ -- !) →→→ 数学 →→→ 比较 →→→ 逻辑 →→→ 赋值
vara=3<8&&8<14;//true
解式
= 3 < 8 && 8 < 14;
= true && true
= ture
vara=1+2<3+3&&3+4<2*7;
解式
= 3 < 6 && 7 < 14
= true && true
true
vara=false+true&&13;
解式
= 1 && 13
= 13
vara=15;
false+a+++true>8&&13||6
解式
= false + 15 + true > 8 && 13 || 6
= 16 >8 && 13 || 6
= 13 || 16
=13
注意:
像++ -- ! 这种只需要一个操作符参与的叫做 一元运算符, 同时一元操作符还包括+ -
两个操作数参与的叫二元运算符
三个操作数参与的叫做三元运算符
特殊一元操作符 + -
对于数值+没有变化,- 会将数值变为负数,如果数值为负值,那么结果就是正数
vara=1;
console.log(+a);
console.log(-a);
如果是非数字,就会像Number一样将其他类型转换为数值类型
console.log(+true);//1
console.log(+false);//0
console.log(+undefined);//NaN
console.log(+null);//0
console.log(+"33");//33
console.log(+"aa");//NaN
测试:
varn1=10,n2=20;
varn=n1++;
console.log("n = "+n);// 10
console.log("n1 = "+n1);// 11
n=++n1;
console.log("n = "+n);// 12
console.log("n1 = "+n1);// 12
n=n2--;
console.log("n = "+n);// 20
console.log("n2 = "+n2);//19
n=--n2;
console.log("n = "+n);// 18
console.log("n2 = "+n2);// 18