首页  >  问答  >  正文

javascript - js对象的hasOwnProperty为什么比数组的indexof方法在性能上高的多?

如题,简单的数组去重:

Array.prototype.delRepeat1 = function () {
        var n = []; //一个新的临时数组
        for (var i = 0; i < this.length; i++) //遍历当前数组
        {
            //如果当前数组的第i在临时数组已有,跳过,否则把当前项push到临时数组里
            if (n.indexOf(this[i]) == -1) n.push(this[i]);
        }
        return n;
    }
    
Array.prototype.delRepeat2 = function () {
        var temp = {}, len = this.length;
        for (var i = 0; i < len; i++) {
            var tmp = this[i];
            if (!temp.hasOwnProperty(tmp)) {//hasOwnProperty用来判断一个对象是否有你给出名称的属性或对象
                temp[this[i]] = "yes";
            }
        }
 
        len = 0;
        var tempArr = [];
        for (var i in temp) {
            tempArr[len++] = i;
        }
        return tempArr;
    }
    
    

经测试方法二比方法一的性能高出近百倍?对象遍历key值为何与数组遍历元素差别如此巨大?

PHPzPHPz2770 天前1025

全部回复(4)我来回复

  • ringa_lee

    ringa_lee2017-04-10 17:37:09

    indexOf对数组中的每一个元素偏离查询,数组长度越长,需要检查的长度就越长,时间就越久
    hasOwnProperty对对个一个对象的非继承属性的的检查,数组的下标值就是数组对象的属性,一个对象的属性值及对应的值存储为一个hash数据结构

    通过hash查找一个值的速度快于对一个线性数组的查找~~~~

    回复
    0
  • 巴扎黑

    巴扎黑2017-04-10 17:37:09

    这个原因就是算法复杂度的问题了,其实你的delRepeat1方法的复杂度是n的平方的,从底层来看,因为indexOf()的实现方法就是循环,然后遇到相同的返回索引值,否则返回-1,所以算法时间复杂度高,自然就耗时长了。

    回复
    0
  • 高洛峰

    高洛峰2017-04-10 17:37:09

    第二种改成:

    Array.prototype.delRepeat2 = function () {
            var temp = {}, len = this.length;
            for (var i = 0; i < len; i++) {
                var tmp = this[i];
                
                temp[this[i]] = "yes";
                
            }
            return Object.keys(temp);
    }

    回复
    0
  • 迷茫

    迷茫2017-04-10 17:37:09

    我的理解:

    1. indexOf:是数组的元素存在性检查方法。需要遍历所有元素来检查,此方法的时间复杂度是O(n)

    2. hasOwnProperty:是对象的属性(名称)存在性检查方法。对象的属性可以基于Hash表实现,因此对属性进行访问的时间复杂度可以达到O(1)

    所以很明显,后者可以远快于前者。

    注:换个角度:JS中的数组本质上也是对象,也是键值对。但是数组看作对象时,其属性名就是数组的索引,即12这些。而indexOf相当于对属性值(即数组元素)的查找。属性名是哈希过的,可以达到O(1);而属性值只能遍历,只能达到O(n)

    回复
    0
  • 取消回复