来挑战下你的js基本功,原来以前认为的基础扎实都是空中楼阁。由Array.from引申的知识点。包括数组排序,call,apply,bind。等等。

 以前看过一句话基础的不一定简单,一直没体会到,今天终于见识到了。反思了下自己之前的工作学习,一句话总结,很浮躁。不多说,来个小的例子挑战下。
Array.from()。对你没看错,就是这个简单的api,用来将有length属性的数据结构转换为数组,在转换之前可以使用map对每一个生成的值做处理。看到这里你可能一略而过,很简单吗?不就是转换吗?
那么接下来我来引申几个问题。
问题1:Array.from()的这个api兼容性如何?你会看到ie不兼容。如果你想用怎么办?看看polyfill实现吧。然后polyfill的实现是怎样的过程呐?思路是怎样的?里边又有哪些细节需要你注意呐?我总结下来的有
           1:判断数据类型,我们看Array.from(param,fnc,thisArg)。我们自己来写,我们是不是得首先判断fnc是不是一个函数呐?用到了什么呐?对object.prototype.call(fnc) === "[object,Function]";那么这时候又有问题了如果我要判断所有的数据类型呐?

   2:使用call。我们传入的fnc。如何给她传递进去当前循环的item,index,arr,并且改变fnc中的this为thisArg,这时候用到了call。call不了解?可能你去看下call,发现还有apply,bind。是不是得对比下。然后再看看兼容性?是不是会引申其他问题?

 问题2:Array.from能解决我们实际编程中什么问题呐?基础的将各种带有length属性的类型数据变为数组。这些类型包括哪些呐?set,map,arguments,nodeList, string,甚至{length: 5}。复杂的实现数组合并去重。怎样去重呐?
   

function combine(){ 
    let arr = [].concat.apply([], arguments);  //没有去重复的新数组 
    return Array.from(new Set(arr));
} 

var m = [1, 2, 2], n = [2,3,3]; 
console.log(combine(m,n)); 

这是es6中的去重的简单实现。那么我们要考虑他的性能问题了,时间复杂度,空间复杂度。还有哪些实现去重的方法呐?你是不是得总结下。权衡下执行需要的时间和空间,选择合适的去重方法。
比如,利用一个新数组,或者一个新的对象,依次把每个元素加入到对应的新数组,新对象中。然后判断indexOf(item) != -1加入。!obj[item] 。也可以利用filter。forEach.同样通过indexOf实现。
还有一种靠源生实现的。基本的想法是,判断当前一个和下一个,如果重复了,那么忽略这个元素,取下一个元素,如果没有重复的那么添加到我们创建的新数组。show code

function qc(arr) {
if (object.prototype.toString(arr) != '[object, Array]') {
    throw newError('the qc need Array')
}
var newArr = []
    for(let i=0,len=arr.length;i<len;i++){
      for(let j=i+1;j<len;j++){ 
           // 如果重复,则i向前推进,但不管重复项
            if(arr[i]==arr[j]) j= ++i 
        }
        // 将没有重复项的推入到新数组
        newArr.push(arr[i])
    }
    return newArr

}
原文地址:https://www.cnblogs.com/hjdjs/p/9172429.html