凡是运算,必有返回值即运算结果
运算符简介
运算符:也叫操作符,是一种符号。通过运算符可以对一个或多个值进行运算,并获取运算结果。
表达式:由数字、运算符、变量的组合 (组成的式子),表达式最终都会有一个运算结果,我们将这个结果称为表达式的返回值。
-
比如:
+
、*
、/
、(
都是运算符,而(3+5)/2
则是表达式。 -
比如:typeof 就是运算符,可以来获得一个值的类型。它会将该值的类型以字符串的形式返回,返回值可以是 number、string、boolean、undefined、object
算数运算符
算术运算符:用于执行两个变量或值的算术运算。
运算符 | 描述 |
---|---|
+ | 加、字符串连接 |
- | 减 |
* | 乘 |
/ | 除 |
% | 获取余数(取余、取模) |
取模运算符的用法
- 判断两个数是否可以整除
- 取模运算时,结果正负只和被除数有关,上边是被除数
- 使用 % 方式,来换行显示数据
浮点数运算的不精确
- 浮点数值的最高精度是 17 位小数,超出则四舍五入
- 在进行算术计算时,转换为二进制可能会丢失精度,导致计算不够准确
- 因此,不要直接判断两个浮点数是否相等
var num = 0.111000333555666111;
document.write(num); // 0.11100033355566612 只有17位,多出的四舍五入
document.write(0.1 + 0.2); // 运算结果不是 0.3,而是 0.30000000000000004
document.write(0.07 * 100); // 运算结果不是 7,而是 7.000000000000001
自动类型转换
- 算数运算符
+
,数据类型会自动向高精度转换 - 算数运算符
+
,任何类型值和字符串相加,会隐式调用String()
函数,可将任意值转换为字符串 - 除了
+
的算数运算符,会隐式调用Number()
函数,将任意值转换为Number
,然后再进行运算
一元运算符
一元运算符,只需要一个操作数 +
-
- 正号不会对数字产生任何影响。比如说,
2
和+2
是一样的 - 负号可以对数字进行取反
自动类型转换
一元运算符,会隐式调用Number()
函数,将任意值转换为Number
,然后再进行运算
小技巧:可以对其他数据类型使用+,将其转换为Number类型
var a = true;
a = +a; // 注意这行代码的一元运算符操作
console.log('a:' + a); // a:1
console.log(typeof a); // number
var b = '18';
b = +b; // 注意这行代码的一元运算符操作
console.log('b:' + b); // b:18
console.log(typeof b); // number
自增/自减运算符
注意++a与a++的区别
var a = 1;
document.write(++a); // 2 a先加1,然后返回a
var b = 1;
document.write(b++); // 1 先返回b,然后b加1
var $c = 5;
var $d = $c++;
document.write($c,$d); // 6 5 d=c; c++; 先返回c,然后c自增1
var $e = 5;
var $f = ++$e; // e++; f=e; e先自增1.然后返回e
document.write($e,$f); // 6 6
自动类型转换
自增/自减运算符,会隐式调用Number()
函数,将任意值转换为Number
,然后再进行运算
逻辑运算符
先将参与运算的数据转换为bool,然后再运算,返回值为参与运算的最后一个数据的原值(注意php不管怎样返回值都为bool型)
逻辑运算符有三个:
-
&&
与(且):两个都为真,结果才为真。 -
||
或:只要有一个是真,结果就是真。 -
!
非:对一个布尔值进行取反。
自动类型转换
逻辑运算符,会隐式调用Boolean()
函数,将任意值转换为bool,然后再进行运算
- 数字转Boolean除了
0
和NaN
,其余都是true - 字符串转Boolean除了
空字符串
其余都为true null
和undefined
转为bool都是false
小技巧:可以使用两个!!将任意类型转换为bool
逻辑运算的短路特性
- 与操作时,如果前面的逻辑值为false,则后面就不再执行
- 或操作时,如何前面的逻辑值为true,则后面就不再执行
var result = 5 && 0; // 运算过程:true && true;
console.log('result:' + result); // 打印结果:0(也就是参与运算的最后一个数据的原值)
result = NaN && 6;
console.log('result:' + result); // 打印结果:NaN (短路)
result = NaN || 6;
console.log('result:' + result); // 打印结果:6
result = 1 || 6;
console.log('result:' + result); // 打印结果:1 (短路)
实际开发中,我们经常是这样来做「容错处理」的:
当前端成功调用一个接口后,返回的数据为 result 对象。这个时候,我们用变量 a 来接收 result 里的图片资源。通常的写法是这样的:
if (result.resultCode == 0) {
var a = result && result.data && result.data.imgUrl || 'http://img.smyhvae.com/20160401_01.jpg';
}
上方代码的意思是,获取返回结果中的result.data.imgUrl
这个图片资源;如果返回结果中没有 result.data.imgUrl
这个字段,就用 http://img.smyhvae.com/20160401_01.jpg
作为兜底图片。这种写法,在实际开发中经常用到。
赋值运算符
可以将符号右侧的值赋值给符号左侧的变量。
-
=
直接赋值。比如var a = 5
-
+=
。a += 5 等价于 a = a + 5 -
-=
。a -= 5 等价于 a = a - 5 -
*=
。a *= 5 等价于 a = a * 5 -
/=
。a /= 5 等价于 a = a / 5 -
%=
。a %= 5 等价于 a = a % 5
比较运算符
比较运算符的返回值结果为布尔型值
> 大于号
< 小于号
>= 大于或等于
<= 小于或等于
== 等于
=== 全等于
!= 不等于
!== 不全等于
非数值的比较
非数值比较比较杂乱,个人觉得没什么意义,只列举几个重点
- 数字和通过Number()转换为非NaN的其他类型比较时,会将非数字转换为数字然后再比较
- 数字和通过Number()转换为NaN的其他类型比较时,返回值总是false
- 两侧的值都是字符串时,不会将其转换为数字进行比较。比较的是字符串的Unicode编码 (大坑)
因此:当我们在比较两个字符串型的数字时,一定一定要先转型再比较大小,比如 parseInt()
+
// 数字和非数字比较时,会将非数字转换为数字然后再比较
console.log(1 > true); //false
console.log(1 >= true); //true
console.log(1 > "0"); //true
// 比较两个字符串时,比较的是字符串的字符编码,比较字符编码是一位一位进行比较
console.log("56" > "123"); // true
// 比较两个字符串型的数字时,一定要先转型
console.log('1111111' > '5'); // false
console.log('1111111' > +'5'); // true
console.log('1111111' > parseInt('5')); // true
// 数字和通过Number()转换为 NaN 的其他类型比较时,返回值总是false
console.log('a'<'b'); // true
console.log('a'>'b'); // false
console.log('a'<888); // false
console.log('a'>888); // false
console.log('a'>false); // false
console.log('a'<'888'); // false
== 和 === 的说明
- == 仅判断值,=== 类型和值都判断
- 用 == 或 != 进行比较时,如果类型不同,会自动类型转换,一般是转换为数字,并且比较按照值来进行比较
- 用 === 或 !== 进行比较时不进行类型转换,因为此时类型和数值都要比对
// == 仅判断值
console.log("中国" == "中国"); // 输出结果为true
console.log("6" == 6); // 打印结果:true。这里的字符串"6"会先转换为数字6,然后再进行比较
console.log(true == "1"); // 打印结果:true
// === 类型和值都判断
console.log("6" === 6); //false
console.log(6 === 6); //true
NaN不和任何值相等,包括他本身
console.log(NaN == NaN); //false
console.log(NaN === NaN); //false
可以通过isNaN()函数来判断一个值是否是NaN
// 如果 b 为 NaN,则返回true;否则返回false。
console.log(isNaN(b));
三元运算符
三元运算符也叫条件运算符。
语法:
条件表达式 ? 语句1 : 语句2;
执行的流程:
条件运算符在执行时,首先对条件表达式进行求值:
-
如果该值为true,则执行语句1,并返回执行结果
-
如果该值为false,则执行语句2,并返回执行结果
代码示例:
a b不仅可以是变量,也可以是表达式,函数的调用
var a = 1, b = 2, c = 3;
console.log(a>b? a:b); // 2
console.log((a>b? a:b)>c? (a>b? a:b):c); // 3
运算符的优先级
运算符的优先级如下:(优先级从高到低)
-
.
、[]
、new
-
()
-
++
、--
-
!
、~
、+
(单目)、-
(单目)、typeof
、void
、delete
-
%
、*
、/
-
+
(双目)、-
(双目) -
<<
、>>
、>>>
-
关系运算符:
<
、<=
、>
、>=
-
==
、!==
、===
、!==
-
&
-
^
-
|
-
&&
-
||
-
?:
-
=
、+=
、-=
、*=
、/=
、%=
、<<=
、>>=
、>>>=
、&=
、^=
、|=
-
,
注意:逻辑与 &&
比逻辑或 ||
的优先级更高。
备注:记这些没意思,如果不清楚哪个优先级更高,可以用括号