【JavaScript面试】isArray() 、Array.of()、Array.from() 方法

isArray()

定义和用法

isArray() 方法用于判断一个对象是否为数组。

如果对象是数组返回 true,否则返回 false。

语法

Array.isArray(obj)
参数

object:要检测的内容

返回值:

返回值是布尔类型的。
如果传进来的object是数组,返回true,如果不是数组,则返回false。

举例

 
Array.isArray([1, 2, 3, 4]);  // --> true
 
var obj = {
    a: 1,
    b: 2
};
Array.isArray(obj);  // --> false
 
Array.isArray(new Array);  // --> true
 
Array.isArray("Array");  // --> false

注意:Array.isArray是ES 5.1推出的,不支持IE6~8,所以在使用的时候也应注意兼容问题。

Array.of()

Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。

Array.of() 和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个长度为 7 的空数组(注意:这是指一个有 7 个空位 (empty) 的数组,而不是由 7 个undefined组成的数组)。

Array.of(7);       // [7]
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

语法

Array.of(element0[, element1[, ...[, elementN]]])

参数

elementN
任意个参数,将按顺序成为返回数组中的元素。

返回值

新的 Array 实例。

Array.of()方法的使用:

Array.of()方法用于将一组数值转换为数组

const a = Array.of(2,4,6,8);
console.log(a);         // [2,4,6,8]

const b = Array.of(1);
console.log(b);         // [1]

const c = Array.of(1).length;
console.log(c);         // 1

Array.of()可以用以下的代码模拟实现:

function ArrayOf() {
    return [].slice.call(arguments);
}

Array.from()

Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

语法

Array.from(arrayLike[, mapFn[, thisArg]])

参数

  • arrayLike:必传参数,想要转换成数组的伪数组对象或可迭代对象。
  • mapFn:可选参数,mapFunction(item,index){…} 是在集合中的每个项目上调用的函数。返回的值将插入到新集合中。
  • thisArg:可选参数,执行回调函数 mapFunction 时 this 对象。这个参数很少使用。

返回值

一个新的数组实例。

例子

//从 String 生成数组
Array.from('foo');
// [ "f", "o", "o" ]

//从 Set 生成数组
const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// [ "foo", "bar", "baz" ]

//从 Map 生成数组
const map = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(map);
// [[1, 2], [2, 4], [4, 8]]

const mapper = new Map([['1', 'a'], ['2', 'b']]);
Array.from(mapper.values());
// ['a', 'b'];

Array.from(mapper.keys());
// ['1', '2'];


//从类数组对象(arguments)生成数组
function f() {
  return Array.from(arguments);
}

f(1, 2, 3);

// [ 1, 2, 3 ]

Array.from() 五个超好用的用途

Array.from() 五个超好用的用途

  • 将类数组转换成数组

Array.from(arguments) 将类数组对象 arguments 转换成一个数组,然后使用数组的 reduce 方法求和。

function sumArguments() {
    return Array.from(arguments).reduce((sum, num) => sum + num);
}
sumArguments(1, 2, 3); // => 6
  • 克隆一个数组
    在 JavaScript 中有很多克隆数组的方法。正如你所想,Array.from() 可以很容易的实现数组的浅拷贝。
const numbers = [3, 6, 9];
const numbersCopy = Array.from(numbers);

numbers === numbersCopy; // => false

Array.from(numbers) 创建了对 numbers 数组的浅拷贝,numbers === numbersCopy 的结果是 false,意味着虽然 numbers 和 numbersCopy 有着相同的项,但是它们是不同的数组对象。

   let arr = [1, [2, [3, 4, 5]]];
        let arr2 = Array.from(arr);
        console.log(arr2); //[1, [2, [3, 4, 5]]]这个毋庸置疑
        arr[0] = 200; 
        console.log(arr);//此时 arr=[200, [2, [3, 4, 5]]]
        console.log(arr2);//此时 arr2=[1, [2, [3, 4, 5]]]

下面两个输出打印的结果如下:
在这里插入图片描述
由上面输出我们可以看出arr的第一层改变了,arr1的第一层并没有改变,说明只有一层的时候,是深拷贝。接着我们

 let arr = [1, [2, [3, 4, 5]]];
        let arr2 = Array.from(arr);
        // console.log(arr2); //[1, [2, [3, 4, 5]]]这个毋庸置疑
        arr[0] = 200;
        // console.log(arr);  //此时 arr=[200, [2, [3, 4, 5]]]  
        // console.log(arr2); //arr2=[1, [2, [3, 4, 5]]]
        arr[1][1] = 100;
        console.log(arr);  //此时 arr=[200, [2, 100]]  
        console.log(arr2); //arr2=[1, [2, 100]]

在这里插入图片描述
由此我们可以看出
arr的第二层为 [2, [3, 4, 5]]===>[2,100]
arr2的第2层是浅拷贝,所以arr改变,arr2也改变
综上:这就是浅拷贝的含义,只能复制第一层的地址,核心算法没有递归,所以就拷贝一层。深拷贝核心算法会递归,会拷贝每一层。

这就回到最初为什么下面这个双等和三等都是false,因为只有一层的话是深拷贝,拷贝之后就不共享同一块内存地址,最后引用类型是否相等对比的是地址,所以最后双等和三等均为false

    const numbers = [3, 6, 9];
    const numbersCopy = Array.from(numbers);
    console.log(numbers === numbersCopy); // => false
    console.log(numbers == numbersCopy); //=>false

  • 使用值填充数组
    我们来定义一个函数,创建一个填充相同默认值的数组:
const length = 3;
const init   = 0;
const result = Array.from({ length }, () => init);
result; // => [0, 0, 0]

result 是一个新的数组,它的长度为3,数组的每一项都是0。调用 Array.from() 方法,传入一个类数组对象 { length } 和 返回初始化值的 mapFunction 函数。

当初始化数组的每个项都应该是一个新对象时,Array.from() 是一个更好的解决方案:

const length = 3;
const resultA = Array.from({ length }, () => ({}));
const resultB = Array(length).fill({});

resultA; // => [{}, {}, {}]
resultB; // => [{}, {}, {}]

resultA[0] === resultA[1]; // => false
resultB[0] === resultB[1]; // => true

由 Array.from 返回的 resultA 使用不同空对象实例进行初始化。之所以发生这种情况是因为每次调用时,mapFunction,即此处的 () => ({}) 都会返回一个新的对象。

  • 生成数字范围
function range(end) {
    return Array.from({ length: end }, (_, index) => index);
}

range(4); // => [0, 1, 2, 3]

在 range() 函数中,Array.from() 提供了类似数组的 {length:end} ,以及一个简单地返回当前索引的 map 函数 。这样你就可以生成值范围。

  • 数组去重
    由于 Array.from() 的入参是可迭代对象,因而我们可以利用其与 Set 结合来实现快速从数组中删除重复项。
function unique(array) {
  return Array.from(new Set(array));
}
unique([1, 1, 2, 3, 3]); // => [1, 2, 3]

首先,new Set(array) 创建了一个包含数组的集合,Set 集合会删除重复项。

因为 Set 集合是可迭代的,所以可以使用 Array.from() 将其转换为一个新的数组。

这样,我们就实现了数组去重。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵有千堆雪与长街

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值