第7章 数组

一、数组的基本概念

1. 定义:

值的有序集合。
值被称为数组的元素。元素位置称为索引(0-2^32-2);数组是动态的,会根据需要增减。稀疏与稠密数组:length均大于最大的索引号。

2. 创建:

  • 数组直接量创建
  • 调用构造函数Array():
    1. 无参数:var a=new Array();创建的是空数组,相当于数组直接两[];
    2.一个数值参数:var a=new Array(10);创建的是指定长度的数组;
    3.显示指定两个或多个参数:var a=new Array(5,4,3,2,1,"testing,testing"),构造函数的参数成为新数组的元素。

3.数组的读写:

使用[]操作符来访问数组元素。
注意:属性名与索引:在0-2^32-2范围内的非负整数属性名才是索引,数组会自动维护其length属性值。

4.稀松数组:

包含从0开始的不连续索引的数组。
创建方法:
* 使用一个数值参数的Array构造函数
* 指定数组的索引值大于当前数组长度
* delete操作符

5.数组长度

稠密数组中length=数组中的元素个数;
设置length属性小于当前长度的非负整数值n时,数组中≥n的元素会被删除掉;

6.数组元素的添加和删除:

  1. 添加:为新索引赋值;push()和unshift()方法在末尾或开头增加数组元素。
  2. 删除:delete操作,副作用是变为稀松数组;pop()和shift()方法在末尾或开头删除数组元素。

7.数组遍历:

for(var i=0,len=keys.length;i<len;i++){/*语句*/}
在对稀松的数组使用for循环遍历时进行检测;也可使用for/in循环进行遍历。

8.多维数组:

JavaScript不支持多维数组,但可用数组的数组近似获得(即数组的元素为数组)。

二.数组方法:

(一)ECMAScript3在Array.prototype中定义的一些操作数组的函数。

  1. join():将所有元素转化为字符串并连接在一起,返回最后生成的字符串;
var a=[1,2,3];
a.join();           //=>"1,2,3"
a.join(" ")         //=>"1 2 3"
a.join("")          //=>"123"
var b=new Array(10);    //长度为10的空数组;
b.join('-')             //=>'---------':9个连字符组成的字符串
  1. reverse():将数组中的元素颠倒顺序,返回逆序的数组;
var a=[1,2,3];
a.reverse().join();         //=>"3,2,1",并且现在的a是[3, 2, 1]
  1. sort():将数组的元素排序并返回排序后的数组。当不带参数时调用按照字母表顺序排序(如包含undefined会被排到尾部);如果按照其他方式,需要传递一个比较函数。这个函数决定了它的两个参数在排好序的数组中的先后顺序。假设第一个参数应该在前,则比较函数应该返回一个小于0的数值;反之,如第一个参数应该在后,则返回大于0的数值;并且假设两个值相等则返回0;
var a=[33,4,1111,222];
a.sort()            //=>字母表顺序:[1111, 222, 33, 4]
a.sort(function(a,b){
    return a-b;
})                  //=>数值顺序:根据返回的正负或0来判断;[4, 33, 222, 1111]
a.sort(function(a,b){
    return b-a;
})                  //=>数值相反的顺序:[1111, 222, 33, 4]
更复杂的排序:
var a=['ant','Bug','cat','Dog']
a.sort();           //区分大小写的排序:["Bug", "Dog", "ant", "cat"]
a.sort(function(s,t){//不区分大小写的排序
    var a=s.toLowerCase();
    var b=t.toLowerCase();
    if(a<b) return -1;
    if(a>b) return 1;
    return 0;           
});             //=>["ant", "Bug", "cat", "Dog"]
  1. concat():创建并返回一个数组。它的元素包括调用concat()的原始数组的元素和concat()的每个参数。
    注意:如果这些参数中的任何一个自身是数组,则连接的是数组的元素,而非数组本身。但不会递归。
