前端之路——JavaScript中的Array(2)

数组的实例属性和方法

实例属性

  • length 数组中元素的个数, 需要注意的是,通过索引为数组赋值会改变数组的长度
    let a = [ 1, 2 ]
    console.log(a.length) // 2
    a[1000] = 1
    console.log(a.length) // 10001

实例方法

区分数组和Array

  • 数组是调用Array后得到的对象实例,Array是该实例的构造函数

  • 该实例的原型不是Array,而是Array.prototype,即对象实例的原型是该对象实例的构造函数的prototype属性

    let a = []
    a.__proto__ === Array.prototype  // true

数组常用方法

  • 数组的方法都是继承自原型对象——Array.prototype

  • 一般而言,为了降低编程的复杂度,倾向于使用unmutable(不可变)的方法,基于此,对数组的实例方法分类

  • 返回新数组的方法

    • concat
      合并多个数组,返回的新数组是对原始数组的浅拷贝
        let e1 = { foo: 'foo' }
        let e2 = { bar: 'bar' }
        let a1 = [e1]
        let a2 = [e2]
        let a3 = a1.concat(e2)
        console.log(a3)     // [{ foo: 'foo' }, { bar: 'bar' }]
        e1.foo = 'bar'
        console.log(a3)     // [{ foo: 'bar' }, { bar: 'bar' }]
    
    • entries
      返回一个新的iterator对象。iterator对象有一个next方法,返回值为有valuedone属性的对象,done标识该
      iterator是否已经迭代完毕
        let a = [1, 2, 3]
        let it = a.entries
        it.next()  // { value: [0, 1], done: false }
        it.next()  // { value: [1, 2], done: false }
        it.next()  // { value: [2, 3], done: false }
        it.next()  // { value: undefined, done: true }
    
    • every
      测试数组中是否所有元素都满足测试条件,参数为返回boolean的测试函数
      只要有一个元素不满足测试条件,该方法返回false,否则返回true。
      对空数组([])调用会返回true
        [1, 2, 3].every(function(e) {
            return e > 1
        })      // false
    
    • filter
      筛选,参数为返回boolean的测试函数,返回满足条件的元素组成的新数组,若没有满足条件的元素,则返回空数组
        const a = [10, 5, 8]
        let b = a.every(function(e, index) {
            return e > 5
        }) // [10, 8]
    
    • find
      查找,参数为返回boolean的测试函数,返回第一个满足条件的元素,若没有满足条件的元素,则返回undefined
        const a = [
            {
                id: 1
            },
            {
                id: 2
            },
            {
                id: 3
            }
        ]
        let b = a.every(function(e, index) {
            return e.id > 1
        }) // { id: 2 }
    
    • findIndex
      查找下标,参数为返回boolean的测试函数,返回第一个满足条件的元素的下标,若没有满足条件的元素,则返回-1
        const a = [
            { id: 1 },
            { id: 2 },
            { id: 3 }
        ]
        let b = a.every(function(e, index) {
            return e.id > 1
        }) // 1
    
    • flat
      扁平化数组,参数为深度(默认为1),根据深度将所有元素及其子数组合并为一个新的数组。
      使用Infinity作为参数可以展开任意深度的嵌套数组
        const a = [1, 2, [3, 4, [5, 6]]]
        a.flat(2)    // [1, 2, 3, 4, 5, 6]
        a.flat(Infinity)     // [1, 2, 3, 4, 5, 6]
    
    • flatMap
      映射+扁平化,参数为映射函数,即对映射后的中间数组调用flat(1)
        const a = [1, 2, [3, 4, [5, 6]]]
        a.flatMap(function(e) {
            return e
        })    // [1, 2, 3, 4, [5, 6]]
    
    • forEach
      对每个元素执行一次映射函数,参数为映射函数
        const a = [1, 2, 3]
        a.forEach(function(e) {
            console.log(e)
        })
        // 1
        // 2
        // 3
    
    • includes
      测试一个数组是否包含指定元素,参数为待查找元素,可选的第二个参数为开始查找的下标,默认为0
      检测-0 和 0,NaN 和 NaN会返回true
        const a = [1, 2, 0, NaN]
        a.includes(2)   // true
        a.includes(-0)  // true
        a.includes(NaN)  // true
    
    • indexOf
      查找一个给定元素的第一个索引,参数为待查找元素,若未找到,则返回-1
      这里使用的是严格相等(类似===)
        const a = [1, 2, 3]
        a.indexOf(2)   // 1
    
    • join
      返回由参数连接符的数组元素组成的字符串,参数为连接符,默认为,,对空数组返回空字符串
        const a = [1, 2, 3]
        a.join('+')   // "1+2+3"
    
    • keys
      返回包含数组中每个索引键的iterator对象
        const a = [1, 2, 3]
        const it = a.keys()
        it.next()   // { value: 0, done: false }
        it.next()   // { value: 1, done: false }
        it.next()   // { value: 2, done: false }
        it.next()   // { value: undefined, done: true }
    
    • lastIndexOf
      与indexOf类似,区别是从后往前找

    • map
      根据映射函数,返回一个新数组,其中的元素是原数组中每个元素调用映射函数后的返回值

        const a = [1, 2, 3]
        a.map(function(e) {
            return 2 * e
        })  // [2, 4, 6]
    
    • reduce
      对数组中的每个元素执行reduce函数,将其结果返回成单个值,参数为reduce函数和初始值initialValue, 第二个参数是可选的
      reduce函数的第一个参数是上一次调用reduce函数的返回值,第二个参数是当前调用reduce函数对应的数组元素
      在第一次执行reduce函数时,
      • 如果提供了initialValue,则reduce函数的accumulator值为initialValuecurrentValue为第一个元素
      • 如果没有提供initialValue,则reduce函数的accumulator值为数组的第一个元素,currentValue为第二个元素
      • 如果数组为空,且没有提供initialValue,则抛出异常
        所以提供初始值是较好的做法
        const a = [1, 2, 3]
        a.reduce(function(accumulator, currentValue) {
            return accumulator + currentValue
        })  // 6
        a.reduce(function(accumulator, currentValue) {
            return accumulator + currentValue
        }, 10)  // 16
    
    • reduceRight
      同reduce类似,区别在于从右到左开始执行reduce函数

    • slice
      返回一个新的数组对象,长度由参数beginend决定

      • 省略begin,则从0开始,若begin为负数,如-2,则从倒数第2个元素开始
      • 省略end,则默认为数组长度
      • endbegin的左边,则返回空数组
        [1, 2, 3].slice(1)      // [2, 3]
        [1, 2, 3].slice(-1)     // [3]
        [1, 2, 3].slice(1, 0)     // []
    
    • some
      测试是否至少有一个元素满足测试函数,与every类似,区别在于只要有一个元素满足测试函数,就返回true
        [1, 2, 3].some(function(e) {
            return e > 1
        })      // true
        [1, 2, 3].every(function(e) {
            return e > 1
        })      // true
    
    • values
      与keys类似,只不过迭代器的value为数组的元素,而不是下标
  • 修改原数组的方法

    • fill
      使用固定的值填充数组,第一个参数是待填充的值,起始位置和结束位置是可选的
      类似这种指明起始和结束位置的参数,不提供结束参数则默认到数组的length,并且不包括结束位置
        [1, 2, 3].fill(4)   // [4, 4, 4]
    
    • pop
      删除数组最后一个元素,并返回该元素,该方法会修改原数组的长度
        [1, 2, 3].pop()   // 3
    
    • push
      将一个或多个元素添加到数组的末尾, 返回数组的新长度
        [1, 2, 3].push(4, 5, 7)   // 6
    
    • reverse
      将一个数组中的元素反序
        [1, 2, 3].reverse()   // [3, 2, 1]
    
    • shift
      与pop类似,区别是删除数组中的第一个元素,并返回该元素
        [1, 2, 3].shift()   // 1
    
    • sort
      排序,可传入排序函数,默认会将元素转换成字符串再按照Unicode位点排序
      • 比较函数返回-1,0,1,表示小于,等于,大于
        [10, 200, 3, 9, 81].sort()   // [10, 200, 3, 81, 9]
        [10, 200, 3, 9, 81].sort(function(e1, e2) {
            return e1 - e2
        })
    
    • splice
      删除或替换现有元素或者原地添加新的元素来修改数组, 返回被删除元素组成的数组
      • 第一个参数start是操作开始的位置
      • 第二个参数deleteCount为要删除元素的个数,若不指定,则删除从start开始删除剩余所有元素,若小于等于零,则不删除
      • 从第三个参数开始,为要添加的元素
        let a = [1, 2, 3]
        a.splice(1)     // 返回[2, 3]   a = [1]
        a = [1, 2, 3]
        a.splice(1, 1)     // 返回[2]   a = [1, 3]
        a = [1, 2, 3]
        a.splice(1, 1, 11)  // 返回[2]  a = [1, 11, 3]
    
    • unshift
      将一个或多个元素添加到数组的开头,并返回该数组的新长度
        let a = [1, 2, 3]
        a.unshift(4, 5)     // 返回5 a = [4, 5, 1, 2, 3]
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容