JavaScript中“数组也是对象”

先说结论吧:

数组的map要领在IE9以下是不支持的,因而需要写一个兼容要领来完成此行动,在完成兼容的时刻:必需注重:关于数组中被删除(delete)或许基础从未赋值的索引项,map中第一个函数参数是不会实行的。

关于这一点,在ECMA规范MDN参考文档都是有申明的:

MDN:
it is not invoked for indexes that are undefined, those which have been deleted or which have never been assigned values.

ECMA:
callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

我看到一些用来兼容的要领,都没有注重到这类状况,那末不注重这类状况会涌现什么题目呢?为何MDN上给的兼容要领会这么迂回呢?

我先把我在培训班的先生给出的兼容要领贴出来:

javascriptArray.prototype.myMap = function (fn, context) {
    context = context || window;
    var ary = [];
    if (Array.prototype.map) {
        ary = this.map(fn, context);
    } else {
        for (var i = 0; i < this.length; i++) {
            ary[i] = fn.apply(context, [this[i], i, this]);
        }
    }
    return ary;
}

这个完成比较简朴,流程很清楚,假如浏览器有原生数组map要领,挪用该要领,不然实行else中的语句;然则假如是下面如许一个数组,在没有完成原生map要领的浏览器中,效果跟原生map要领挪用不一样:

javascriptvar arr=[1,2,,,3];
console.dir(arr.myMap(function(e,i,a){return e*2;}));

原生map要领实行上述代码的输出是
《JavaScript中“数组也是对象”》

而假如浏览器不支持原生map要领,会实行else语句,如许的输出是:
《JavaScript中“数组也是对象”》

你看,这两者实行区分就在于一开始的结论:原生的map要领跳过了那些从未赋值的索引对应的项。

数组也是对象!!

简朴来讲,对象就是一系列属性名值对,即某个属性名对应某个属性值;当我们遍历对象时,不在对象中的属性固然不会被接见到。

而在JS中,数组就是对象,以至数组的一些遍历要领,在内部实行的时刻,都是先将数组转化为对象,

javascriptvar O=Object(this);

然后遍历数组对象中,一切已定义的,且索引为数字的项。在绝大部分状况下,这些数字恰好是一连的。那什么时刻会涌现不一连呢?我所晓得有这两种;

  1. 以字面量体式格局新创建数组的时刻,一连的逗号,会构成数字索引不一连;如var arr=[1,2,,,3],你能够在浏览器掌握台中尝尝输出console.dir([1,2,,,3])的效果(注重,一定要用console.dir要领);

  2. 应用delete操作符删除数组中的某项。我们晓得delete操作符用于删除对象中某个属性,而JS中,数组就是对象的一种,数组的索引就是其属性名,对应的项就是属性值。用delete删除后,数组中的这对属性名值对(又称键值对)就不存在了,这时刻对其采纳遍历要领,固然不会针对不存在名值对举行挪用了。

有一点要特别注重,数组中被删除的项或许从未定义的项,与工资将其值设置为undefined的项,只管假如强行接见,效果都是undefined,然则是不太一样的,比方如许一个数组,[1,,undefined];,该数组(如今我们能够更正确得说:数组对象)中不存在索引为1的项,然则却存在索引为2的项,能够用console.dir输出看出区分。

数组的length属性还能回响反映数组长度吗?

说到上面这些,你一定已认识到了,既然数组的索引能够被跳过,那数组的length属性还能回响反映其长度吗?

关于这个题目,我是这么明白的,

  1. 数组的length属性并不能回响反映数组中元素的数量,在绝大多数状况(即没有人工干预length属性,且数组中没有跳过的索引),它只是恰好,恰好即是最大的索引加一。当我们从对象的角度来对待数组时,像0、1、2、3、4、5、6等等这些数字索引和length一样,都只是数组对象的属性。

  2. delete操作符删除数组恣意一项,或许将恣意一项值赋值为undefinedlength不转变;

  3. 当工资地设置数组的length属性值时,length随之转变,同时索引不小于该值的都会被从数组中完全删除。

    原文作者:oslh
    原文地址: https://segmentfault.com/a/1190000002995303
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