JS基础之操作符规则

一、一元操作符:只能操作一个值的操作符


1.递增(++)递减(--)操作符(前置递增递减、后置递增递减

规则:

>应用于整数

>在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减1的操作。字符串变量变成数值变量。

>在应用与一个不包含有效数字字符的字符串时,将变量的值设置为NaN,字符串变量变成数值变量

>在应用于布尔值false时,先将其转换为0再执行加减1的操作,布尔值变量变成数值变量

>在应用于布尔值true时,先将其转换为1再执行加减1的操作,布尔值变量变成数值变量

>在应用与浮点数值时,执行加减1的操作

>在应用于对象时,先调用对象的valueOf()以取得一个可供操作的值。然后对改值应用前述规则。如果结果是NaN,则在调用toString()后再应用前述规则。对象变量变成数值变量。

例子:

          var s1 = "2";

          console.log(s1++);    //3

          var s2 = "z";

          console.log(s2++);    //NaN

          var f = 1.1;

          console.log(f--);    //0.10000000000000009(由于浮点舍入错误所致)

          var o = {

              valueOf:function(){

                  return -1;

              }

          };

          console.log(o--);    //-2


2.一元加和减操作符(+、-)---主要用于基本算术运算,也可以像前面示例展示的一样用于转换数据类型。

规则:

>一元加放在数值前面,对数值不会产生任何影响,一元减会使该值变为负数

>在对非数值应用一元加操作符时,会像Number()转型函数一样对这个值进行转换。应用一元减操作符遵循与一元加操作符相同规则,最后将得到的数值转换为负数。

例子:

          var s1 = "01";

          s1 = +s1;

          console.log(s1);    //1

          var s2 = "1.1";

          s2 = +s2;

          console.log(s2);    //1.1

          var o = {

               valueOf:function(){

                   return -1;

                }

          };

          o = -o;

          console.log(o);    //1


二、位操作符


PS:当对数值应用位操作符时,后台会将64位的数值转换成32位数值,然后执行位操作,最后再将32位的结果转换回64位数值。这样,表面上看起来就好像是在操作32位数值,但这个转换过程也导致了一个严重的副效应,即在对特殊的NaN和Infinity值应用位操作时,这两个值都会被当做0来处理。

     如果对非数值应用位操作符,会先使用Number()函数将该值转换为一个数值(自动完成),然后再应用位操作符。得到的结果将是一个数值。


1.按位非(~)---返回数值的反码,本质即操作数的负值减1(ES中少数几个与二进制计算有关的操作符之一)

例子:

          var num = 25;

          var num2 = -num;

          console.log(num2);    //-26

          虽然-num -1也能返回同样的结果,但由于按位非是在数值表示的最底层执行操作,因此速度更快。


2.按位与(&)---只在2个数值的对应位都是1时才返回1,任何一位是0,结果都是0。

例子:

          var result = 25 & 3;

          console.log(result);    //1 ( 11001 & 0011 》 1 》1)


3.按位或(|)---在有一个位是1的情况下就返回1,而只有在2个位都是0的情况下才返回0)

例子:

          var result = 25|3;

          console.log(result);    //27( 11001 | 00011 》11011 》27)


4.按位异或(^)---在2个数值对应位上只有一个1时才返回1,如果对应位的2位都是1或都是0,则返回0。

例子:

          var result = 25 ^ 3;

          console.log(result);    //26( 11001 ^ 00011 》 11010 》26)


5.左移(<<)---这个操作符会将数值的所有位向左移动指定的位数。(不会影响操作数的符号位)

例子:

          var oldValue = 2;    //等于二进制的10

          var newValue = oldValue <<5;    等于二进制的1000000,十进制的64

PS:在向左移位后,原数值的右侧多出了5个空位。左操作符会以0来填充这些空位,以便得到的结果是一个完整的32位二进制数。


6.有符号的右移(>>)---这个操作数会将数值向右移动,但保留符号位(即正负号标记)。

例子:

          var oldValue = 64;    //等于二进制的1000000

          var newValue = oldValue >> 5;    //等于二进制的10,即十进制的2

PS:这次的空位出现在原数值的左侧、符号位的右侧,而此时ES会用符号位的值来填充所有空位,以便得到一个完整的值。


7.无符号右移(>>>)---这个操作符会将数值的所有32位都向右移动,对正数来说,无符号右移的结果与有符号右移相同。

