js中的常用运算符规则和隐式类型转换

在 JavaScript 中,当我们进行比较操作或者加减乘除四则运算操作时,常常会触发 JavaScript 的隐式类型转换机制,下面将介绍javaScript的数据类型及执行运算时遵循的类型转换规则。

一、javaScript 数据类型:

(1)值类型(基本类型、原始值):Undefined(未定义)、Null(空)、Boolean(布尔)、Number(数字)、String(字符串)、Symbol(ES6 新增数据类型, 类似于字符串类型, 通常用来作为对象的属性名,表示独一无二的值);

(2)引用数据类型(对象值):Object(对象),包括Array(数组)、Function(函数)、Date(日期)等除了基本类型之外的所有其他类型的值。

原始类型(基本类型):按值访问,可以操作保存在变量中实际的值。原始类型汇总中null和undefined比较特殊。

引用类型:引用类型的值是保存在内存中的对象。

与其他语言不同的是,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。所以引用类型的值是按引用访问的。

二、javaScript 数据类型转换

1. 一般的类型转换可参照下面的类型转换表(包括引用类型向原始类型转换的范例):

初始值转化为数值类型转化为字符串类型转化为 Boolean 类型
false0"false"false
true1"true"true
00"0"false
11"1"true
"0"0"0"true
"1"1"1"true
NaNNaN"NaN"false
InfinityInfinity"Infinity"true
-Infinity-Infinity"-Infinity"true
""0""false
"20"20"20"true
"twenty"NaN"twenty"true
[ ]0""true
[20]20"20"true
[10,20]NaN"10,20"true
["twenty"]NaN"twenty"true
["ten","twenty"]NaN"ten,twenty"true
function(){}NaN"function(){}"true
{ }NaN"[object Object]"true
null0"null"false
undefinedNaN"undefined"false

2. 在比较运算与加法运算中,都会涉及将运算符两侧的操作对象转换为原始对象的操作,此过程实际上由javaScript引擎内部的抽象操作 ToPrimitive(input [, PreferredType]) 函数执行,当某个对象出现在了需要原始类型才能进行操作的上下文时,JavaScript 会自动调用 ToPrimitive 函数将对象转化为原始类型。该抽象操作接受一个参数input和一个可选的参数PreferredType。该抽象操作的目的是把参数input转化为非对象数据类型,也就是原始数据类型。如果input可以同时转化为多个原始数据,那么会优先参考PreferredType的值。转换过程参照表:

参数input的数据类型结果
Undefined返回input自身
Null返回input自身
Boolean返回input自身
Number返回input自身
String返回input自身
Symbol返回input自身
Object

执行下面的步骤:

 

若 PreferredType是Number,则:

  1. 先调用 input.valueOf() 方法,若 执行结果 为原始类型,则返回 执行结果

  2. valueOf() 方法执行结果仍是对象类型(例如数组调用valueOf()返回其本身,仍是对象类型),则继续调用 toString() 方法,若 执行结果 为原始类型,则返回 执行结果

  3. toString() 方法 执行结果 仍是对象类型,则抛出类型错误的异常;

若 PreferredType是String,则与PreferredType是Number的情况步骤相反,先调用toString()方法 :

  1. 先调用 input.toString() 方法,若 执行结果 为原始类型,则返回 执行结果

  2. 若 toString() 方法执行结果仍是对象类型,则继续调用 valueOf() 方法,若 执行结果 为原始类型,则返回 执行结果

  3. valueOf() 方法 执行结果 仍是对象类型,则抛出类型错误的异常;

若PreferredType未设置,则将 PreferredType默认为 Number ,按照PreferredType是Number的规则进行处理(Date日期对象会默认为String,按照String处理)。

三、javaScript 常用运算符规则

注:若两个操作数不是均为数字,则只有 + 号 会优先考虑转换为字符串(但若其中一个操作数为数字,另一个操作数为原始类型,则会将原始类型转化为Number),剩下的操作均优先转换为Number再进行计算。

1. 加法(+)

对于加法运算而言,JavaScript 首先会将操作符两侧的对象转换为 Primitive 类型,即先调用ToPrimitive函数,在适当的隐式类型转换可得出有意义的值的前提下,JavaScript 会先进行隐式类型转换,再进行运算。一般遵循如下规则:

(1)若两个操作数均为数值,则遵循常规加法计算;

