JavaScript运算符-学习笔记

在这里插入图片描述

1 算数运算符

JavaScript总共提供了10个算数运算符,用来完成基本的算术运算:加/减/乘/除法运算符(4个)、余数运算符、指数运算符、自增/减运算符(2个)以及数值运算符、负数值运算符。

1.1 加法运算符

1.1.1 非对象类型值相加

前4种运算符减、乘、除运算符执行的是单纯的数学运算,这里重点是加法运算符,常见用法有:

  1. 数值相加

  2. 非数值相加:两个布尔值或数值与布尔值相加,布尔值会自动转换为数值,然后相加。

    true+true //2
    1+true  //2
    
  3. 连接字符串:非字符串(如数字或布尔值)和字符串相加,这时非字符串会转为字符串,然后连接在一起。

    'a'+'bc' //"abc"
    1+'a' //"1a"
    false+'a' //"falsea"
    
  4. "重载"现象:运算子的不同,导致了不同的语法行为(数值相加或字符串相连),这种现象称为“重载”(overload)。

    '3' + 4 + 5 // "345"
    3 + 4 + '5' // "75"
    

    注意:除了加法运算符,其他像减法、乘法、除法运算符都不会发生重载现象,它们的规则是:所有运算子一律转为数值,再进行相应的数学运算

    1 - '2' // -1
    1 * '2' // 2
    1 / '2' // 0.5
    

1.1.2 对象相加

若运算子为对象,则对象会首先被转为原始类型的值,然后再相加:

var obj={p:1};
obj+2 //"[object Object]2"

实际上,在上述运算中,obj的真实转换为:obj.valueOf().toString();,其中obj.valueOf();结果为{p:1}即返回对象本身,然后调用toString()方法后变为[object Object],即再将其转为字符串。

这样看来:要想得到我们需要的结果,则需要自定定义valueOf()方法或toString()方法(Java中称之为重写方法)。我们直接在浏览器控制台进行测试:

  1. 重写valueOf()方法:

    在这里插入图片描述

  2. 重写toString()方法:
    在这里插入图片描述

特例:若运算子为Date对象,则会优先执行toString()方法。测试如下:

在这里插入图片描述

1.2 余数运算符

  1. 余数运算的结果取决于第一个运算子的正、负;

    -1 % 2 // -1
    1 % -2 // 1
    
  2. 为了得到负数正确的余数值,可以使用绝对值函数去掉负号。

    Math.abs(-1 % 2) //1
    
  3. 余数运算符还可以用于浮点数,但无法得到准确的结果:

    6.5%2.1 //0.19999999999999973
    

1.3 自增/减运算符

举个例子:自减运算符同理,这里不再赘述。

++x:先自增后返回;

x++:先返回后自增,这种运算之后,变量的值发生变化的情况被叫做运算的副作用(side effect)。

1.4 负/数值运算符

数值运算符的作用:可以将任何值转为数值(与Number函数的作用相同)。

+true //1
+[] //0
+{} //NaN
-(-1) //1

注意:数值运算符号和负数值运算符,都会返回一个新的值,而不会改变原始变量的值

1.5 指数运算符

指数运算符为**,前一个运算子为底数,后一个运算子为指数

注:指数运算符是右结合运算符,会首先计算第二个指数运算符。

2**4 //16
2**3**2 //2**(3**2)=2**9=512

2 比较运算符

比较运算符返回结果是一个布尔值,表示是否满足指定的条件。除了比较数字,其他类型的值也可以进行比较。

JavaScript总共提供了8个比较运算符,大体分为3类:

  1. 非相等运算符:大于、小于、大于等于、小于等于运算符;
  2. 相等运算符与不相等运算符;
  3. 严格相等运算符与严格不相等运算符;

对于非相等的比较,首先看两个运算子是否都是字符串,若是,则按照字典顺序比较(即比较每个字符的Unicode码);否则,将两个运算子转为数值,再比较数值的大小。

2.1 非相等运算符

  1. 字符串比较:如下例子,由于c的Unicode码为99,C的Unicode码为67,因此返回值为true;同样地也适用于汉字,“大”的Unicode码为22823,“小”的Unicode码为23567,显然返回值为false

    'cat'>'Cat' //true
    '大'>'小' //false
    
  2. 非字符串比较:字符串和布尔值都会先转成数值,再进行比较。

    5>'4' //true,等同于5>Number('4'),即5>4
    true>false //true,等同于Number(true)>Number(false),即1>0
    

    任何值(包括NaN)与NaN使用非相等运算符进行比较,返回值都为false

  3. 对象比较:会转为原始类型的值,再进行比较。具体地和上一节加法运算符中对象的转换方法是一致的,即先调用valueOf()方法;如果返回的还是对象,再接着调用toString()方法。

2.2 相等运算符

相等运算符==)比较的是两个值是否相等:会将两个值转换为同一种类型的值后,再用===进行比较;不相等运算符!=)则为相等运算符的结果取反。

  1. 简单值比较:

    1==1.0 //true
    1==true //true
    0==false //true
    true=='true' //false,等同于Number(true)===Number('true'),即1===NaN
    ''==0 //true,等同于Number('')===0,即0===0
    '1'==true //true,等同于Number('1')===Number(true),即1===1
    undefined == undefined // true
    null == null // true
    undefined == null // true
    
  2. 复合类型的值比较:同样地,对象先调用valueOf()方法;如果返回的还是对象,再接着调用toString()方法。

    [1]==1 //true
    [1,2]=='1,2' //true
    [1]==true //true
    

2.3 严格相等运算符