例子:

          var oldValue = 64;    //等于二进制的1000000

          var newValue = oldValue >>> 5;    //等于二进制的10,即十进制的2

但是对负数来说,情况就不一样了。首先,无符号右移是以0来填充空位,而不是像有符号右移那样以符号位的值来填充空位。所以,对整数的无符号右移与有符号右移结果相同,但对负数的结果就不一样了。其次,无符号右移操作符会把负数的二进制码当成正数的二进制码。而负数以其绝对值的二进制补码形式表示,因此就会导致无符号右移后的结果非常大。

例子:

          var oldValue = -64;    //等于二进制的11111111111111111111111111000000

      var newValue = oldValue >>> 5;    //等于二进制的00000111111111111111111111111110,等于十进制的134217726


三、布尔操作符


1.逻辑非(!)---首先会将它的操作数转换为一个布尔值,然后再对其求反。(同时使用2个逻辑非操作符,实际上就会模拟Boolean()转型函数的行为)

规则:

>如果操作数是一个对象,返回false

>如果操作数是一个空字符串,返回true

>如果操作数是一个非空字符串,返回false

>如果操作数是数值0,返回true

>如果操作数是任意非0数值(包括Infinity),返回false

>如果操作数是null,返回true

>如果操作数是NaN,返回true

>如果操作数是undefined,返回true

例子:

          console.log(!false);    //true

          console.log(!"blue");    //false

          console.log(!!NaN);    //false


2.逻辑与(&&)---又称短路与,即如果第一个操作数就能够决定结果,那么就不会再对第二个操作数求值。

规则:

在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值。

>如果第一个操作数是对象,则返回第2个操作数

>如果第2个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象

>如果2个操作数都是对象,则返回第2个操作数

>如果第一个操作数是null,则返回null

>如果第一个操作数是NaN,则返回NaN

>如果第一个操作数是undefined,则返回undefined

PS:不能在逻辑与操作中使用未定义的值,但如果第一个值为false,就不会发生错误了(不会再对第2个值求值了)


3.逻辑或(||)---短路或,如果第一个操作数的就只结果为true,就不会对第2个操作数求值了

规则:

与逻辑与相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值

>如果第一个操作数是对象,则返回第一个操作数

>如果第一个操作数的求值结果为false,则返回第二个操作数

>如果2个操作数都是对象,则返回第一个操作数

>如果2个操作数都是null,则返回null

>如果2个操作数都是NaN,则返回NaN

>如果2个操作数都是undefined,则返回undefined

PS:同样不能在逻辑或操作中使用未定义的值,但如果第一个值为true,就不会发生错误了(不会再对第2个值求值了)

我们可以利用逻辑或这一行为来避免为变量赋null或undefined值。

例如:

         var myObject = preferredObject || backupObject;

解析:变量myObject将被赋予等号后面2个值中的一个。变量preferredObject中包含优先赋给myObject的值,变量backupObject负责在preferredObject中不包含有效值的情况下提供后备值。如果prederredObject的值不是null,那么它的值将被赋给myObject;如果是null,则将backupObject的值赋给myObject。ES程序的赋值语句经常会使用这种模式。


四、乘性操作符

1.乘法(*),用于计算2个数值的乘积。

在处理特殊值的情况下,遵循下列特殊规则:

>如果操作数都是数值,执行常规的乘法计算,即2个正数或2个负数相乘的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了ES数值的表示范围,则返回Infinity或 - Infinity

>如果有一个操作数是NaN,则结果是NaN

>如果是Infinity与0相乘,则结果是NaN

>如果是Infinity与非0数值相乘,则结果是Infinity或 -Infinity,取决于有符号操作数的符号

>如果是Infinity与Infinity相乘,则结果是Infinity

>如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则

例子:

console.log(5 * "5");    //25
console.log(5 * null);    //0
console.log(5 * "a");    //NaN
console.log(5 * undefined);    //NaN
console.log(5 * NaN);    //NaN
console.log(5 * 5);    //25
console.log(Infinity * 0);    //NaN
console.log(Infinity * 2);    //Infinity
console.log(Infinity * Infinity);    //Infinity
2.除法(/)---执行第2个操作数除第一个操作数的计算

与乘法操作符类似,除法操作符对特殊的值也有特殊的处理

