3.运算符

147 阅读8分钟

运算符概述

第2章:变量和数据类型,解决数据存放问题 第3章:运算符,解决数据运算的问题,面试题密集

操作符和操作数

操作符:运算符,参与运算的符号

操作数:参与运算的数据,也称之为“元”

操作符不一定只有一个符号

操作符出现在不同的位置,可能具有不同的含义

1-2;
-1.2;

目前接触的操作符:

  1. =:赋值符号,将右边的数据赋值给左边
  2. .: 访问符号,用于访问对象的属性
  3. []:访问符号,用于访问对象的属性
  4. ():函数调用

分类

按操作数数量区分:

  1. 一元(目)运算符:() . []
  2. 二元(目)运算符: + - / * % =
  3. 三元(目)运算符: ?:

功能区分:

  1. 算术运算符(数学)
  2. 比较运算符
  3. 逻辑运算符
  4. 位运算符
  5. 其他

表达式

表达式 = 操作符 + 操作数

每个表达式都有一个运算结果,该结果叫做返回值,返回值的类型叫做返回类型

所有的表达式都可以当作数据使用。

目前学习的运算符的返回值和类型

  1. =:该表达式,返回赋值的结果
  2. .:属性访问表达式,返回的是属性的值
  3. []:属性访问表达式,返回的是属性的值
  4. ():函数调用表达式,返回的结果取决于函数的运行
  5. 如果是一个声明+赋值的表达式,返回结果为undefined。

console.log函数调用的返回结果为undefined

chrome浏览器控制台的环境是REPL环境 REPL:Read Eval Print Loop,读-执行-打印-循环 当直接在控制台书写代码时,除了运行代码之外,还会输出该表达式的返回值

算术运算符

数学运算符

  1. + - * /
  2. + -
  3. %
  4. ++ -- (下节课讨论)
  5. **

细节

  1. 数字运算是不精确的

  2. 除数为0

如果被除数是正数,得到结果 Infinity (正无穷) 如果被除数是负数,得到结果 -Infinity (负无穷) 如果被除数是0,得到结果 NaN (Not a Number,非数字)

typeof函数返回类型为string isNaN函数,该函数用于判断一个数据是否是NaN,返回boolean isFinite函数,该函数用于判断一个数据是否是有限的,返回boolean

image.png

  1. 求余

%,有的教程称之为求模

余数的符号,与被除数相同。

这里需要注意的是负数也是可以求余的

image.png

其他类型使用算术运算

  1. 除加号之外的算术运算符

将原始类型转换为数字类型(自动完成转换),然后进行运算。

  • boolean: true -> 1, false -> 0
  • string: 如果字符串内部是一个正确的数字,直接变为数字,如果是一个非数字,则得到NaN(能识别Infinity,不能把字符串内部的东西当作表达式),如果字符串是一个空字符串(没有任何内容),转换为0. 字符串转换时,会忽略前后空格。

NaN虽然是数字,但它和任何数字作任何运算,得到的结果都是NaN

  • null:null -> 0
  • undefined: undefined -> NaN

将对象类型先转换为字符串类型,然后再将该字符串转换为数字类型

对象类型 -> "[object Object]" -> NaN

image.png

  1. 加号运算符
  • 加号一边有字符串,含义变为字符串拼接

将另一边的其他类型,转换为字符串

数字 -> 数字字符串 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,转化为字符串就是 “NaNconsole.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,得到的表达式的值是自减之后的值。

优先级

从高到底依次是:

  1. ++ --
  2. * / %
  3. + -

优先级的运算细节:

  1. 从左到右依次查看
  2. 如果遇到操作数,将数据的值直接取出
  3. 如果遇到相邻的两个运算符,并且左边的运算符优先级大于等于右边的运算符,则直接运行左边的运算符。

比较运算符

大小比较:> < >= <= 相等比较:== != === !==

比较运算符的返回类型:boolean

算术运算符的优先级高于比较运算符