严格相等运算符===)比较的是它们是否为同一个值:若两个值不是同一类型,则严格相等运算符直接返回false严格不相等运算符!==)就是对严格相等运算符的结果取反。

  1. 简单值比较:

    1===1.0 //true,等价于1==1.0
    1==='1' //false,类型不同
    true==='true' //false,类型不同
    1===0x1 //true,十进制的1和十六进制的1类型相同,值相同,因此返回true。
    +0===-0 //true
    NaN===NaN //false,NaN与任何值都不相等(包括自身)
    undefined === undefined // true
    null === null // true
    
  2. 复合类型的值(对象、函数、数组)比较:比较的是它们是否指向同一个地址

    {} === {} // false
    [] === [] // false
    (function () {} === function () {}) // false
    
    //若两个对象引用同一个对象,则严格相等
    var v1 = {};
    var v2 = v1;
    v1 === v2 // true
    

总结相等运算符会进行隐式类型转换,建议只使用严格相等运算符

3 布尔运算符

布尔运算符用于将表达式转为布尔值,共有4个运算符:

  1. 取反运算符:!,像undefinednullfalse0NaN''(空字符串)这6个值取反后为true,其他值则都为false

    注:两次取反就是将一个值转为布尔值的简便写法,等同于Boolean()函数。

  2. 运算符:&&,往往用于多个表达式求值,运算规则为:返回第一个布尔值为false的表达式的值,若所有表达式的值都为true则返回最后一个表达式的值。

    true && 'foo' && '' && 4 && 'foo' && true  //返回值为''
    1 && 2 && 3  //返回值为3
    
  3. 运算符:||,也往往用于多个表达式求值,运算规则为:返回第一个布尔值为true的表达式的值,若所有表达式的值都为false,则返回最后一个表达式的值。

    技巧:或运算符常用于为一个变量设置默认值

    false || 0 || '' || 4 || 'foo' || true //返回值为4
    false || 0 || '' // 返回值为''
    
  4. 三元运算符:?:,与if...else语句具有同样表达效果。

4 二进制位运算符

二进制位运算符用于对二进制位进行计算,共有7个:

注:位运算只对整数有效,遇到小数时,会将小数部分舍去,只保留整数部分。

  1. 二进制或运算符,符号为|,若两个二进制位都为0,则结果为0,否则为1
  2. 二进制与运算符,符号为&,若两个二进制位都为1,则结果为1,否则为0
  3. 二进制否运算符,符号为~,对二进制位取反。
  4. 异或运算符,符号为^,若两个二进制位不同,则结果为1,否则为0
  5. 左移运算符,符号为<<,表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方。向左移动的时候,最高位的符号位是一起移动的。
  6. 右移运算符,符号为>>,表示将一个数的二进制值向右移动指定的位数。如果是正数,头部全部补0;如果是负数,头部全部补1,右移运算符基本上相当于除以2的指定次方,同样地,最高位即符号位也参与移动。
  7. 头部补零的右移运算符,符号为>>>,它与右移运算符(>>)只有一个差别,就是一个数的二进制形式向右移动时,头部一律补零,而不考虑符号位。所以,该运算总是得到正值。

5 赋值运算符

赋值运算符(Assignment Operators)用于给变量赋值

赋值运算符最常见的就是=,但还可以和其他运算符结合使用。

  • 算术运算符结合:x+=y(等同于x=x+y)、x-=y(等同于x=x-y)、x*=y(等同于x=x*y)、x/=y(等同于x=x/y)、x%=y(等同于x=x%y)、x**=y(等同于x=x**y)。

  • 位运算符结合:x>>=y(等同于x=x>>y)、x<<=y(等同于x=x<<y)、x>>>=y(等同于x=x>>>y)、x&=y(等同于x=x&y)、x|=y(等同于x=x|y)、x^=y(等同于x=x^y)。

6 void运算符

void运算符用于执行一个表达式,然后不返回任何值(或返回undefined)。

void(0) // undefined

void运算符的主要用途:浏览器的书签工具,以及在超链接中插入代码防止网页跳转。

模仿添加书签:

<script>
function f() {
  console.log('Hello World');
}
</script>

<a href="http://example.com" onclick="f(); return false;">点击</a>
//使用void则写法更加简洁
<a href="javascript: void(f())">文字</a>

提交但并不跳转:

<a href="javascript: void(document.form.submit())">提交</a>

7 逗号运算符

逗号运算符用于对2个表达式求值,并返回后1个表达式的值

var x = 0;
var y = (x++, 10);
x // 1
y // 10

8 运算顺序

8.1 优先级

JavaScript的各种运算符的优先级别(Operator Precedence)时不一样的,优先级高的高的运算符先执行,优先级低的后执行。

8.2 圆括号

圆括号()的优先级是最高的,可以用它来提高运算的优先级。建议总是使用圆括号,保证运算顺序清晰可读,这对代码的维护和除错至关重要。

注:圆括号不具有求值的作用,即(expression)等同于expression,它仅改变了运算的优先级。

8.3 左/右结合运算符

在计算时,对于优先级别相同的运算符(例如加和减是同等优先级)同时出现的时候,就会有计算顺序的问题,我们姑且用下面的式子表示(OP为Operator Precedence的缩写):

a OP b OP c

运算的方式有:

// 方式1
(a OP b) OP c
// 方式2
a OP (b OP c)

若采用方式1运行的运算符,则称为左结合运算符(left-to-right associativity);若采用方式2运行的运算符,则称为右结合运算符(right-to-left associativity)。

JavaScript运算符大多数都为左结合运算符,少数像赋值运算符=、三元运算符?:以及指数运算符**为右结合运算符。

w = x = y = z;  //等同于w = (x = (y = z));
q = a ? b : c ? d : e ? f : g; //等同于q = a ? b : (c ? d : (e ? f : g));
2 ** 3 ** 2 //等同于2 ** (3 ** 2)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值