var a=[1,2,3];
a.concat(4,5);      //返回[1,2,3,4,5]
a.concat([4,5]);    //返回[1,2,3,4,5]
a.concat([4,5],[6,7]);//返回[1,2,3,4,5,6,7]
a.concat(4,[5,[6,7]]);//返回[1,2,3,4,5,[6,7]]
  1. slice():返回制定数组的一个片段或子数组。它的两个参数分别指定了开始和结束位置。其中负数表示相对于数组中最后一个元素的位置。返回的数组包含第一个参数指定位置到不包含第二个参数之间的所有数组元素。
    注意:slice()不会修改调用的数组
var a=[1,2,3,4,5];
a.slice(0,3)    //返回[1,2,3]
a.slice(3)      //返回[4,5]
a.slice(1,-1)   //返回[2,3,4]
a.slice(-3,-2)  //返回[3]
  1. splice():在数组中插入或删除元素的通用方法,会修改调用的数组。
    splice()的前两个参数指定了需要删除的数组元素。紧随其后的任一个数的参数指定了需要插入到数组中的元素,从第一个参数的位置开始插入。
    splice()返回一个由删除元素组成的数组,或者如果没有删除就返回一个空数组
var a=[1,2,3,4,5,6,7,8];
a.splice(4);        //返回[5,6,7,8],a是[1, 2, 3, 4]
a.splice(1,2);      //返回返回[2,3],a是[1, 4]
a.splice(1,1);      //返回[4],a是[1]

var a=[1,2,3,4,5];
a.splice(2,0,'a','b')   //返回[],a是[1, 2, "a", "b", 3, 4, 5]
a.splice(2,2,[1,2],3)   //返回["a", "b"],a是[1, 2, [1,2], 3, 3, 4, 5]
  1. push()与pop():
    这两个方法允许将数组当做栈来使用。
  • push()方法在数组的尾部添加一个活多个元素,并返回数组的长度。
  • pop()方法则相反,它删除数组的最后一个元素,减小数组的长度并返回它删除的值。
    注意:会修改并替换原始数组
  1. unshift()与shift():
    这两个方法行为非常类似于push()与pop();不一样的是它是在数组的头部而不是尾部进行元素的插入和删除操作。
  2. toString()与toLocalString():
    数组和其他JavaScript对象一样拥有toString()方法。针对数组,该方法将其每个元素转化为字符串并且用逗号隔开。(和不加任何参数的join()方法返回的字符串一样)。toLocalString是本地化版本。
    下列代码在谷歌浏览器打开时,会弹出“Uncaught TypeError: Cannot read property 'toString' of undefined”错误,放到console.log()中不会
[1,2,3].toString()  //'生成1,2,3'
["a","b","c"].toString()//生成'a,b,c'
[1,[2,'c']].toString()//生成'1,2,c'

(二)ECMAScript5定义了9个新的数组方法来遍历、映射、过滤、检测、简化和搜索数组。

一般性规律:大部分ES5的数组方法第一个参数都是接收一个函数并对数组的每一个元素进行调用,大多数情况下调用提供的函数使用三个参数:数组元素、数组索引和数组本身。第二个参数是可选的。

  1. forEach():从头至尾遍历数组,为每个元素指定调用的函数。
            var data=[1,2,3,4,5];
            //计算数组元素的和值
            var sum=0;
            data.forEach(function(value){
                sum +=value;
            })
            sum                             //=>15
  1. map():将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含函数的返回值。注意返回的是新数组,不会修改调用的数组
            var a=[1,2,3];
            b=a.map(function(x){
                return x*x
            });                             //b是[1,4,9]
  1. filter():返回的数组元素是调用的数组的一个子集。传递的函数事用来做逻辑判定的,该函数返回true或false;
            var a=[5,4,3,2,1];
            smallvalues=a.filter(function(x){
                return x<3
            })                              //[2,1]
            everyother=a.filter(function(x,i){
                return i%2==0
            })                              //[5, 3, 1]
  1. every()与some()
  2. reduce()与reduceRight()
  3. indexOf()与lastIndexOf()

三、数组类型

1.定义:

数组是具有特殊行为的对象。给一个未知的对象,判定它是否为数组非常有用。

  1. ECMAScript5中可以用Array.isArray()函数来做;
