其实JavaScript 加法运算深度解析的问题并不复杂,但是又很多的朋友都不太了解,因此呢,今天小编就来为大家分享JavaScript 加法运算深度解析的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
一、JS中的类型
基本类型JS 的基本类型包括Undefined、Null、Boolean、Number 和String。 Undefined类型和Null类型都只有一个值,即undefined和null; Boolean类型有两个值:true和false; Number 类型有很多很多值;而String类型理论上有无数的值。值类型JS中的值包括原始类型(Primitive)和对象类型(Object)。在进行加法等操作时,非原始类型的必须先转换为原始类型,然后才能进行相关操作。
二、JS中的加法运算
1. 使用ToPrimitive 操作将左右操作数转换为原始数据类型(primitive)。
2、转换后,如果其中一个操作数的原始数据类型是“字符串”值,则另一个操作数将被强制转换为字符串,然后进行字符串串联操作。
3.其他情况下,所有操作数都会转换为原始数据类型的“number”类型值,然后将数字相加。
三、ToPrimitive内部运算
加号运算符只能用于原始数据类型。对于对象类型的值,需要进行数据转换。在ECMAScript中,有一个抽象的ToPrimitive操作,用于将对象转换为原始数据类型。它用于对象相加、关系比较或值相等比较等操作。
关于ToPrimitive的说明语法:ToPrimitive(input, PreferredType?) input 表示替换值。 PreferredType 可以是数字(Number),也可以是字符串(String),表示首先需要转换的原始类型。但如果未提供此值(这是默认情况),则转换后的提示值将设置为“默认”。这个转换原始类型的首选指令(提示值)是JS在内部转换时自动添加的,一般是默认值。
在JS的Object原型设计中,有两个方法,valueOf和toString。在对象的数据类型转换过程中,它们的调用顺序会根据传入的值进行调整。
PreferredType为数字(Number)时当PreferredType 为Number(数字)时,输入为要转换的值,转换输入值的步骤为:
1.如果输入是原始数据类型,则直接返回输入。
2、否则,input是一个对象,调用valueOf()方法,如果能获取到原始数据类型的值,则返回该值。
3、否则,input是一个对象,调用toString()方法,如果能获取到原始数据类型的值,则返回该值。
4. 否则,抛出TypeError。
PreferredType为字符串(String)时1. 如果输入是原始数据类型,则直接返回输入。
2.否则,input是一个对象,调用toString()方法,如果能获取到原始数据类型的值,则返回该值。
3.否则,input是一个对象,调用valueOf()方法,如果能获取到原始数据类型的值,则返回该值。
4. 否则,抛出TypeError。
PreferredType未提供(default)时PreferredType 默认类型是Number,所以先调用valueOf(),然后调用toString()。
比较特殊的是Date 对象和Symbol 对象,它们会覆盖原始的PreferredType 行为。 Date 对象的默认首选类型是String。
四、valueOf()和toString()
valueOf()和toString()是Object上的两个方法,但在JS中,根据Object之间的差异,返回值可能会有所不同。
普通的Object对象valueOf():返回对象本身。
toString():"[object Object]"字符串值,不同内置对象的返回值为"[object type]"字符串,"type"指对象本身的类型标识,例如Math对象返回"[对象数学]"字符串。但是,某些内置对象在直接调用时没有此值,因为它们重写了此方法。 (注意,返回字符串:前面的英文单词“object”是小写,后面的英文单词是大写)。在Object中使用toString判断各种对象语法:
Object.prototype.toString.call([])
"[对象数组]"
Object.prototype.toString.call(新日期)
"[object Date]"需要配合call才能得到正确的对象类型值。
Array(数组)Array虽然是对象类型,但其设计与Object不同。它的toString被覆盖了。请解释一下数组:的valueOf和toString这两个方法的返回值
valueOf():返回对象本身
toString():相当于使用数组值调用join(",") 返回的字符串。即[1,2,3].toString()将是"1,2,3",请特别注意这一点。
Function对象Function对象很少使用,而且它的toString也被覆盖了,所以不是Object中的toString。 Function对象的valueOf和toString两个方法的返回值为:
valueOf():返回对象本身
toString():返回函数中包含的代码被转换为字符串值。
Date对象valueOf():返回转换为UNIX 时间的给定时间(自1970 年1 月1 日起00:00:00 UTC),但作为以微秒为单位的数值
toString():返回本地化时间字符串
五、Number、String、Boolean包装对象
JS包装对象必须使用new关键字进行对象实例化,直接使用Number()、String()、Boolean()这三个强制转换函数。例如new Number(123),Number("123")就是强制将其他类型转换为数字类型的函数。
包装对象包装对象是JS针对数字、字符串、布尔等原始数据类型专门设计的对象。包装对象的valueOf和toString这两个方法在原型上都被重写了,所以它们的返回值和一般Object的设计是一样的。不同:
valueOf方法返回值:对应的原始数据类型值
toString方法返回值:对应原始数据类型值,转换为字符串类型时的字符串值
toString 方法很特殊。这三个包对象中toString的详细信息如下:
1、Number包对象的toString方法:可以有一个参数来确定转换为字符串时的进位(2/8/16)
2、String包装对象的toString方法:返回的结果与String包装对象中的valueOf相同。
3.布尔包装对象的toString方法:返回"true"或"false"字符串
强制转换Number()、String()、Boolean()这三个强制转换函数对应ECMAScript标准中ToNumber、ToString、ToBoolean这三个内部运算转换的对照表。
通过ToNumber()将值转换为Number:
参数结果undefinedNaNnull+0booleantrue转换为1,false转换为+0number,不进行转换。字符串从字符串解析为数字。例如,使用ToString() 将“324”转换为324,将该值转换为字符串:
参数result undefined "undefined" null "null" boolean "true" 或"false" number 字符串形式的数字。例如“1.765”字符串不需要转换
六、从实例中理解
运算元其一为字符串(String)/**
* 操作数之一是字符串(String)
*/
console.log("12"+1); //121
console.log("abc"+"def"); //abcdef
console.log("1"+true); //1true
console.log("1"+未定义); //1未定义
console.log("1"+null); //1null操作数之一是字符串,即字符串的串联操作。
运算元其一为数字(Number)/**
* 操作数之一是数字(Number)
*/
控制台.log(1+1); //2
console.log(1+"def"); //1def
控制台.log(1+true); //2
控制台.log(1+未定义); //NaN
控制台.log(1+null); //11+"def"表示操作数之一是字符串,其余表示如果没有字符串,操作数之一是数字,类型转换后相加。
数字(Number)/字符串(String)以外的原始类型相加/**
* 添加除Number/String 之外的基本类型
*/
控制台.log(true+true); //2
控制台.log(true+null); //1
console.log(true+未定义); //NaN
console.log(未定义+null); //NaN
console.log(未定义+未定义); //NaN
console.log(null+null); //0除数字和字符串之外的其他原始数据类型直接使用加号运算时,都是转换为数字再进行操作,与字符串无关。
空数组 + 空数组console.log([] + []); //""将两个数组相加,左右操作数先调用valueOf(),返回数组本身,调用toString(),返回原始数据类型,即空字符String,进行串联操作,得到一个空字符串。
空对象 + 空对象console.log({} + {}); //"[object Object][object Object]" 添加两个对象。左右操作数先调用valueOf(),返回对象本身,再调用toString(),返回原始数据类型,即对象字符串[object Object],进行连接操作,得到字符串[object Object] ][对象对象]
Console.log({}+{}) 获取此结果。但是,如果在某些浏览器(例如Firefox 和Edge 控制台)中直接输入{}+{},则会得到NaN,因为浏览器会将{} + {} 直译为相当于+{} 语句,因为它们会认为大括号({)是从一个块语句开始的,而不是一个对象字面量,因此他们会认为第一个{}被跳过,整个语句被认为是一个+{}语句,这相当于Number({})函数调用操作,强制计算数值,相当于Number("[object Object]")操作,最终结果为NaN。通过添加括号({}) + {} 可以避免此问题。
空对象 + 空数组console.log({} + []); //"[object Object]" 添加空对象和空数组。左右操作数先调用valueOf(),返回对象数组本身,调用toString(),返回Primitive数据类型,即对象string[object Object]和"",进行串联操作得到string[object目的]
直接console.log会得到同样的值,但是在浏览器控制台直接输入:
{} + []
0
[] + {}
"[object Object]"{} + [] 相当于+[] 语句,相当于强制计算数值的Number([]) 操作。相当于Number("")运算,最终结果为0数字。
Date对象console.log(1 + (新日期())); //"1Tue Aug 14 2018 21:18:24 GMT+0800 (China Standard Time)" Date 对象的首选类型是String。首先调用toString()来获取字符串。字符串连接操作。
要获取Date对象中的valueOf返回值,需要使用一元加号(+)强制其为数字类型,如下面的代码:
console.log(+new Date());
1534298171747Symbols类型ES6中新添加的Symbols数据类型既不是一般值也不是对象。它没有内部自动变换设计,所以不能直接用于加法运算,使用时会报错。
+[]/+{}控制台.log(+[]); //0
控制台.log(+{}); //南
控制台.log(+null); //0
好了,关于JavaScript 加法运算深度解析和的问题到这里结束啦,希望可以解决您的问题哈!
【JavaScript 加法运算深度解析】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
原来 JavaScript 加法运算还能这样总结,好好学习一下!
有9位网友表示赞同!
这下终于明白怎么计算数值和字符串了,感谢分享。
有14位网友表示赞同!
好详细的文章,把所有细节都分析清楚。
有15位网友表示赞同!
看标题就知道全方位讲解加法运算,收藏起来慢慢读。
有15位网友表示赞同!
之前做项目遇到加法不兼容的问题经常卡壳,学习这些知识很有用!
有13位网友表示赞同!
JavaScript 学习笔记里少不了这个基础的内容,方便查阅。
有5位网友表示赞同!
希望文章还讲解下减法、乘法和除法的运算规则,这样就更全面了。
有20位网友表示赞同!
看不懂的代码直接来看看解析,好帮手!
有17位网友表示赞同!
这篇文章肯定是我学习 JavaScript 加法运算的不二选择。
有11位网友表示赞同!
分享这么详细的文章,太厉害了!
有20位网友表示赞同!
一定要认真读一遍,加深对 JS 加法运算的理解。
有11位网友表示赞同!
学习码农的必修课,感谢作者的讲解!
有13位网友表示赞同!
之前写代码的时候总是忽略一些细节,这下明白了!
有15位网友表示赞同!
希望文章还有练习题,这样能加深记忆效果。
有17位网友表示赞同!
JS 加法运算看似简单,但掌握其中的规律很重要!
有18位网友表示赞同!
推荐给正在学习 JavaScript 的朋友们。
有17位网友表示赞同!
终于不需要再看别人写的代码问加法怎么运作了!
有18位网友表示赞同!
学习完这篇解析,就能更轻松地写 js 加法运算了。
有17位网友表示赞同!
点赞!把JS加法运算解释得清清楚楚!
有7位网友表示赞同!