两个空数组相加结果为何是空字符串

显然,两个空数组都转化为了空字符串。

Q1:为何会转换为字符串?
Object.prototype.toString() toString()方法返回一个表示该对象的字符串。

pic

数组本来就是对象,然而b转成了”[object Object]”c却是””

A:数组的默认toString()方法经过了重新定义,将所有的字符串化以后再用“,”连接起来

let a = [1,2,3]
a.toString() // "1,2,3"
let b = [[1,2],[3,4],[5,[6,7]]]
// "1,2,3,4,5,6,7"

Q2: 为何是强制转换为string而不是number或其他?

A: pic

因为Array没有toNumber方法。
同样Object也没有
pic

另外需要注意的是使用Object.create(null) 创建的对象原型属性为null,并且没有valueOf()和toString()方法,因此无法进行强制类型转换。

如何判断是数组

instanceof

检测对象的原型链是否指向构造函数的prototype对象的

let a = []
a instanceof Array //true

对象的constructor属性

a.constructor === Array

可参考第二张图片

但是跨frame实例化的对象彼此是不共享原型链的

Object.prototype.toString()

[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这 个方法,再配合call,我们可以取得任何对象的内部属性[[Class]]。

参考第一张图片

Array.isArray()

用于确定传递的值是否是一个Array.

当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.

Polifill

假如不存在 Array.isArray(),则在其他代码之前运行下面的代码将创建该方法。

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

当然也可以不创建,如下测试:

if (typeof Array.isArray === "function") {
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value) === "[object Array]";
}

数组扁平化

参考第一段示例代码 可知调用 arr.toString()

ES6 数组的扩展 flat(), flatMap()

flat,flatMap

数组的方法

不改变原数组(8个)

ES5:

join, toLocaleString, toString, slice, concat, indexOf, lastIndexOf

ES6:

includes

改变原数组(9个)

ES5:

splice, sort, pop, shift, push, unshift, reverse

ES6:

copyWithin, fill

遍历方法(12个)

ES5:

forEach, every, some, filter, map, reduce, reduceRight

ES6:

find, findIndex, keys, values, entries