super-fool / blog

珍藏经典, 分享思想, 共同进步.加油
3 stars 0 forks source link

Array数组总结及实现 #48

Open super-fool opened 5 years ago

super-fool commented 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);