javascript整理——数组和类数组

数组就是一组数据的集合,其表现形式就是内存中的一段连续的内存地址,数组名称其实就是连续内存地址的首地址,那什么是类数组呢?类数组顾名思义就是像数组,但不是真正的数组,利用对象和数组的特性模拟成的数组,有length属性,但是没有数组的方法。先来讲讲数组

创建数组的两种方式:

  •   var 数组名 = [ ];     //数组字面量(推荐)
  •   var 数组名 = new Array(); //构造函数

           eg: var arr1 = new Array(); //创建一个空数组

                 var arr2 = new Array(10); //传递一个参数,一个参数为数字类型的时候(整数)表示数组长度,就如这个时候数组arr2的长度为10

                 var arr3 = new Array("a","b"); //创建一个包含a和b的数组

数组的属性:

      length 长度 长度从1开始  但是数组的下标从0开始,不要搞混了

数组的方法:

    数组的长度分为两类

      第一种:可以改变原始数组的方法

  • push() 在数组末尾添加一个元素,并返回新长度     
var arr1 = ["apple","orange"]
var arr2 = arr1.push("peach");
console.log(arr2);//数组新长度为3
console.log(arr1);//输出为apple orange peach
  • pop() 删除数组最后一个元素,并返回删除元素   
var arr1 = ["apple","orange","peach","banana"]
var arr2 = arr1.pop();
console.log(arr2);//数组删除元素为banana
console.log(arr1);//输出为apple orange peach
  • unshift() 向数组的开头添加一个或多个元素,并返回新长度
var arr1 = ["tom","lily","lucy"];
arr1.unshift("mack","angle");
console.log(arr1); //5(数组新长度) mack angle tom lily lucy
  • shift()   删除数组第一个元素,返回删除元素       
var arr1 = ["tom","lily","lucy"];
arr1.shift();
console.log(arr1); 
  • splice() 删除数组元素,并向数组添加新元素

       删除:可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。

       插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如,splice(2,0,4,6)会从当前数组的位置 2 开始插入4和6。 

        替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如,splice (2,1,4,6)会删除当前数组位置 2 的项,

然后再从位置 2 开始插入4和6。

var arr = [1,3,5,7,9,11];
var arrRemoved = arr.splice(0,2);
console.log(arr); //[5, 7, 9, 11]
console.log(arrRemoved); //[1, 3]
var arrRemoved2 = arr.splice(2,0,4,6);
console.log(arr); // [5, 7, 4, 6, 9, 11]
console.log(arrRemoved2); // []
var arrRemoved3 = arr.splice(1,1,2,4);
console.log(arr); // [5, 2, 4, 4, 6, 9, 11]
console.log(arrRemoved3); //[7]
  • reverse() 颠倒数组元素
var arr = [12,23,45,56,78,89];
arr.reverse();
console,log(arr);//89 78 56 45 23 12
  • sort()  数组排序(从小到大)

       在排序时,sort()会调用会调用每个数组的tostring()方法,比较的也是字符串,因此原数组会发生改变

arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](元数组被改变)

    如果想要原数组不被改变,可以写一个比较函数作为参数,以便指定哪个值在哪个值得前面,比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:

function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]

上面的为升序(从小到大),如果想要降序(从大到小),交换一下比较值就可以了

第二种:不可改变原始数组的方法

  •  join(separator)  将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符,该方法只接收一个参数:即分隔符。
var arr = [1,2,3];
console.log(arr.join()); // 1,2,3
console.log(arr.join("-")); // 1-2-3
console.log(arr); // [1, 2, 3](原数组不变)
  • concat()  连接两个或多个数组,并返回结果,如何没有参数就相当于数组的一次克隆
var arr = [1,2,3,4]
var arr1 = arr.concat(78,56);
console.log(arr,arr1);
//arr : 1 2 3 4
//arr1 : 1 2 3 4 78 56
  • toString()  转成字符串 
  • slice() 截取数组长度,返回从开始下标到结束下标的元素,如果只有一个参数,那就是截取参数下标到数组最后一个元素
arr = [13, 24, 51, 3,12];
var test = arr.slice(3);
console.log(test);//3,12
var test1 = arr.slice(1,4);
console.log(test1);//24,51,3
console.log(arr);//13,24,51,3,12原始数组没有改变

    现在到了类数组啦(arguments,ArrayLike)

    类数组有length属性,但是没有数组的方法,其实本质为一个对象,那类数组到底是什么样子的呢

//类数组示例
var a = {'1':'gg','2':'love','4':'meimei',length:5};
Array.prototype.join.call(a,'+');//'+gg+love++meimei'

//非类数组示例
var c = {'1':2};   //没有length属性就不是类数组

既然类数组没有数组的方法,如果强行调用呢?就拿数组的push()和splice()方法来说,强行调用,会根据length属性的位置进行属性扩充

var obj = {
  0 : "a",
  1 : "b",
  push : Array.prototype.push,
  splice : Array.prototype.splice
}

判断一个对象是否为类数组的函数,如下

function isArrayLike(o) {
    if (o &&                                // o is not null, undefined, etc.
        typeof o === 'object' &&            // o is an object
        isFinite(o.length) &&               // o.length is a finite number
        o.length >= 0 &&                    // o.length is non-negative
        o.length===Math.floor(o.length) &&  // o.length is an integer
        o.length < 4294967296)              // o.length < 2^32
        return true;                        // Then o is array-like
    else
        return false;                       // Otherwise it is not
}

类数组可以转换成数组,类数组本质是一个对象,转成数组后可以调用数组的一系列方法

1.Array.prototype.slice.call(arrayLike):将arrayLike转换成一个Array对象,后面可以直接调用数组所具有的方法
Array.prototype.slice.call(arrayLike).forEach(function(element,index){  //可以随意操作每一个element了 })

Arrray.prorotype.slice借用了原型中的slice方法,返回一个数组,slice内部实现方法

Array.prototype.slice = function(start,end){  
      var result = new Array();  
      start = start || 0;  
      end = end || this.length; //使用call之后this指向了类数组对象
      for(var i = start; i < end; i++){  
           result.push(this[i]);  
      }  
      return result;  
 } 

一个通用的转换函数

var toArray = function(s){  
    try{  
        return Array.prototype.slice.call(s);  
    } catch(e){  
            var arr = [];  
            for(var i = 0,len = s.length; i < len; i++){   
                 arr[i] = s[i];   
            }  
             return arr;  
    } 

2.Array.from() 

  Array.from()是ES6中新增的方法,可以将两类对象转为真正的数组:类数组对象和可遍历(iterable)对象(包括ES6新增的数据结构Set和Map)。

3.、扩展运算符(…) 
  同样是ES6中新增的内容,扩展运算符(…)也可以将某些数据结构转为数组

原文地址:https://www.cnblogs.com/jrrrrr/p/9255699.html