规则:

>如果操作数都是数值,执行常规的除法计算,即2个正数或2个负数相除的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果商超过了ES数值的表示范围,则返回Infinity或 - Infinity

>如果有一个操作数是NaN,则结果是NaN

>如果是Infinity被Infinity除,则结果是NaN

>如果是0被0除,则结果是NaN

>如果是非零的有限数被零除,则结果是Infinity 或 -Infinity,取决与有符号操作数的符号

>如果是Infinity被任何非零数值除,则结果是Infinity或-Infinity,取决与有符号操作数的符号

>如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则

例子:

console.log(5 / "5");    //1
console.log(5 / null);    //Infinity
console.log(5 / "a");    //NaN
console.log(5 / undefined);    //NaN
console.log(5 / NaN);    //NaN
console.log(5 / 5);    //1
console.log(0 / -5);    //0
console.log(0 / 0);    //NaN
console.log(-5 / 0);    //-Infinity
console.log(null / 5);    //0

3.求模(%)

与另外2个乘性操作符类似,求模操作符会遵循下列特殊规则来处理特殊的值

规则:

>如果操作数都是数值,执行常规的除法计算,返回除得的余数

>如果被除数是无穷大值而除数是有限大的数值,则结果是NaN

>如果被除数是有限大的数值而除数是零,则结果是NaN

>如果是Infinity被Infinity除,则结果是NaN

>如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数

>如果被除数是零,则结果是零

>如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则

console.log(16 % "5");    //1
console.log(5 % null);    //NaN
console.log(5 % "a");    //NaN
console.log(5 % undefined);    //NaN
console.log(5 % NaN);    //NaN
console.log(5 % 5);    //0
console.log(5 % Infinity);    //5
console.log(0 % 0);    //NaN
console.log(Infinity % Infinity);    //NaN
console.log(null % 5);    //0
console.log(Infinity % 5);    //NaN
五、加性操作符(与乘法操作符类似,也会在后台转换不同的数据类型)

1.加法(+)

如果2个操作数都是数值,执行常规的加法计算:

>如果有一个操作数是NaN,则结果是NaN

>如果是Infinity + Infinity ,则结果是Infinity

>如果是-Infinity + (-Infinity),则结果是-Infinity

>如果是Infinity +(-Infinity),则结果是NaN

>如果是+0 + (+0),则结果是+0

>如果是-0 +(-0),则结果是-0

>如果是+0 +(-0),则结果是+0

不过如果有一个操作数是字符串,那么就要应用如下规则:

>如果2个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来

>如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将2个字符串拼接起来

>如果另外有一个操作数是对象、数值或布尔值,则调用他们的toString()取得相应的字符串值,然后再应用前面关于字符串的规则。对与undefined和null,则分别调用String()函数并取得字符串"undefined"和"null"

如果一个数字加null或者undefined等非字符串,那么还是把null或者undefined进行Number()之后再相加


console.log(16 + "5");    //"165"
console.log(5 + "a");    //"5a"
console.log(5 + NaN);    //NaN
console.log(5 + null);    //5
console.log("5" + null);    //"5null"
console.log(5 + undefined);    //NaN
console.log(null + undefined);    //NaN
console.log(5 + 5);    //10
console.log("两个数的和是"+5+5);    //"两个数的和是55"
console.log("两个数的和是"+(5+5));    //"两个数的和是10"

2.减法(-)

在处理各种数据类型转换时,同样需要遵循一些特殊规则:

>如果2个操作数都是数值,则执行常规的算数减法操作并返回结果

>如果有一个操作数是NaN,则结果是NaN

>如果是Infinity - Infinity,则结果是NaN

>如果-Infinity-(-Infinity),则结果是NaN

>如果是Infinity-(-Infinity),则结果是Infinity

>如果是-Infinity -Infinity,则结果是-Infinity

>如果是+0-(+0),则结果是+0

>如果是-0-(+0),则结果是-0

>如果是-0-(-0),则结果是+0

>如果有一个操作数是字符串、布尔值、null或undefined,则先在后台调用Number()函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是NaN,则减法的结果就是NaN

>如果有一个操作数是对象,则调用对象的valueOf()以取得表示该对象的数值。如果得到的值是NaN,则减法的结果就是NaN。如果对象没有valueOf(),则调用其toString()并将得到的字符串转为数值。

