Go转JS-第四弹(数组)

41 阅读4分钟

JavaScript中的数组学习

1、数组的定义

  • var arr = ['a','b']
  • var arr = new Array('a','b')
  • var arr = new Array(4)

1.1、数组下标越界

  • js中规定,数组下标越界会返回undefined,而不会报错。(go会panic)
    var arr = ['a','b']
    arr[1]     // b
    arr[2]     // undefined

1.2、数组长度

  • 数组的length属性表示数组的长度。(go中使用len()函数)
    var arr = ['a','b','c']
    console.log(arr.length)  // 3

1.3、数组更改项内容

  • 通过下标获取数组某项再赋予新值即可。arr[1] = '只因'
  • 当获取的下标超过数组的长度时,会自动创建新的项,即数组变长了。
    var arr = ['a','b']
    // 更改项
    arr[1] = '只因'
    console.log(arr)  // (2) ['a', '只因']
    // 下标超过原数组长度
    arr[4] = '坤'
    console.log(arr)  // (5) ['a', '只因', empty × 2, '坤']

区别: go数组下标越界会panic,同时go不允许修改数组的长度

1.4、数组类型的检测

  • typeof数组的类型为object,并不是Array
  • 可使用Array.isArray()来检测,返回结果为布尔值

2、数组的常用方法

  • pop(),shift(),push(),unshift()删除项与插入项
  • splice(),替换指定项
  • slice(),截取数组
  • join()split()
  • concat(),多个数组连接,不改变原数组
  • reverse(),数组置反,改变原数组
  • indexOf()includes(),数组中是否存在某元素

2.1、数组的删除项与插入项

  • 删除: pop()删除尾部,并返回删除内容,shift()删除头部,并返回删除内容。
  • 插入: push()尾部插入新项,unshift()头部插入新项
    var arr = ['a','b','c']
    // pop
    var p = arr.pop()
    console.log(arr,p)   // ['a','b'],'c'
    // shift
    var s = arr.shift()
    console.log(arr,s)   // ['b'],'a'
    // push
    arr.push('d','e')
    console.log(arr)     // ['b','d','e']
    // unshift
    arr.unshift('r')
    console.log(arr)     // ['r','b','d','e']

2.2、splice()替换指定项

  • 数组.splice(i,j,arr...),从第i个项开始(i不是下标),将后面连续的j个项,替换成arr,同时以数组形式返回被替换的内容
    var arr = ['a','b','c']
    var a = arr.splice(1,1,'d','e','f')
    console.log(arr)     // (5) ['a', 'd', 'e', 'f', 'c']
    console.log(a)       // ['b']

2.2.1、splice()实现插入项和删除项

    var arr = ['a','b','c','e','f','g']
    // 插入
    arr.splice(1,0,'只因','坤')
    console.log(arr)    // ['a', '只因', '坤', 'b', 'c', 'e', 'f', 'g']
    // 删除
    arr.splice(3,3)
    console.log(arr)    // ['a', '只因', '坤', 'f', 'g']

2.3、slice()截取数组

  • slice(a,b),从下表a开始,截取到下标b,但不包含下标b。[a,b):左包含,右不包含
  • b是可选的,也可以为负数。当b不填时,表示从a到最后;当b为负数时,表示从a到倒数第几项。
  • slice()并不会改变原数组,只是获得基于原数组截取的一个子数组。
    var arr = ['a','b','c','d']
    var a = arr.slice(1,3)
    console.log(arr)  // ['a', 'b', 'c', 'd'] 原数组并未改变
    console.log(a)    // ['b', 'c']
    // b为负数
    var b = arr.slice(1,-2)
    console.log(b)    // ['b']
    // b不填
    var c = arr.slice(1)
    console.log(c)    // ['b', 'c', 'd']

2.4、join()split()

  • join('a'),将数组以'a'作为分隔符连接成字符串。(数组转字符串)
  • split('a'),将字符串以'a'作为分隔符切割成数组。(字符串转数组)
    var arr = ['1','2','3','4']
    var s = arr.join('a')
    console.log(s)  // 1a2a3a4
    var a = s.split('a')
    console.log(a)  // ['1', '2', '3', '4']

2.5、concat()多个数组连接。

  • concat(arr1,arr2...),将多个数组进行连接,形成新数组。并不会改变原数组
    var arr1 = ['1','2','3']
    var arr2 = ['4','5']
    var arr3 = ['6','7']
    var arr = arr1.concat(arr2,arr3)
    console.log(arr)   // ['1', '2', '3', '4', '5', '6', '7']

2.6、reverse(),数组置反

  • reverse(),数组置反。不会形成新数组,直接改变原数组。
    var arr = ['a','b','c']
    arr.reverse()
    console.log(arr)   // ['c', 'b', 'a']

2.7、indexOf()includes(),数组中是否存在某元素

  • indexOf('a'),搜索数组中'a'元素,返回第一个元素的下标;若不存在则返回-1
  • includes('a'),判断数组中是否存在'a'元素,存在返回true,反之返回false
    var arr = ['a','b','c','a']
    console.log(arr.indexOf('a'))   // 0 
    console.log(arr.indexOf('d'))   // -1
    console.log(arr.includes('a'))  // true
    console.log(arr.includes('d'))  // false

3、数组为引用类型

  • var arr = arr1arr1赋值给arr的其实是arr1指向的内存地址,而不是arr1值的副本。即当arr1后续发生改变时,arr也会随着改变。
    var arr1 = ['a','b','c']
    var arr = arr1
    console.log(arr)   // ['a', 'b', 'c']
    arr1.push('d')
    console.log(arr)   // ['a', 'b', 'c', 'd']

引用类型与基本类型比较

包含类型值传递时(赋值)作相等(==)比较时
基本类型Numberstringbooleanundefined传递值的副本比较值是否相等
引用类型objectArray传递内存地址比较内存地址是否相等

4、数组的深浅拷贝

  • 浅拷贝:只拷贝数组的第一层,不拷贝数组中的项是引用类型的。
  • 深拷贝:拷贝数组的所有层。使用递归进行拷贝。

4.1、数组的浅拷贝

数组的元素中不含有引用类型的值

    // 浅拷贝
    var arr = ['a','b','c']
    var arr1 = []
    for (var i = 0;i < arr.length;i++) {
        arr1.push(arr[i])
    }
    console.log(arr1)        // ['a', 'b', 'c']
    console.log(arr1 == arr) // false  故:arr1 与 arr的内存地址不同

数组的元素中含有引用类型的值

    var arr = ['a','b',['c','d']]
    var arr1 = []
    for (var i = 0;i < arr.length;i++) {
        arr1.push(arr[i])
    }
    console.log(arr1)              // ['a', 'b', Array(2)]
    console.log(arr1[2] == arr[2]) // true  故:arr1[2] 与 arr[2]的内存地址相同,并未实现真正意义上的拷贝。

4.2、数组的深拷贝

  • 数组的深拷贝,本质上与浅拷贝相似,不同的在于深拷贝使用递归多次执行浅拷贝,从而达到多层数组的拷贝。
  • 判断每个元素的类型,是引用类型的才执行递归。
    // 深拷贝
    var arr = [1,2,3,[4,5,[6,7]]]
    function fun(n){
        var res = []
        for (var i = 0; i < n.length;i++){
            if (Array.isArray(n[i])){
                res.push(fun(n[i]))
            }else{
                res.push(n[i])
            }
        }
        return res
    }
    var a =fun(arr)
    a.push(8)
    console.log(arr)    // [1,2,3,[4,5,[6,7]]]
    console.log(a)      // [1,2,3,[4,5,[6,7]],8]