参数是一个数组
返回一个新的数组引用
const arr = [1, 2, 3];
const newArr = Array.from(arr);
console.log(newArr === arr); //false
参数是一个带有引用类型元素的数组
返回的新数组是一个浅拷贝
const arr = [
{
id: 1,
name: '张三',
},
{
id: 2,
name: '李四',
},
{
id: 3,
name: '王五',
},
];
const newArr = Array.from(arr);
console.log(newArr[1] === arr[1]);//true
如果参数是字符串
const str = '123';
const newArr = Array.from(str);
console.log(newArr );//['1', '2', '3']
如果参数是一个Symbol - Array.from 不做处理 并且返回一个空数组
const sm = Symbol('123');
const newArr = Array.from(sm);
console.log(newArr);//[]
如果参数是一个数字 - Array.from 不做处理 并且返回一个空数组
const num = 123;
const newArr = Array.from(num);
console.log(newArr); //[]
如果参数是一个布尔值 - Array.from 不做处理 并且返回一个空数组
const bool = true;
const newArr = Array.from(bool);
console.log(newArr); //[]
如果参数是一个正则 - Array.from 不做处理 并且返回一个空数组
const reg = /123/;
const newArr = Array.from(reg);
console.log(newArr); //[]
null 和 undefined 都会抛出错误
const newArr = Array.from(null);
console.log(newArr);
const newArr = Array.from(undefined);
console.log(newArr);
如果什么都不填 相当于里面填了undefined
const newArr = Array.from();
console.log(newArr);
如果参数是一个普通对象 - Array.from 不做处理 并且返回一个空数组
const obj = {
a: 1,
b: 2,
c: 3,
};
const newArr = Array.from(obj);
console.log(newArr)// []
参数是一个类数组
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike);
console.log(newArr);
总结类数组这种情况
正常返回一个对应的数组的必要条件
1.键名必须从0开始按数字顺序排列
2.length属性必须正确
长度决定了新数组的长度 属性名决定了填充该数组的位置
参数是map
const m = new Map([
['a', 1],
['b', 2],
['c', 3],
]);
console.log(m);
const newArr = Array.from(m);
console.log(newArr);
const s = new Set([1, 2, 3, 4]);
console.log(s);
const newArr = Array.from(s);
console.log(newArr);
回调函数 对数组的遍历 每一次遍历必须返回一个值
进一步对每一个参数进行处理
回调函数 里有两个可选参数item,index
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike, function (item, index) {
console.log(item, index);
return item;
});
console.log(newArr);
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike, function (item, index) {
console.log(item, index);
});
console.log(newArr);
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike, function (item, index) {
return item + 1;
});
console.log(newArr);
由于回调执行的时候 Array.from 还没有执行完毕 所以不存在逻辑上的新数组
所以无法在回调里获取到新数组本身 (有别于数组的其他遍历方法)
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike, function (item, index, arr) {
console.log(item, index, arr);
return item;
});
非严格模式下 回调内部的this -> window
严格模式下 回调内部的this为undefined
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike, function (item, index, arr) {
console.log(this);
return item;
});
'use strict';
const arrLike = {
0: 1,
1: 2,
2: 3,
length: 3,
};
const newArr = Array.from(arrLike, function (item, index, arr) {
console.log(this);
return item;
});
更改回调内的this指向
const newArr = Array.from(arrLike).map(function (item, index, arr) {
console.log(item, index, arr);
return item + 1;
});
console.log(newArr);
虽然Array.from 的第二个参数的执行结果与 在面调用map相同 原理也差不多
但是内部的执行顺序是不同的 Array.from 是在执行的过程中进行遍历 所以获取不到arr
而这种方法 实在Array.from运行结束后才调用map遍历所以可以获取arr
console.log(Array.from.length); //1
const r = range(1, 10, 2);
function range(start, stop, step) {
return Array.from({ length: (stop - start) / step + 1 }, function (item, index) {
return start + index * step;
});
}
console.log(r);//[1, 3, 5, 7, 9]
function combine() {
const arr = Array.prototype.concat.apply([], arguments);
return Array.from(new Set(arr));
}
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [2, 3, 4, 5, 6];
const arr3 = [3, 4, 5, 6, 7];
console.log(combine(arr1, arr2, arr3));//[1, 2, 3, 4, 5, 6, 7]
参数
1.可迭代对象或者类数组
2.mapFn
3.this指向
Array.myFrom = (function () {
const isCallable = function (fn) {
return typeof fn === 'function' || Object.prototype.toString.call(fn) === '[object Function]';
};
const toInt = function (value) {
const v = Number(value);
if (isNaN(v)) {
return 0;
}
if (v === 0 || !isFinite(v)) {
return v;
}
return (v > 0 ? 1 : -1) * Math.floor(Math.abs(v));
};
const maxSafeInt = Math.pow(2, 53) - 1;//最大安全整数
const toLength = function (value) {
const len = toInt(value);
return Math.min(Math.max(len, 0), maxSafeInt);
};
return function (arrayLike) {
const caller = this;
if (arrayLike === null) {
throw new TypeError('Method `from` requires an array-like');
}
const origin = Object(arrayLike);
let arg2;
const mapFn = arguments.length > 1 ? arguments[1] : void undefined;
if (typeof mapFn !== 'undefined') {
if (!isCallable(mapFn)) {
throw new TypeError('mapFn must be a function');
}
if (arguments.length > 2) {
arg2 = arguments[2];
}
}
const len = toLength(origin.length);
const arr = isCallable(caller) ? Object(new caller(len)) : new Array(len);
let i = 0,
val;
while (i < len) {
val = origin[i];
if (mapFn) {
arr[i] = typeof arg2 === 'undefined' ? mapFn(val, i) : mapFn.apply(arg2, [val, i]);
} else {
arr[i] = val;
}
i++;
}
return arr;
};
})();
Array.from 的第一个参数必须要是可迭代对象或者是标准的类数组