IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> “空对象 {}” 与 “空数组 []” 的相加问题(详解!!!) -> 正文阅读

[JavaScript知识库]“空对象 {}” 与 “空数组 []” 的相加问题(详解!!!)

本文旨在让读者能更加清晰地了解 “空对象 {}” 与 “空数组 ()” 相加(eg:“[] + []” 、“[] + {}”、“{} + []”、“{} + {}”)得到结果的隐式转换过程,还望读者能仔细阅读完,相信或多或少会有所收获 !

首先来了解一些相关知识

一、在 JavaScript 中,一共有两种类型的值:

  1. 原始值(primitives)
    undefined、null、boolean、number、string
  2. 对象值(objects)
    除了原始值外,其他的所有值都是对象类型的值,包括数组(array)和函数(function)。

二、“加号 +” 的运算原理( “+” 既是一元运算符,也是二元运算符)

1. 一元运算符

说明:’+’ 号运算符作为一元运算符时,表达式将进行 ToNumber() 操作。

① ToNumber(argument) 转换方式:

argument类型返回值
Undefinedreturn NaN
Nullreturn 0
Booleantrue return 1; false return 0;
Numberreturn value
String若字符串为纯数字,返回转换后的数字;非纯数字则返回 NaN
Symbol抛出 TypeError 异常
Object进行如右步骤:1.先进行 ToPrimitive(argument, hint Number) 得到 rs ;?2.然后返回 ToNumber(rs) 的结果。

② 示例:

	// Undefined
	+ undefined; // => NaN
	 
	// Null
	+ null; // => 0
	 
	// Boolean
	+ true; // => 1
	+ false; // => 0
	 
	// String
	+ '1'; // => 1
	+ '-1'; // => -1
	+ 'a1'; // => NaN
	 
	// Object
	+ []; // => 0
	+ {}; // => NaN
	+ { valueOf: function () { return 0 } }; // => 0
	/*
	*	该对象重写了 valueOf() 方法,
	*	因此该对象隐式转换过程中调用 valueOf() 方法后得到 0,
	*	故最终结果为 0
	*/ 

2. 二元运算符

① 运算元其一为字符串(String)

??运算元其一为字符串时,进行字符串的拼接操作。

	console.log('10' + 1);          //	101
	console.log('ab' + 'cd');       //	abcd
	console.log('1' + true);        //	1true
	console.log('1' + undefined);   //	1undefined
	console.log('1' + null);        //	1null

② 运算元其一为数字(Number)

??1 + ‘cd’ 为运算元其一为字符串情况,做字符串拼接操作;其余为在没有字符串情况下,运算元其一为数字,做类型转换后做数值相加。

	console.log(1 + 1);            //	2
	console.log(1 + 'cd');        //	1cd
	console.log(1 + true);         //	2
	console.log(1 + undefined);    //	NaN
	console.log(1 + null);         //	1

注:在运算元一侧为数字,另一侧为字符串的情况下,如果是 “减号 - ” 或其他运算符(eg:“*”、“/”、“%”、“ >”、“<”、“==”) 的话,会将字符串转换为数字进行减法操作(eg:数字相减:10 - “1” = 9)。

③ 数字(Number) / 字符串(String) 以外的原始类型相加

??当数字与字符串以外的其他原始数据类型直接使用加号运算时,要先转为数字(可参考上面有关 “ToNumber(argument) 转换方式” 的表格)再运算,这与字符串完全无关。

	console.log(true + true);             // 2
	console.log(true + null);             // 1
	console.log(true + undefined);        //NaN
	console.log(undefined + null);        //NaN
	console.log(undefined + undefined);   //NaN
	console.log(null + null);            //0

④ 运算元其一为复杂数据类型(以下为初步解释,示例请见后续第三大点)

注意,以上 ① ~ ③ 的示例均是原始数据类型的 “加法 +” 操作,当进行复杂数据类型的 “加法 +” 操作时,JS 内部有以下有隐式转换过程(实际上是 JS 调用了内部的 toPrimitive() 方法,有关该方法详见 JS原始值转换算法—toPrimitive() ):
??Ⅰ 当 “加号 +” 的某一侧数据类型是对象时,会将对象先进行 valueOf() 操作(有关 valuOf() 方法可参考博文 JS 中 valueOf() 方法的详解);
??Ⅱ 如果返回的是原始数据类型,则后续操作按照以上三点进行;
??Ⅲ 如果返回的值还是对象,则再调用 toString 方法(此处应了解 “ [] 调用 toString() 方法变成空字符串 "",{} 调用 toString() 等于 [object Object] ,有关 toString 方法详解可参考 javascript中的toString方法);
??Ⅳ 若返回原始数据类型,则按照上面原始数据类型计算;
??Ⅴ 否则报错。

