一、JS运算
1.1 JS运算符
1)运算符也叫操作符,通过运算符,可以对一个或多个值进行运算,并获取运算结果。
2)JS运算分为【算数运算】、【逻辑运算】、【关系运算】。
1.2 JS运算符优先级
这个表不需要记忆。如果遇到优先级不清楚的,
我们使用()改变优先级。
1.2 JS运算规则
JS运算规则:
1) 非Number类型的数据在做算数运算、关系运算时,会将这些值转换为Number在运算。(字符串相加除外)
内部原理:底层使用了Number(x)函数进行转换
非Boolean类型的数据在做逻辑运算时,会将这些值转换为Boolean在运算。
内部原理:底层使用了Boolean(x)函数进行转换
2) 任何值和NaN做运算,其结果都是NaN。
【基本规则和上述一致,有些特殊情况!!!】
1)非Number类型的数据在做算数运算、关系运算时,会将这些值转换为Number在运算。(字符串相加除外)
内部原理:底层使用了Number(x)函数进行转换
console.log(Number("12")); //12
console.log(Number("")); //0
console.log(Number(" ")); //0
console.log(Number("12ab")); //NaN
console.log(Number(true)); //1
console.log(Number(false));
console.log(Number(null));
console.log(Number(undefined));
console.log(Number(NaN));
2)非Boolean类型的数据在做布尔运算时,会将这些值转换为Boolean在运算。
内部原理:底层使用了Boolean(x)函数进行转换
console.log(Boolean("12"));
console.log(Boolean(""));
console.log(Boolean(" "));
console.log(Boolean("12ab"));
console.log(Boolean(12));
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(NaN));
1.3 JS和JAVA的区别
JS和JAVA的不同点在于:
1) JAVA中只有相似类型的数据才可以进行数学运算;
而JS中完全不同类型的数据也可以进行数学运算。
2) JAVA中逻辑运算必须是布尔类型,并且返回值也是布尔类型。
JS中逻辑运算可以是任意类型。并且运算时转为布尔类型运算,返回时返回原值。
3)JS中的除法运算不同于JAVA中的除法运算。
JAVA中的除法运算,其结果的类型取决于这个式子中最大数据类型。
JS中的除法运算,与我们日常无疑。
JAVA:12/8=1
JS: 12/8=1.5
二、算数运算
非Number类型的数据在做算数运算时,会将这些值转换为Number在运算。(字符串相加除外)
2.1 算数运算符
+运算:相加运算
1) 任意类型的数据与字符串相加,等同于拼接字符串
2)字符串隐式类型转换【利用 x+“” 来实现字符串隐式类型转换】
内部原理:任何类型的数据和字符串直接相加,都会做拼接字符串操作。
-运算:减法运算
*运算:乘法运算
/运算:除法运算
1)JS中的除法运算不同于JAVA中的除法运算。JS中的除法运算,与我们日常无疑。
JAVA:12/8=1
JS: 12/8=1.5
2)Number隐式类型转换【利用 x-0 、 x*1 、 x/1 来实现Number类型转换】
内部原理:
非Number类型的数据在做运算,会将这些值转换为Number在运算。(字符串相加除外)。
%运算:取模运算
1)取模运算就是取余数
2)其结果的正负号取决于被除数
1)示例
>>>>>> 任意类型的数据和字符串相加,就等同于拼接字符串
var s="12";
console.log(13+s);
console.log("13"+s);
console.log(null+s);
console.log(undefined+s);
console.log(NaN+s);
console.log(1+2+s);
>>>>>> 加法运算
var result =1;
console.log(result+13);
console.log(result+null);
console.log(result+undefined);
console.log(result+true);
console.log(result+NaN);
console.log(result+"12");
>>>>>> 减法、乘法、除法运算
console.log("13"/1); //13
console.log(true/1); //1
console.log(null/1); //1
console.log(undefined/1); //NaN
console.log(NaN/1); //NaN
console.log("13"*1); //13
console.log(true*1); //1
console.log(null*1); //1
console.log(undefined*1); //NaN
console.log(NaN*1); //NaN
console.log("13"-1); //12
console.log(true-1); //0
console.log(null-1); //-1
console.log(undefined-1); //NaN
console.log(NaN-1); //NaN
>>>>>> 除法运算
console.log(12/8);
console.log(6.6/1);
>>>>>> 取模运算
console.log(12%5) //2
console.log(-12%5) //-2
console.log(12%-5) //2
2)隐式类型转换
1.字符串隐式类型转换【利用 x+“” 来实现字符串隐式类型转换】
内部原理:
任意类型的数据与字符串相加,等同于字符串拼接。
我们可以利用该点,将任意类型的数据转化为字符串。
2.Number隐式类型转换【利用 x-0 、 x*1 、 x/1 来实现Number类型转换】
内部原理:
任意类型的数据在做运算,会转化为Number在做运算(与字符串相加除外)。
我们可以利用该点,将任意类型的数据转化为Number类型。
a)字符串隐式类型转换
console.log(12+"");
console.log(true+"");
console.log(null+"");
console.log(undefined+"");
console.log(NaN+"");
b)Number隐式类型转换
console.log("13"/1); //13
console.log(true/1); //1
console.log(null/1); //0
console.log(undefined/1); //NaN
console.log(NaN/1); //NaN
console.log("13"-0); //13
console.log(true-0); //1
console.log(null-0); //0
console.log(undefined-0); //NaN
console.log(NaN-0); //NaN
console.log("13"*1); //13
console.log(true*1); //1
console.log(null*1); //0
console.log(undefined*1); //NaN
console.log(NaN*1); //NaN
2.2 一元运算符
+(正号)、-(负号)
1)一元运算符,只需要一个操作数 。
2)正号不会对操作数产生影响,负号可以对操作数进行取反。
3) 通过一元运算符可以实现与字符串直接相加,而不是拼接字符串。
4) 利用 +x 来实现Number隐式类型转换
内部原理:
利用一元运算符实现Number类型隐式类型转换
任意类型的数据在做运算,会转化为Number在做运算(与字符串相加除外)。
我们可以利用该点,并结合一元运算符,将任意类型的数据转化为Number类型。
1)通过一元运算符可以实现与字符串可以直接相加,而不是拼接字符串
var s=1+ +"2" +3;
console.log(s);//6
2)Number的隐式类型转换
var s=+true;
console.log(s); //1
s=+"123";
console.log(s); //123
s=+null;
console.log(s);//1
s=+undefined;
console.log(s);//NaN
s=1+ +"2" +3;
console.log(s);//6
2.3 自增、自减运算符
a++ 、a--
先使用,后自增自减
++a 、--a
先自增自减,后使用
var s=1;
console.log(++s); // 2
var s=1;
console.log(s++); // 1
console.log(s); //2
2.4 赋值运算符
+= 、-= 、 *= 、 /+ 、 %=
a+=5 等价于 a=a+5;
var a=4;
console.log(a+=1);
var a=4;
console.log(a-=1);
var a=4;
console.log(a*=1);
var a=4;
console.log(a/=1);
var a=4;
console.log(a%=1);
三、逻辑运算
非Boolean类型的数据在做逻辑运算时,会将这些值转换为Boolean在运算。
3.1 逻辑运算符
!
注意事项:
1) 非运算,对操作数进行取反。返回布尔类型。
2) 非布尔类型的数据在做非运算,首先会转化为布尔类型,在做运算。
返回布尔类型。
3) Boolean类型隐式类型转换。
内部原理:
对任意类型取两次反,可以将其转化为布尔值。
var s="12";
s=!!s; //true
&&
注意事项:
1) 逻辑与,相同为true,不同为false。返回原值。
2) 短路运算。如果第一个值为false,则不会看第二个值。
3) 非布尔类型的数据进行与运算时,运算时转会布尔值进行运算,返回时会返回原值。
第一个值为true,返回第二个值。
第一个值为false,返回第一个值。
||
注意事项:
1) 逻辑或,只要有一个为true,就会true。否则为false。返回原值。
2) 短路运算。如果第一个值为true,则不会看第二个值。
3) 对于非布尔类型的数据进行逻辑与、逻辑或运算时,首先会将其转化为布尔值,在进行运算。并且一定会返回原值。
第一个值为true,返回第一个值。
第一个值为false,返回第二个值。
1) ! 非运算
>>>>>> 对于非布尔类型的数据,做非运算时,首先会转换为布尔运算,在运算。返回布尔类型
console.log(!"123"); // false
console.log(!""); //true
console.log(!" "); //false
console.log(!1); //false
console.log(!0); //true
console.log(!null); //true
console.log(!undefined); //true
console.log(!NaN) //true
>>>>>> Boolean类型隐式类型转换
console.log(!!"123");
console.log(!!"");
console.log(!!" ");
console.log(!!null);
2) 逻辑与 &&
a) 相同为true,不同为false。
console.log(true&&true);
console.log(true&&false);
console.log(false&&true);
console.log(false&&false);
b) 短路运算。只要第一个值为false,则不会运算第二个值。
<script>
true&&alert("123");//运行alert
false&&alert("123");//不运行alert
</script>
c) 非布尔类型的数据进行与或运算时,运算时转会布尔值进行运算,返回时会返回原值。
//第一个值为true,返回第二个值
console.log("12"&&"13"); //返回13
//第一个值为false,返回第一个值
console.log(undefined&&"13"); //返回undefined
3) 逻辑或 ||
a) 只要有一个为true,就为true。否则false。返回原值
console.log(true || true);
console.log(true || false);
console.log(false || true);
console.log(false || false);
b) 短路运算。只要第一个为true,则不会运算第二个值。
<script>
true||alert("123");//不运行alert
false||alert("abc");//运行alert
</script>
c) 非布尔类型的数据进行与或运算时,运算时转会布尔值进行运算,返回时会返回原值。
//第一个值为true,返回第一个值
console.log("12"||"13"); //返回12
//第一个值为false,返回第二个值
console.log(undefined || "13"); //返回13
四、关系运算
1.6 关系运算符
> >= == < <=
注意事项:
1) 关系运算返回布尔类型
2)关系运算规则
a)如果两个操作数不都是字符串,那么会将这些值转换为Number在运算。
b)如果两个操作数都是字符串,则会比较字符的大小。
1.能找到对应位置上的不同字符,那么就比较第一个不同字符的大小。
2.不能找到对应位置上的不同字符,那么就比较长度。
c)任何值和NaN比较,都是false。
1)关系运算返回布尔类型
console.log(3>13)
console.log(13>13)
console.log("113">13)
2)如果两个操作数不都是字符串,那么会将这些值转换为Number在运算
console.log("12">14);
console.log("" > -1);
console.log(NaN >13);
console.log(true >0);
3)如果两个操作数都是字符串,则会比较从左到右第一个不同字符的大小。
console.log("123">"12"); //true
console.log("hello">"hell") //true
console.log("a">"b") //false
console.log("abcs">"b") //false
1.7 相等运算符
使用相等运算符比较基本数据类型时,比较的就是值。
使用相等运算符比较引用数据类型时,比较的是引用对象的内存地址。
==
使用==比较两个值时,如果值的类型不同,
则会自动类型转换。转换为相同的类型后,在做比较。
!=
使用!=比较两个值时,如果值的类型不同,
则会自动类型转换。转换为相同的类型后,在做比较。
【切记:自动类型转换后的数据类型是什么,视情况而定,所以==、!= 情况比较多,需要测试后用】
===
全等。用来判断两个值是否全等。它和相等类似,不同的是它不会做自动类型转换。
如果两个值的类型不同,直接返回false。
!==
不全等。用来判断两个值是否不全等。它和得等类似。不同的是它不会做自动类型转换。
如果两个值的类型不同,直接返回true。
1)==、!=
a) 如果操作数的类型不同,则会自动转换为相同类型,在做比较。
console.log(123 ==123); //true
console.log("123"==123); //true
console.log("1"==true); //true
console.log("1"=="true"); //false
console.log(null == undefined); //true
console.log("null" == null); //false
b) 自动转换后类型是情况而定。所以需要测试后使用
console.log("1"==true);
console.log("1"=="true");
console.log("null"==NaN);
console.log(null == undefined);
console.log("null" == null);
2)===、!==
a) 如果操作数的类型不同,则不会自动类型转换,直接返回结果。
console.log("1"===true);
console.log("1"==="true");
3)总结
a)==、!= 与 ===、!=== 的区别?
1)==、!=,如果操作数的类型不同时,则会自动转换为相同的类型在做运算。
2)===、!===,如果操作数的类型不同,则不会自动转换,直接返回结果。
b)推荐使用===、!===【我的看法】
==、!=
对于不同类型的数据会自动转换然后计算。只与转换后的类型是什么,
视情况而定,所以比较乱。所以在使用时要进行测试。
===、!==
和java中的类似。