• JavaScript学习笔记(三) 数组


    严格来说,在 JavaScript 中并不存在数组这个数据类型,但是 JavaScript 却提供了一种具有数组特性的对象

    并且通过一定的封装,以及提供一系列的语法糖,让这个对象用起来像真正的数组一样方便

    1、创建数组

    (1)数组字面量

    数组字面量由零个或多个用逗号分隔的表达式组成,每个表达式的值可以是任意类型,所有表达式用方括号括起来

    > // 创建一个空数组
    > var empty = []
    > // 创建一个带有内容的数组
    > var fruit = ['apple', 'banana', 'cherry']
    

    检查一下刚刚创建的数组,发现它是一个 object 类型

    > typeof fruit
    // 'object'
    

    在创建数组的时候,数组中的每个元素都会得到一个默认的属性名,第一个为 '0',第二个为 '1',以此类推

    最终,属性名和元素值以键值对的形式存储下来,类似于下面直接用对象直接量创建的一个对象

    > var fruit = {'0': 'apple', '1': 'banana', '2': 'cherry'}
    

    当然,两者(使用数组直接量创建数组 和 使用对象直接量创建对象)还是有很多不同之处的

    • 数组继承自 Array.prototype,对象继承自 Object.prototype,两者具有的方法有所不同
    • 数组拥有一个神奇的 length 属性,而对象没有

    (2)new Array()

    可以使用 new 运算符加上 Array 构造函数创建一个数组

    > // 创建一个空数组
    > var empty = new Array()
    

    2、元素的增删改查

    (0)数组的索引

    对于常规的数组而言,数组的索引是从零开始的连续增加的正整数,但是在 JavaScript 中情况就不一样了

    因为数组也是对象的一种,所以理论上我们可以使用任意合法的字符串索引数组,就像索引对象属性一样

    那么怎么区分数组索引和对象属性呢?

    JavaScript 规定,只有在 [0, 2**32) 之间的整数才能作为数组索引,否则只能将其当作对象属性

    (1)元素的读取(查)

    使用方括号操作符( [] )可以访问数组中的元素

    方括号的左边是数组的引用,方括号的里面是一个返回非负整数的任意表达式,作为数组的索引

    > var fruit = ['apple', 'banana', 'cherry']
    > fruit[0]
    // 'apple'
    

    不要忘了哦,数组是对象的一种特殊形式,所以使用方括号访问数组元素就像使用方括号访问对象属性一样

    JavaScript 会把数字索引值转化为字符串索引值,然后将其作为属性名使用

    (2)元素的设置(改)

    设置元素的值同样可以使用方括号运算符

    > var fruit = ['apple', 'banana', 'cherry']
    > fruit[0] = 'almond'
    > fruit[0]
    // 'almond'
    

    (3)元素的删除(删)

    • delete 运算符:在原数组中将指定索引的元素值设置为 undefined
    > var drink = ['milk', 'tea', 'coffee']
    > delete drink[1]
    > drink[1]
    // undefined
    > drink[2]
    // coffee
    
    • pop 方法:在原数组中删除最后一个元素,并返回删除的元素
    > var drink = ['milk', 'tea', 'coffee', 'beer']
    > var drink_popped = drink.pop()
    > drink
    // ['milk', 'tea', 'coffee']
    > drink_popped
    // 'beer'
    
    • shift 方法:在原数组中删除最前一个元素,并返回删除的元素
    > var drink = ['milk', 'tea', 'coffee', 'beer']
    > var drink_shifted = drink.shift()
    > drink
    // ['tea', 'coffee', 'beer']
    > drink_shifted
    // 'milk'
    
    • splice 方法:在原数组中删除指定元素,第一个参数指定起始索引,第二个参数指定长度,返回删除的元素
    > var drink = ['milk', 'tea', 'coffee', 'coke', 'sprite', 'beer']
    > var drink_spliced = drink.splice(3, 2)
    > drink
    // ['milk', 'tea', 'coffee', 'beer']
    > drink_spliced
    // ['coke', 'sprite']
    

    (4)元素的增加(增)

    • 添加元素最简单的方式就是给新索引赋值
    > var food = ['rice', 'meat', 'vegetable']
    > food[3] = 'noodle'
    > food
    // ['rice', 'meat', 'vegetable', 'noodle']
    
    • push 方法:在原数组的最后添加一个元素,返回新数组中元素的个数
    > var food = ['rice', 'meat', 'vegetable']
    > var food_length = food.push('bread')
    > food
    // ['rice', 'meat', 'vegetable', 'bread']
    > food_length
    // 4
    
    • unshift 方法:在原数组的最前添加一个元素,返回新数组中元素的个数
    > var food = ['rice', 'meat', 'vegetable']
    > var food_length = food.unshift('bread')
    > food
    // ['bread', 'rice', 'meat', 'vegetable']
    > food_length
    // 4
    
    • splice 方法:除了删除数组中的元素,splice 方法还可以通过第三个可选的参数添加元素
    > var food = ['rice', 'meat', 'vegetable']
    > var food_spliced = food.splice(2, 0, 'fish')
    > food
    // ['rice', 'meat', 'fish', 'vegetable']
    > food_spliced
    // []
    

    3、元素的遍历

    由于数组也是对象的一种,所以我们可以使用遍历对象的方式来遍历数组,常用的有 for-in 循环和 for-of 循环

    > var fruit = ['apple', 'banana', 'cherry']
    > fruit[5] = 'filbert'
    > // for-in 循环
    > for (let index in fruit) {
        console.log(fruit[index])
    }
    // apple
    // banana
    // cherry
    // filbert
    > // for-of 循环
    > for (let item of fruit) {
        console.log(item)
    }
    // apple
    // banana
    // cherry
    // undefined
    // undefined
    // filbert
    

    4、数组的 length 属性

    JavaScript 数组 length 属性的值不一定等于数组中元素的个数,它实际上是等于数组中最大的合法索引加 1

    在这里有一条规则,那就是 在数组中肯定找不到一个元素的索引值大于或等于它的长度

    为了维持这个规则,length 属性有许多有趣的行为

    • 如果为一个数组元素赋值,并且它的索引 i 大于或等于现有的数组长度,那么 length 属性的值将设置为 i + 1
    > var alphabet = ['a', 'b', 'c']
    > alphabet.length
    // 3
    > alphabet[4] = 'e'
    > alphabet.length
    // 5
    
    • 如果为一个数组元素赋值,并且它的索引不是一个合法的数组索引,那么 length 属性的值将不会发生改变
    > var alphabet = ['a', 'b', 'c']
    > alphabet.length
    // 3
    > alphabet[-1] = 'z'
    > alphabet.length
    // 3
    
    • 如果设置 length 属性为一个小于当前长度的非负整数 n 时,数组中那些索引值大于或等于 n 的元素将被删除
    > var alphabet = ['a', 'b', 'c']
    > alphabet.length
    // 3
    > alphabet.length = 1
    > alphabet
    // ['a']
    

    5、数组的方法

    JavaScript 提供了一套作用于数组的方法,这些方法是储存在 Array.prototype 的函数

    (1)常规的数组方法

    • join:将数组中的所有元素都转化为字符串并拼接在一起,返回拼接后的字符串

      可以通过一个可选的参数(字符串类型)指定分隔符,默认使用逗号

    > var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    > var numbers_join = numbers.join()
    > numbers_join
    // '0,1,2,3,4,5,6,7,8,9'
    
    • reverse:将数组中的元素倒序排列,返回排序后的数组
    > var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    > var numbers_reverse = numbers.reverse()
    > numbers_reverse
    // [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]
    
    • sort:将数组中的元素按照一定的规则排序,返回排序后的数组

      可以通过一个可选的参数(函数类型)指定元素之间的比较规则,默认为字典序

    > var numbers = [111, 3, 22]
    > ns1 = numbers.sort() // 转化为字符串,按照字典序排列
    > ns2 = numbers.sort(function(a, b) { return a < b }) // 按照数值从大到小排列
    > ns3 = numbers.sort(function(a, b) { return a > b }) // 按照数值从小到大排列
    > ns1
    // [ 111, 22, 3 ]
    > ns2
    // [ 111, 22, 3 ]
    > ns3
    // [ 3, 22, 111 ]
    
    • concat:拼接两个数组的元素,返回拼接之后的数组
    > var a = [1, 2, 3]
    > var b = [4, 5, [7], [8, 9]]
    > var c = a.concat(b)
    > var d = b.concat(a)
    > c
    // [1, 2, 3, 4, 5, [7], [8, 9]]
    > d
    // [4, 5, [7], [8, 9], 1, 2, 3]
    
    • slice:返回指定范围的数组片段

      两个参数分别指定起止位置,省略第二个参数默认为数组最后,同时省略第一个参数默认为数组最前

    > var a = [1, 2, 3, 4, 5]
    > var b = a.slice(1, 4)
    > var c = a.slice(2) // 省略第二个参数
    > var d = a.slice() // 同时省略第二个和第一个参数
    > b
    // [ 2, 3, 4 ]
    > c
    // [ 3, 4, 5 ]
    > d
    // [ 1, 2, 3, 4, 5 ]
    
    • includes:检查数组中是否包含特定的元素,有的话返回 true,没有的话返回 false
    > var numbers = [1, 2, 3, 4, 5]
    > numbers.includes(0)
    // false
    > numbers.includes(1)
    // true
    
    • indexOf:检查数组中是否包含特定的元素,有的话返回对应的索引,没有的话返回 -1
    > var numbers = [1, 2, 3, 4, 5]
    > numbers.indexOf(0)
    // -1
    > numbers.indexOf(1)
    // 0
    

    (2)ECMAScript5 中的数组方法

    ECMAScript5 中新定义的数组方法具有一些类似的特性,这里先做介绍

    这些方法大都接收一个函数作为参数,并且对数组中的每个元素都调用一次该函数

    该函数接收三个参数,分别是数组元素、元素索引和数组本身

    (1)forEach

    > var numbers = [1, 3, 5, 7, 9]
    > // 计算数组中所有元素的总和
    > var sum = 0
    > numbers.forEach(function(value){
        sum += value
    })
    > sum
    // 25
    > // 将数组中的每个元素加 1
    > numbers.forEach(function(value, index, array){
        array[index] = value + 1
    })
    > numbers
    // [2, 4, 6, 8, 10]
    

    (2)map

    > var numbers = [1, 2, 3, 4, 5]
    > // 将数组中的每个元素乘 2,并返回一个新的数组
    > var numbers_doubled = numbers.map(function(number){
        return (number * 2)
    })
    > numbers_doubled
    // [2, 4, 6, 8, 10]
    

    (3)filter

    > var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    > // 留下偶数元素
    > var even_numbers = numbers.filter(function(number){
        return (number % 2 === 0)
    })
    > even_numbers
    // [2, 4, 6, 8, 10]
    

    (4)every / some

    > function isPrime(val) {
        if (val < 2) {
            return false
        } else if (val === 2) {
            return true
        } else { // val > 2
            if (val % 2 === 0) {
                return false
            } else { // val % 2 !== 0
                for (let i = 3; i * i <= val; i += 2) {
                    if (val % i === 0) {
                        return false
                    }
                }
                return true
            }
        }
    }
    > // 判断数组中的每个元素是否都是素数
    > [2, 3, 5, 7].every(function(value){
        return isPrime(value)
    })
    // true
    > [2, 3, 5, 7, 9].every(function(value){
        return isPrime(value)
    })
    // false
    > // 判断数组中是否存在一个元素是素数
    > [4, 6, 8, 9].some(function(value){
        return isPrime(value)
    })
    // false
    > [2, 4, 6, 8, 9].some(function(value){
        return isPrime(value)
    })
    // true
    

    这里给大家出一道题目,请写出下面程序的执行结果

    ['1', '3', '10'].map(parseInt)
    

    输出的结果是 [1, NaN, 2],大家答对了吗

    解决这道题目有两个关键的知识点,一个是 map 函数的原理,一个是 parseInt 函数的原理

    map 函数的原理,就是将在参数中指定的函数作用于数组的每一个元素,然后把这些结果组成一个数组返回

    它接收的第一个参数是数组的当前元素,第二个参数是该元素的索引,第三个参数是数组本身

    实际上,这个程序会返回这样的结果 [parseInt('1', 0), parseInt('3', 1), parseInt('10', 2)]

    好,下面我们再来看看 parseInt 函数的作用,它的作用其实就是将一个字符串转换成十进制数字

    它接收的第一个参数是被解析的字符串,第二个参数表示要使用的基数,这个值可以是 0 或者在 2 ~ 36 之间

    parseInt('1', 0):基数为 0,默认使用十进制解析字符串,将十进制的数字 1 转换为十进制数字还是 1

    parseInt('3', 1):基数既不为 0,也不在范围 2 ~ 36 之间,所以返回 NaN

    parseInt('10', 2):基数为 2,因此使用二进制解析字符串,将二进制的数字 10 转换为十进制数字是 2

    所以最终的结果就是 [1, NaN, 2]

    【 阅读更多 JavaScript 系列文章,请看 JavaScript学习笔记

    版权声明:本博客属于个人维护博客,未经博主允许不得转载其中文章。
  • 相关阅读:
    乒乓操作
    Poj 2010-Moo University
    POJ
    spirngmvc POJO参数映射详解
    spring AOP解析之xml方式详解
    spring AOP解析之xml方式详解
    springmvc POJO参数映射详解
    springmvc RequestMappingHandlerAdapter初始化详解
    springmvc RequestMappingHandlerMapping初始化详解
    Jquery的选择器
  • 原文地址:https://www.cnblogs.com/wsmrzx/p/11831942.html
Copyright © 2020-2023  润新知