运算符
第2章:变量和数据类型,解决数据存放问题 第3章:运算符,解决数据运算的问题,面试题密集
操作符和操作数
操作符:运算符,参与运算的符号
操作数:参与运算的数据,也称之为“元”
操作符不一定只有一个符号
操作符出现在不同的位置,可能具有不同的含义
1 - 2;
-1.2;目前接触的操作符:
=:赋值符号,将右边的数据赋值给左边.: 访问符号,用于访问对象的属性[]:访问符号,用于访问对象的属性():函数调用
分类
按操作数数量区分:
- 一元(目)运算符:() . []
- 二元(目)运算符: + - / * % =
- 三元(目)运算符: ?:
功能区分:
- 算术运算符(数学)
- 比较运算符
- 逻辑运算符
- 位运算符
- 其他
表达式
表达式 = 操作符 + 操作数
每个表达式都有一个运算结果,该结果叫做返回值,返回值的类型叫做返回类型
所有的表达式都可以当作数据使用。
目前学习的运算符的返回值和类型
=:该表达式,返回赋值的结果.:属性访问表达式,返回的是属性的值[]:属性访问表达式,返回的是属性的值():函数调用表达式,返回的结果取决于函数的运行- 如果是一个声明+赋值的表达式,返回结果为undefined。
console.log函数调用的返回结果为undefined
chrome浏览器控制台的环境是REPL环境 REPL:Read Eval Print Loop,读-执行-打印-循环 当直接在控制台书写代码时,除了运行代码之外,还会输出该表达式的返回值
算数运算符
数学运算符
+ - * /+ -%++ --(下节课讨论)**幂
其他类型使用算术运算
- 除加号之外的算术运算符
将原始类型转换为数字类型(自动完成转换),然后进行运算。
- boolean: true -> 1, false -> 0
- string: 如果字符串内部是一个正确的数字,直接变为数字,如果是一个非数字,则得到NaN(能识别Infinity,不能把字符串内部的东西当作表达式),如果字符串是一个空字符串(没有任何内容),转换为0. 字符串转换时,会忽略前后空格。
NaN虽然是数字,但它和任何数字作任何运算,得到的结果都是NaN
- null:null -> 0
- undefined: undefined -> NaN
将对象类型先转换为字符串类型,然后再将该字符串转换为数字类型
对象类型 -> "[object Object]" -> NaN
- 加号运算符
- 加号一边有字符串,含义变为字符串拼接
将另一边的其他类型,转换为字符串
数字 -> 数字字符串 boolean -> boolean字符串 null -> "null" undefined -> "undefined" 对象 -> "[object Object]"
- 加号两边都没有字符串,但一边有对象,将对象转换为字符串,然后按照上面的规则进行
- 其他情况和上面的数学运算一致
// 说出下面的输出结果
console.log(1 + 2 * 3); // 7
console.log(1 + (3 % 2)); // 2
console.log("" + (3 % 2)); // "1"
console.log(+"" + (3 % 2)); // 1
console.log(+{} + ""); //"NaN"
console.log((100 % 4) / 0); //NaN
console.log(null / null); //NaN
var a;
console.log(a + {} + 123); //undefined[object Object]123
console.log(1 + "" + 2 + 3); //"123"
console.log({} * null); //NaN
console.log(+"" + 100); //100技巧: 在一个类型前使用
+true,将该类型转换为数字。
自增和自减
基本功能
一元运算符
++:将某个变量的值自增1
--:将某个变量的值自减1
细节
自增自减表达式
x++: 将变量x自增1,得到的表达式的值是自增之前的值。 ++x: 将变量x自增1,得到的表达式的值是自增之后的值。 x--: 将变量x自减1,得到的表达式的值是自减之前的值。 --x: 将变量x自减1,得到的表达式的值是自减之后的值。
优先级
从高到底依次是:
++ --* / %+ -
优先级的运算细节:
- 从左到右依次查看
- 如果遇到操作数,将数据的值直接取出
- 如果遇到相邻的两个运算符,并且左边的运算符优先级大于等于右边的运算符,则直接运行左边的运算符。
比较运算符
大小比较:> < >= <= 相等比较:== != === !==
比较运算符的返回类型:boolean
算术运算符的优先级高于比较运算符
细节
两个字符串比较大小,比较的是字符串的字符编码。
如果一个不是字符串,并且两个都是原始类型,将它们都转换为数字进行比较
'1' -> 1 '' -> 0 ' ' -> 0 ' a' -> NaN '3.14' -> 3.14
NaN与任何数字比较,得到的结果都是false
Infinity比任何数字都大
-Infinity比任何数字都小
- 如果其中一个是对象,将对象转换为原始类型然后,按照规则1或规则2进行比较
目前,对象转换为原始类型后,是字符串 "[object Object]"
== 和 != (相等比较 和 不相等比较)
==: 比较两个数据是否相等 !=: 比较两个数据是否不相等
细节
- 两端的类型相同,直接比较两个数据本身是否相同(两个对象比较的地址)
- 两端的类型不同
- null 和 undefined, 它们之间相等, 和其他原始类型比较, 则不相等。
- 其他原始类型,比较时先转换为数字,再进行比较
- NaN与任何数字比较,都是false,包括自身
- Infinity和-Infinity,自能和自身相等
- 对象比较时,要先转换为原始类型后,再进行比较
由于相等和不相等比较,对于不同类型的数据比较违反直觉,因此,通常我们不适用这种比较方式,而是使用更加接近直觉的严格相等和严格不相等比较
=== 和 !== (严格相等 和 严格不相等)
=== : 两端的数据和类型必须相同 !== : 两端的数据或类型不相同
- 两端类型相同,规则和相等比较一致。
- 两端类型不同,为false。
数字规则:
- NaN与任何数字比较,都是false,包括自身
- Infinity和-Infinity,自能和自身相等
推荐使用===
逻辑运算符
布尔运算符
与(并且)
符号:&&
书写方式: 表达式1 && 表达式2
将表达式1 进行 boolean 判定
以下数据均判定为false:
- null
- undefined
- false
- NaN
- ''
- 0
其他数据全部为真
如果表达式1的判定结果为假,则直接返回表达式1,而不执行表达式2;
否则,返回表达式2的结果。 (短路规则)
或
符号:||
写法:表达式1 || 表达式2
- 将表达式1 进行 boolean 判定
- 如果表达式1为真,直接返回表达式1,不运行表达式2;否则,返回表达式2
非
符号:!
写法: !数据
一元运算符 优先级最高
将数据的boolean判定结果直接取反,非运算符一定返回boolean类型。
三目运算符
书写方式: 表达式1 ? 表达式2 : 表达式3
- 对表达式1进行boolean判定
- 如果判定结果为真,返回表达式2;否则,返回表达式3。
运算符补充
类型转换不会影响原本的数据
复合的赋值运算符
+= -= /= *= %= **=
void 运算符
一元运算符
写法:
- 普通写法:
void 表达式 - 函数写法:
void(表达式)
运行表达式,然后返回undefined
typeof 运算符
一元运算符
写法:
- 普通写法:
typeof 表达式 - 函数写法:
typeof(表达式)
typeof运算,返回表达式的类型,是一个字符串。
逗号运算符
写法:表达式1, 表达式2
依次运行两个表达式,返回表达式2
逗号运算符的优先级比赋值更低
var x = 1;
x = (x++ * 2, x++ * 2, x++ * 2);
console.log(x); //6
((x = x++ * 2), x++ * 2, x++ * 2);
console.log(x); //4 会把x = x++ * 2当成一个整体