大小比较

细节

  1. 两个字符串比较大小,比较的是字符串的字符编码。具体是怎么比较的呢? "ACC" > "ABF",具体来说就是先比较A的ASCI码,第一位相等。比较完开始比较第二位,发现第一个的C的ASCI码数值大于B的ASCI码,第一个大于字符串大于第二个,不再继续往下比较了。不轮第二个后面还有多少位均不再比较了。

  2. 如果一个不是字符串,并且两个都是原始类型,将它们都转换为数字进行比较

'1' -> 1 '' -> 0 ' ' -> 0 ' a' -> NaN '3.14' -> 3.14

NaN与任何数字比较,得到的结果都是false

Infinity比任何数字都大

-Infinity比任何数字都小

  1. 如果其中一个是对象,将对象转换为原始类型然后,按照规则1或规则2进行比较

目前,对象转换为原始类型后,是字符串 "[object Object]"

相等比较

== 和 != (相等比较 和 不相等比较)

==: 比较两个数据是否相等 !=: 比较两个数据是否不相等

细节

  1. 两端的类型相同,直接比较两个数据本身是否相同(两个对象比较的地址)

  2. 两端的类型不同

1). null 和 undefined, 它们之间相等, 和其他原始类型比较, 则不相等。 2). 其他原始类型,比较时先转换为数字,再进行比较 3). NaN与任何数字比较,都是false,包括自身 4). Infinity和-Infinity,自能和自身相等 5). 对象比较时,要先转换为原始类型后,再进行比较

由于相等和不相等比较,对于不同类型的数据比较违反直觉,因此,通常我们不适用这种比较方式,而是使用更加接近直觉的严格相等和严格不相等比较

=== 和 !== (严格相等 和 严格不相等)

=== : 两端的数据和类型必须相同 !== : 两端的数据或类型不相同

  1. 两端类型相同,规则和相等比较一致。
  2. 两端类型不同,为false。

数字规则:

1). NaN与任何数字比较,都是false,包括自身 2). Infinity和-Infinity,自能和自身相等

逻辑运算符

布尔运算符

与(并且)

符号:&&

书写方式: 表达式1 && 表达式2

  1. 将表达式1 进行 boolean 判定

以下数据均判定为false:

  1. null
  2. undefined
  3. false
  4. NaN
  5. ''
  6. 0

其他数据全部为真

  1. 如果表达式1的判定结果为假,则直接返回表达式1,而不执行表达式2;否则,返回表达式2的结果。 (短路规则)

符号:||

写法:表达式1 || 表达式2

  1. 将表达式1 进行 boolean 判定

  2. 如果表达式1为真,直接返回表达式1,不运行表达式2;否则,返回表达式2

符号:!

写法: !数据

一元运算符

将数据的boolean判定结果直接取反,非运算符一定返回boolean类型。

三目运算符

书写方式: 表达式1 ? 表达式2 : 表达式3

  1. 对表达式1进行boolean判定
  2. 如果判定结果为真,返回表达式2;否则,返回表达式3。

补充知识

模板字符串

首先js 拼接字符串有两种方法:

  1. 使用 + 进行拼接 “” + user.name
  2. 使用 来拼接 有点像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 运算符

一元运算符

写法:

  1. 普通写法: void 表达式
  2. 函数写法: void(表达式)

运行表达式,然后返回undefined

void 1 + 2 ,计算 void 1 计算后是undefined,undefined + 2 -》 NaN + 2 最后就是NaN 运行表达式,然后返回undefined,作用太扯淡了,基本没用。

typeof 运算符

一元运算符

写法:

  1. 普通写法: typeof 表达式
  2. 函数写法: typeof(表达式)

typeof运算,返回表达式的类型,是一个字符串。 比方说 typeof 1+ 2 结果是 “number2”

逗号运算符

写法:表达式1, 表达式2

依次运行两个表达式,返回表达式2

逗号运算符的优先级比赋值更低