一、数组toString方法的执行过程
Array原型对象上的toString方法与Object.prototype上的toString方法不同,它进行了重写。Array.prototype.toString会先查看执行时上下文
(this)及其原型链上是否具有join
方法。
- 若
join
方法存在则会在内部执行join
方法,类似this.join(',')
。 - 若
join
方法不存在则会调用Object.prototype.toString
方法。
我们通过一个简单的例子便可以验证:
// eg1:
console.log(Array.prototype.toString.call({ join: () => 1 })); // 1
// eg2:
console.log(Array.prototype.toString.call({ join: () => undefined })); // undefined
// eg3:
console.log(Array.prototype.toString.call({ join: 'not a function' })); // [object Object]
上述的第一个例子是如何得到结果1
的呢?首先我们要注意到上述的代码将toString
的执行时上下文绑定为具有join
方法的对象,那么 按照上述的执行过程,将执行第一步:执行执行时上下文中的join
方法,此时得到join
方法的执行结果1
,也就是该行代码的结果。
第二个例子可以更有力的证明,Array的原型对象将优先执行join
方法,而从第三个例子则可以验证上述的第二个过程,此时的join
并不是一个方法,因此将调用Object.prototyp.toString
方法。
二、利用join的"数组扁平化"
比较有意思的是我们发现使用数组的join
方法能够扁平化一些高维的数组(注意:数组中只能存放基础数据类型!!)为字符串。先举个例子吧:
[1, [2, [3, [4, [5]]]]].join(","); //'1,2,3,4,5'
上述的例子我们将一个高维度的数组转为了一串一维的字符串,如果当我们知道数组中的元素全都为同一个类型时完全可以利用join
完成一个简单的扁平化操作:
[1, [2, [3, [4, [5]]]]].join(",").split(",").map(Number); // [1, 2, 3, 4, 5]
当然了,这样的写法缺陷太大了,首先你得明确元素的类型都为同一个元素、且不能有引用类型的属性存在,否则将以[object Object]
的形式出现在结果中。
细心的小伙伴在这里应该能猜到为什么使用join
能够将一个高维度的数组转为一串简单字符,这是因为join
的执行时会将每一个元素都先转为String
的形式,因此对于引用类型将执行其身上的toString
方法,而在前文提到了数组的toString
方法本质上是调用的join
方法,那么这就形成了一个"小递归"。过程如下:
[1, [2, [3, [4, [5]]]]].join(", ")
=> "1, " + [2, [3, [4, [5]]]].toString()
=> "1, " + "2, " + [3, [4, [5]]].toString()
=> "1, 2, " + "3, " + [4, [5]].toString()
=> "1, 2, 3, " + "4, " + [5].toString()
=> "1, 2, 3, 4, " + "5"
=> "1, 2, 3, 4, 5"
这样我们将一个高维数组扁平成了一个基础字符串,当然将外层的join修改为toString同样可行。这一小节的"扁平化"并不推荐使用到项目中去,因为Array.prototype上有一个专门的扁平化方法flat
,是由JS内部引擎优化过的代码,性能上远远优于本节中的"错误"方式。文章来源:https://www.toymoban.com/news/detail-497412.html
三、总结
本文主要探究了数组原型上的toString
方法的内部执行过程,以及使用简单的例子来验证这个过程。并通过一个"扁平化"的小例子基础的了解了join
方法的执行过程。文章来源地址https://www.toymoban.com/news/detail-497412.html
到了这里,关于[阅读MDN]之Array.prototype.toString的过程探究的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!