⑤ 有关 NaN 需要注意的点

??Ⅰ. 执行运算时 , 非带 “+” 号的运算,只要有 NaN 参与,执行结果就都是 NaN;
??Ⅱ. 如果是带 “+” 号的运算,一侧是 NaN、另一侧是字符串时,就执行字符串拼接操作;
??Ⅲ. 如果是带 “+” 号的运算,一侧是 NaN、另一侧是 Number 类型的数值时,执行结果就都是 NaN;
??Ⅳ. 在 JavaScript 中的规定,NaN 表示的是非数字,但是这个非数字也是不同的;因此 NaN 不等于 NaN,两个 NaN 永远不可能相等。
注:NaN 虽然不是一个具体数值,但数据类型确是 Number 类型;NaN 和任何 Number 类型数据进行 “+”、“-”、“*”、“/”、“% 等操作时,操作结果都是 NaN。

三、“空对象 {}” 与 “空数组 []” 的相加问题

1. 空数组 + 空数组

空对象 + 空对象
隐式转换过程: 首先 [] 调用 valueOf() 方法,得到的还是 [],然后调用 toString() 方法,得到 "",两个 "" 相加还是 "",故最终结果为 ""


2. 空数组 + 空对象

空数组 + 空对象
隐式转换过程: 如第一点分析,[] 经隐式转换最终得到 ""{} 调用 valueOf() 方法,得到的还是 {},然后调用 toString() 方法,得到 "[object Object]""""[object Object]" 相加得到 "[object Object]",故最终结果为 "[object Object]"


3. 空对象 + 空对象

空对象 + 空对象
隐式转换过程: 分析与上面类似,此处不再累赘


4. 空对象 + 空数组

空对象 + 空数组
补充有关知识:
??首先要知道 javascript 有这样的特性,如果 {} 既可以被认为是代码块,又可以被认为是对象字面量,那么 js 会把他当做代码块
??而在浏览器中,如果 {} 在前面,而 [] 在后面时,前面的 {} 会被认为是区块语句而不是对象字面量;
??故此处的 {} + [] 可看成 + [],然后参考上面有关 “ToNumber(argument)转换方式” 的表格中 argument 类型为 Null 和 Object 的两行,对本例进行分析。

隐式转换过程:
??① 参考表格中 argument 类型为 Object 的一行,对于 + [] 来说,对 [] 进行 ToPrimitive(argument, hint Number) 操作【可参考第二大点的第二小点最下方的注释】,先对 [] 调用 valueOf() 方法,得到的还是 [],然后调用 toString() 方法,得到 ""
??② 参考表格中 argument 类型为 Null 的一行,故 + "" 返回的是 0 。
?综上,最终 {} + [] 得到的结果是 0


5. !空数组 + 空数组

 !空数组 + 空数组
补充有关知识:
运算符优先级和结合性
??根据运算符优先级 , ! 的优先级是大于 + 的,所以先会执行 ![] ;
??! 可将变量转换成 boolean 类型,且除 nullundefinedNaN 以及 "" 取反为 true 外,其余运算元取反都为 false 。

隐式转换过程:
??① 根据以上分析,先执行 ![] ,得到 false
??② [] 经隐式转换最终得到 ""
??③ 参考第二大点的第二小点中的示例(如下),可知 false + "" 的结果为 "false"

console.log('1' + true);        //	1true

6. !空数组 + 空对象

 !空数组 + 空对象
隐式转换过程:
??① 执行 ![] ,得到 false
??② {} 经隐式转换得到 "[object Object]"
??③ 可知 false + "[object Object]" 的结果为 "false[object Object]"


7. !空对象 + 空对象

在这里插入图片描述
隐式转换过程:
??① 执行 !{} ,得到 false
??② {} 经隐式转换得到 "[object Object]"
??③ 可知 false + "[object Object]" 的结果为 "false[object Object]"


8. !空对象 + 空数组

在这里插入图片描述
隐式转换过程:
??① 执行 !{} ,得到 false
??② [] 经隐式转换得到 ""
??③ 可知 false + "" 的结果为 "false"


整理不易,本文各方面讲的比较详细,也附上了有关知识的链接,如果各位读者读完本文章觉得有收获的话,还望点个赞,万分感谢 ! ! ! ! !

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:16:46  更:2021-08-21 15:17:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:18:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码