运算符概述
第2章:变量和数据类型,解决数据存放问题 第3章:运算符,解决数据运算的问题,面试题密集
操作符和操作数
操作符:运算符,参与运算的符号
操作数:参与运算的数据,也称之为“元”
操作符不一定只有一个符号
操作符出现在不同的位置,可能具有不同的含义
1-2;
-1.2;
目前接触的操作符:
=:赋值符号,将右边的数据赋值给左边.: 访问符号,用于访问对象的属性[]:访问符号,用于访问对象的属性():函数调用
分类
按操作数数量区分:
- 一元(目)运算符:() . []
- 二元(目)运算符: + - / * % =
- 三元(目)运算符: ?:
功能区分:
- 算术运算符(数学)
- 比较运算符
- 逻辑运算符
- 位运算符
- 其他
表达式
表达式 = 操作符 + 操作数
每个表达式都有一个运算结果,该结果叫做返回值,返回值的类型叫做返回类型
所有的表达式都可以当作数据使用。
目前学习的运算符的返回值和类型
=:该表达式,返回赋值的结果.:属性访问表达式,返回的是属性的值[]:属性访问表达式,返回的是属性的值():函数调用表达式,返回的结果取决于函数的运行- 如果是一个声明+赋值的表达式,返回结果为undefined。
console.log函数调用的返回结果为undefined
chrome浏览器控制台的环境是REPL环境 REPL:Read Eval Print Loop,读-执行-打印-循环 当直接在控制台书写代码时,除了运行代码之外,还会输出该表达式的返回值
算术运算符
数学运算符
+ - * /+ -%++ --(下节课讨论)**幂
细节
-
数字运算是不精确的
-
除数为0
如果被除数是正数,得到结果 Infinity (正无穷) 如果被除数是负数,得到结果 -Infinity (负无穷) 如果被除数是0,得到结果 NaN (Not a Number,非数字)
typeof函数返回类型为string isNaN函数,该函数用于判断一个数据是否是NaN,返回boolean isFinite函数,该函数用于判断一个数据是否是有限的,返回boolean
- 求余
%,有的教程称之为求模
余数的符号,与被除数相同。
这里需要注意的是负数也是可以求余的
其他类型使用算术运算
- 除加号之外的算术运算符
将原始类型转换为数字类型(自动完成转换),然后进行运算。
- boolean: true -> 1, false -> 0
- string: 如果字符串内部是一个正确的数字,直接变为数字,如果是一个非数字,则得到NaN(能识别Infinity,不能把字符串内部的东西当作表达式),如果字符串是一个空字符串(没有任何内容),转换为0. 字符串转换时,会忽略前后空格。
NaN虽然是数字,但它和任何数字作任何运算,得到的结果都是NaN
- null:null -> 0
- undefined: undefined -> NaN
将对象类型先转换为字符串类型,然后再将该字符串转换为数字类型
对象类型 -> "[object Object]" -> NaN
- 加号运算符
- 加号一边有字符串,含义变为字符串拼接
将另一边的其他类型,转换为字符串
数字 -> 数字字符串 boolean -> boolean字符串(“true” “false”) null -> "null" undefined -> "undefined" 对象 -> "[object Object]"
-
加号两边都没有字符串,但一边有对象,将对象转换为字符串,然后按照上面的规则进行.对象转换为字符串是'[object Object]'。
-
其他情况和上面的数学运算一致
练习
<script>
// 说出下面的输出结果
console.log(1 + 2 * 3); // 7
console.log(1 + 3 % 2); // 2
console.log("" + 3 % 2);// "1" 字符串拼接 1
console.log(+"" + 3 % 2); // 1
首先 +“”,代表是一个正数,然后将 +“”转化为 0,再然后 0 + 1 =1
console.log(+{} + ""); //"NaN"
现将 +{} 转化为数字,是NaN,转化为字符串就是 “NaN”
console.log(100 % 4 / 0); //NaN
console.log(null / null); //NaN
var a;
console.log(a + {} + 123); //undefined[object Object]123
看见{} 对象类型,先将对象转化为 “[object Object]”,再继续算
console.log(1 + "" + 2 + 3); //"123"
console.log({} * null); //NaN
对象类型 -> "[object Object]" -> NaN
console.log(+"" + 100); //100
</script>
**+{} {} 进行运算,现将他转化为NaN,再进行后续处理 **
字符串转数字
+”字符串“可以把字符串转化为数字,比方说 +“-3” 其实将“-3” 转化为数字 -3.
字符串拼接
<script>
var C = 27.5;
var F = 9 / 5 * C + 32;
console.log("摄氏温度为" + C + "度,华氏温度为" + F + "度");
</script>
自增和自减
基本功能
一元运算符
++:将某个变量的值自增1
--:将某个变量的值自减1
细节
自增自减表达式
x++: 将变量x自增1,得到的表达式的值是自增之前的值。 ++x: 将变量x自增1,得到的表达式的值是自增之后的值。 x--: 将变量x自减1,得到的表达式的值是自减之前的值。 --x: 将变量x自减1,得到的表达式的值是自减之后的值。
优先级
从高到底依次是:
++ --* / %+ -
优先级的运算细节:
- 从左到右依次查看
- 如果遇到操作数,将数据的值直接取出
- 如果遇到相邻的两个运算符,并且左边的运算符优先级大于等于右边的运算符,则直接运行左边的运算符。
比较运算符
大小比较:> < >= <= 相等比较:== != === !==
比较运算符的返回类型:boolean
算术运算符的优先级高于比较运算符
大小比较
细节
-
两个字符串比较大小,比较的是字符串的字符编码。具体是怎么比较的呢? "ACC" > "ABF",具体来说就是先比较A的ASCI码,第一位相等。比较完开始比较第二位,发现第一个的C的ASCI码数值大于B的ASCI码,第一个大于字符串大于第二个,不再继续往下比较了。不轮第二个后面还有多少位均不再比较了。
-
如果一个不是字符串,并且两个都是原始类型,将它们都转换为数字进行比较
'1' -> 1 '' -> 0 ' ' -> 0 ' a' -> NaN '3.14' -> 3.14
NaN与任何数字比较,得到的结果都是false
Infinity比任何数字都大
-Infinity比任何数字都小
- 如果其中一个是对象,将对象转换为原始类型然后,按照规则1或规则2进行比较
目前,对象转换为原始类型后,是字符串 "[object Object]"
相等比较
== 和 != (相等比较 和 不相等比较)
==: 比较两个数据是否相等 !=: 比较两个数据是否不相等
细节
-
两端的类型相同,直接比较两个数据本身是否相同(两个对象比较的地址)
-
两端的类型不同
1). null 和 undefined, 它们之间相等, 和其他原始类型比较, 则不相等。 2). 其他原始类型,比较时先转换为数字,再进行比较 3). NaN与任何数字比较,都是false,包括自身 4). Infinity和-Infinity,自能和自身相等 5). 对象比较时,要先转换为原始类型后,再进行比较
由于相等和不相等比较,对于不同类型的数据比较违反直觉,因此,通常我们不适用这种比较方式,而是使用更加接近直觉的严格相等和严格不相等比较
=== 和 !== (严格相等 和 严格不相等)
=== : 两端的数据和类型必须相同 !== : 两端的数据或类型不相同
- 两端类型相同,规则和相等比较一致。
- 两端类型不同,为false。
数字规则:
1). NaN与任何数字比较,都是false,包括自身 2). 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。
补充知识
模板字符串
首先js 拼接字符串有两种方法:
- 使用 + 进行拼接 “” + user.name
- 使用
来拼接有点像oc 中 @“”,首先是 ``,然后里面写直接我叫${user.name},今年${user.age}岁了,注意看里面的${}这种写法,作用和 %@ %ld一样。 特别需要注意的是模版字符串里面必须在两个飘之间。
// 输出: 我叫xxx,今年xxx岁了,性别是xxx,目前已成年(未成年)
console.log("我叫" + user.name +
",今年" + user.age +
"岁了,性别是" + user.gender +
",目前" + (user.age >= 18 ? "已成年" : "未成年"));
console.log(`我叫${user.name},今年${user.age}岁了,性别是${user.gender},目前${user.age>=18?"已成年":"未成年"}`);
复合的赋值运算符
+= -= /= *= %= **=
void 运算符
一元运算符
写法:
- 普通写法:
void 表达式 - 函数写法:
void(表达式)
运行表达式,然后返回undefined
void 1 + 2 ,计算 void 1 计算后是undefined,undefined + 2 -》 NaN + 2 最后就是NaN 运行表达式,然后返回undefined,作用太扯淡了,基本没用。
typeof 运算符
一元运算符
写法:
- 普通写法:
typeof 表达式 - 函数写法:
typeof(表达式)
typeof运算,返回表达式的类型,是一个字符串。 比方说 typeof 1+ 2 结果是 “number2”
逗号运算符
写法:表达式1, 表达式2
依次运行两个表达式,返回表达式2
逗号运算符的优先级比赋值更低