Array.isArray([]);      //=>true
Array.isArray({});      //=>false`
  1. 在ES5之前,typeof帮不上忙对数组仅返回“对象”,instanceof操作符只能用于简单的情形(web多窗体或窗口存在)。
//ES5之前判断对象时数组的方法
var isArray=Function.isArray || function(o){
    return typeof o ==="object" &&
    Object.prototype.toString.call(o)==="[object Array]"
}

2.类数组对象

  1. 定义:把拥有一个数值length属性和对应非负整数属性的对象看做一种类型的数组。
    Arguments对象就是一个类数组对象,DOM方法如document.getElementsByTagName()也返回类数组对象。
//下面这个函数用来检测类数组对象
//判定o是否为一个类数组对象
//字符串和函数有length属性,但是它们可以用typeof检测将其排除。
//在客户端JavaScript中,DOM文本节点也有length属性,需要额外判断o.nodeType!=3将其排除
function isArrayLike(o){
    if(o &&                         //o非null、undefined等
        typeof o==="object" &&      //o是对象
        isFinite(o.length) &&       //o.length是有限数值
        o.length >=0 &&             //o.length为非负值
        o.length===Math.floor(o.length)&&   //o.length是整数
        o.length<4294967296)        //o.length<2^32
        return true;
    else
        return false;               //否则它不是
}
  1. 类数组对象没有继承自Array.prototype,不能直接在它们上面调用数组方法,可以间接地使用Function.call方法调用。
var a={"0":"a","1":"b","2":"c",length:3};           //类数组对象
Array.prototype.join.call(a,"+")        //=>"a+b+c"
Array.prototype.slice.call(a,0)         //["a", "b", "c"]:真正数组的副本
Array.prototype.map.call(a,function(x){
    return x.toUpperCase();
})                                      //=>["A", "B", "C"]
//在Firefox 1.5中将这些方法的版本在Array构造函数上直接定义为函数,这样上述例子可以这样重写
var a={"0":"a","1":"b","2":"c",length:3};
Array.join(a,"+")
Array.slice(a,0)
Array.map(a,function(x){return x.toUpperCase();})   
//由于这些不是标准的,可以增加以下代码兼容所有浏览器:
Array.join=Array.join || function(a,sep){
    return Array.prototype.join.call(a,sep);
}
Array.slice=Array.slice || function(a,from,to){
    return Array.prototype.slice.call(a,from,to);
}
Array.map=Array.map || function(a,f,thisArg){
    return Array.prototype.map.call(a,f,thisArg)
}

3.作为数组的字符串

除用charAt()方法访问单个字符以外,可以用方括号。另可将通用的数组方法应用到字符串上。

var s="JavaScript";
Array.prototype.join.call(s," ")                //=>J a v a S c r i p t
Array.prototype.filter.call(s,function(x){      //过滤字符串的字符
    return x.match(/[^aeiou]/);                 //只匹配非元音字符
}).join("")     

请记住:字符串是不可变值,故把它们看做数组时,它们也是只读的。如push()、sort()、reverse()和splice()等数组方法在字符串上市无效的,且使用数组方法修改字符串导致错误,出错的时候是没有提示的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,219评论 0 4
  • PHP常用函数大全 usleep() 函数延迟代码执行若干微秒。 unpack() 函数从二进制字符串对数据进行解...
    上街买菜丶迷倒老太阅读 1,360评论 0 20
  • php usleep() 函数延迟代码执行若干微秒。 unpack() 函数从二进制字符串对数据进行解包。 uni...
    思梦PHP阅读 1,983评论 1 24
  • 人山人海啊 一个浪 接着一个浪 希望很快就会到家 月儿恋恋山岗 海潮依依口岸 夜色舞动喧腾时 最容易心灵沉寂 落叶...
    树梢的雪阅读 195评论 0 1
  • 该不该投诉外卖小哥这件事? 在别人做得好的时候,要不吝啬自己的赞美 ,在别人做的不好的 地方要站出来指证,毋以善小...
    真真卒迹阅读 441评论 0 0