>一个数字减Infinity,结果是-Infinity

例子:

console.log(16 - "5");    //11
console.log(5 - 5);    //0
console.log(5 - "a");    //NaN
console.log(5 - NaN);    //NaN
console.log(5 - null);    //5
console.log(Infinity - Infinity);    //NaN
console.log(5 - undefined);    //NaN
console.log(5 - true);    //4
console.log(5 - "true");    //NaN
console.log(5 - "");    //5
console.log(5 - Infinity);    //-Infinity
console.log("两个数的差是"+5-5);    //NaN
console.log("两个数的差是"+(5-5));    //"两个数的差是0"

六、关系操作符

1.小于(<)、大于(>)、小于等于(<=)、大于等于(>=)这几个操作符用于对2个值进行比,返回一个布尔值

与ES中的其他操作符一样,当关系操作符的操作数使用了非数值时,也要进行数据转换或完成某些奇怪的操作

规则:

>如果2个操作数都是数值,则执行数值比较

>如果2个操作数都是字符串,则比较2个字符串对应的字符串编码值(大写的字符编码全部小于小写的,要和字母表中的位置大小一样,就必须把2个操作数转为相同的大小写)

>如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较

>如果一个操作数是对象,则调用这个对象的valueOf(),用得到的结果按照前面的规则执行比较。如果对象没有valueOf(),则调用toString(),并用得到的结果根据前面的规则执行比较

>如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较

>任何操作数与NaN进行比较,结果都是false

console.log(16 > "5");    //true
console.log("23">"3");    //false,2的字符编码是50,而3的字符编码是51
console.log(5 < "a");    //false,"a"被转换成了NaN
console.log(5 >= NaN);    //false
console.log(NaN >= NaN);    //false
console.log(5 >= null );    //true
console.log(5 >= undefined);    //false
console.log(5 >= 5);    //true
console.log(5 >= "true");    //false
console.log(5 >= true);    //true
console.log(5 >= "");    //true
console.log("Brick" > "al");    //false,B的字符编码值66,a为97
console.log("brick" > "al");    //true,小写字母b的编码值比a大

七、相等操作符

"=="、“!=”相等和不相等,先转换再比较(强制转换)(注意:null == undefined,他们是类似的值)

"==="、“!==”全等和不全等,仅比较而不转换(注意:null !==undefined,他们是不同类型的值)

在转换不同的数据类型时规则:

>如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转为0,true转为1

>如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值

>如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf(),用得到的基本类型值按照前面的规则进行比较

这2个操作符在进行比较时要遵循下列规则:

>null和undefined是相等的

>要比较相等性之前,不能将null和undefined转换成其他任何值

>如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true。即使2个操作数都是NaN,相等操作符也返回false

>如果2个操作数都是对象,则比较他们是不是同一个对象。如果2个操作数都指向同一个对象,则返回true,否则返回false

例子:

console.log(true == 2);    //false
console.log(undefined == 0);    //false
console.log(null == 0);    //false
console.log(NaN != NaN);    //true
console.log("5" == 5);    //true
console.log(undefined == null );    //true
console.log("NaN" == NaN);    //false
console.log(5 == NaN);    //false
console.log(false == 0);    //true

八、条件操作符

三目表达式:variable = boolean_expersion ? true_value : false_value;

基于对boolean_expersion求值的结果,决定给变量variable赋什么值。如果求值结果为true,则给变量variable赋true_value,如果求值结果为false,则给变量variable赋false_value值。

例子:

          var max = (num1 > num2) ? num1 : num2;


九、赋值操作符

· 简单的赋值操作符:如var num = 10; 其作用就是把右侧的值赋给左侧的变量

· 复合赋值操作符:设计这些操作符的主要目的就是简化赋值操作,使用他们不会带来任何性能的提示

>乘/赋值(*=)   

>除/赋值(/=)

>模/赋值(%=)

>加/赋值(+=)

>减/赋值(-=)

>左移/赋值(<<=)

>有符号右移/赋值(>>=)

>无符号右移/赋值(>>>=)


九、逗号操作符

· 多用于声明多个变量,如var num1 = 1, num2 = 2, num3 = 3;

· 还可以用于赋值,在用于赋值时,逗号操作符总会返回表达式中的最后一项,如:var num =(5,1,4,8,0);//num的值为0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值