Open super-fool opened 5 years ago
实现Array.map方法
// Array.map(item => {/* return new item;*/}, thisArg): // 将每一个数组元素映射至指定方法(cb),thisArg作为cb中的上下文,最后将返回一组新的数组。 // Note: 1. cb只会在索引上有值的情况下才会去调用,比如:[1,empty,2],只会针对0,2索引调用。 // 2. 第一次调用cb后,数组的长度就已经被确定了,如果在cb中尝试更改数组长度是不会影响新数组的结果,但是会对被调用数组有影响的。 // 3. 如果在cb中delete/modified当前索引后的元素,那么会影响新数组的结果。 var arr = [].concat(new Array(1), Array.of(1), [undefined]); // [empty, 1, undefined] var mapArr = arr.map((item,index)=>{ console.log(index); // index直接从索引1开始调用cb。 return item * 2; } ) console.log('mapArr:%o', mapArr) // index: 1,2 // mapArr: [empty, 2, NaN] /*------------------------------*/ var arr1 = [1, 2, 3, 4]; var mapArr1 = arr1.map((item,index)=>{ console.log(index); if (index === 0) arr1[1] = true; // 证明调用cb的索引值是当前数组最新的值 if (index === arr1.length - 2) delete arr1[arr1.length - 1]; // 删除数组的最后一个值导致下面语句将不会执行 if (index === arr1.length - 1) arr1.length = 5; // 这里将不会被执行,因为上一条语句删除了索引值,而cb不会去调用empty的索引 return typeof item; } ) console.log('arr1: %o', arr1); console.log('mapArr1: %o', mapArr1); // index: 0, 1, 2 // arr1: [1, true, 3, empty] // mapArr1: ["number", "boolean", "number", empty] /*------------------------------*/ var arr2 = [1, 2, 3, 4]; Array.prototype.$map = function(fn, context=self) { let arr = this; let mapArr = new Array(arr.length); for (let i = 0; i < arr.length; i++) { // for( let i in arr){ // 如果使用这里遍历,将会锁定arr数组! console.log('123', arr) if (!arr.hasOwnProperty(i)) continue; mapArr[i] = fn.call(context, arr[i], i, arr); } return mapArr; } var mapArr2 = arr2.$map((item,index,arr)=>{ console.log('index',index) if (index === 0) arr2[1] = true; if (index === arr2.length - 2) { delete arr2[arr2.length - 1]; console.log(arr2) } if (index === arr2.length - 1) arr2.length = 5; return typeof item; } ) console.log('arr2: %o', arr2); console.log('mapArr2: %o', mapArr2);
实现Array.map方法