(2)否则遵循下列规则:

  • 若其中一个操作数为 NaN,则结果为 NaN;
  • 若为 Infinity + Infinity,则结果为 Infinity;
  • 若为  -Infinity + (-Infinity),则结果为 -Infinity;
  • 若为 -Infinity + Infinity,则结果为 NaN;
  • 若为 +0 加 +0,则结果为 +0;
  • 若为 -0 加 -0,则结果为 -0;
  • 若为 +0 加 -0,则结果为 +0;
  • 若两个操作数均为字符串,则结果为 两个字符串拼接的结果:'0' + '1' = '01'
  • 若其中一个为字符串,则将另一个操作数转化为字符串,再返回 两个字符串拼接起来的结果;
  • 若其中一个为非数值类型或非字符串类型,则遵循ToPrimitive函数执行结果,再遵循字符串相加规则计算最后结果;

2. 减法(-)

javaScript减法执行遵循下列规则:

  • 如果两个操作数都是数值,则执行常规的算术减法操作并返回结果
  • 如果一个操作数是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()方法并将得到的字符串转换为数值

3. 关系操作符:小于(<)、大于(>)、小于等于(<=)、大于等于(>=)

(1)若对两个数值进行比较时,则按照正常比较大小的规则返回一个布尔值;

(2)若对非数值进行比较时,则遵循下列规则:

  • 若两个操作数都是字符串,则比较两个字符串对应的字符编码值;
  • 若一个操作数是数值,则将另一个操作数转换为一个数值,再执行数值的比较;
  • 若一个操作数是对象,则调用这个对象的valueOf()方法,并用得到的结果(按照javaScript 数据类型转换规则获得)根据前面的规则执行比较;
  • 若一个操作数是布尔值,则先将其转换为数值,再执行比较;
  • 例子:
    var result1 = "Brick" < "alphabet";//true
    //字母B的字符编码为66,二字母a的字符编码为97
    
    var result2 = "23" < "3";//true
    //两个操作数都是字符串,而字符串比较的是字符编码("2"的字符编码是50,而"3"的字符编码是51)
    
    var result3 = "23" < 3;//false
    //在比较字符串和数值时,字符串都会被转换为数值,然后再以数值的形式与另一个数值进行比较
    
    var result4 = "a" < 3;//false
    //由于字母a不能转换为合理的数值,因此被转换成了NaN
    
    var result5 = NaN < 3;//false
    var result6 = NaN >= 3;//false
    //按照常理,如果一个值不小于另一个值,则一定是大于或等于另一个值。在与NaN比较时,都返回了false

     

4. 相等操作符

    4.1 相等(==)、不相等(!=)

    (1)相等(==):若两个操作数相等,则返回true;

    (2)不相等(!=):若两个操作数不相等,则返回true;

    (3)==、!= 操作符均会将操作数先强制转换后再比较其相等性:

转换规则为:

  • 若一个操作输是布尔值,则在比较前先将其转换为数值(false转换为0,true转换为1);
  • 若一个操作数是字符串,另一个操作数为数值,则在比较前先将字符串转换为数值;
  • 若一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较;

比较规则为:

  • null == undefined,在比较相等性之前,不能将null和undefined转换为其他任何值;
  • 若一个操作数是NaN,则 == 操作符返回false,而 != 操作符返回 true;
  • 若两个操作数都是NaN,按照 NaN不等于NaN的规则, == 操作符返回false;
  • 若两个操作数都是对象,则比较它们是不是同一个对象,若均指向同一个对象,则 == 操作符返回true,否则返回false,!= 操作符规则相反;

例:

表达式
null == undefined           true
"NaN" == NaNfalse
5 == NaNfalse
NaN == NaNfalse
NaN != NaNtrue
"5" == 5true
false == 0true
true == 1true
true == 2false
undefined == 0false
null == 0false

    4.2 全等(===)、全不等(!==)

全等(===)操作符表示不仅两个操作数的值相同,类型也相同,而全不等(!==)则表示操作数的值和类型都不相同,即:

  • 当两个操作数不需要进行类型转换就可相等时 全等(===)操作符 返回true;
  • 当两个操作数不需要进行类型转换就不相等时 全不等(!==)操作符 返回true;

例:

var result1 = ("55" == 55);//true,转换后相等
var result2 = ("55" === 55);//false,不转换,字符串不等于数值

var result3 = ("55" != 55);//false,转换后相等
var result4 = ("55" !== 55);//true,不转换,字符串不等于数值

var result5 = (null == undefined);//true,因为它们是类似的值
var result6 = (null === undefined);//false,因为它们是不同类型的值

 

参考链接:

  1. https://blog.csdn.net/qq_41218152/article/details/81562202

  2. https://www.jb51.net/article/122992.htm

  3. https://www.cnblogs.com/MasterYao/p/7783004.html

  4. https://www.cnblogs.com/starof/p/6368048.html

  5. http://www.php.cn/js-tutorial-410318.html

  6. https://www.cnblogs.com/why-not-try/p/7931268.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值