喜迎
春节

JS基础-数组


Array 对象
Array 对象用于在变量中存储多个值:

var cars = ["Saab", "Volvo", "BMW"];

第一个数组元素的索引值为 0,第二个索引值为 1,以此类推。

数组

数组:一组数据(一个变量来承载)
数组对象是一个有序的数据,数据可以是 [原始类型] 或 [对象类型]集合。相对于变量,数组可用于在一个变量中存储多个变量值。
数组中的每一项都有一个数字附于其上,被称为索引。在 JavaScript 中,数组索引从 0 开始,并可以使用多种 [方法]操作.。

 var str = "Hello world"; // 一个变量存放一个数据
 var arr = [1,2,3,4,5,6,7,8,9];
 arr[arr.length] = 20 //往数组结尾插入元素

数组有两种定义方式

因为js是弱类型语言,所以数组也是弱类型,同一个数组变量里可以有各种不同类型的元素

 var arr = [];   //字面量的方式
var arr = new Array();   //构造函数的方式
var arr = new Array(10);//一个参数指数组长度为10
var arr = new Array(10,20,30);//多个参数指定义数组元素

数组的长度 arr.length
数组的索引(下标)从0开始 arr[0] - arr[arr.length-1]

遍历

 var arr = [9,2,35,5,74,12,43,4];
 for(var i = 0; i < arr.length; i++){
    console.log(arr[i]);
}
for...in(ES5) 遍历稀疏数组的时候不会遍历到undefined

 var arr = [9,2,35,5,74,12,43,4];
 for(var key in arr){
    console.log(typeof key); //string
    console.log(arr[key]);
}
for...of(ES6)

//直接取数组元素的值
 var arr = [9,2,35,5,74,12,43,4];
 for(var value of arr){
    console.log(value);
}

稀疏数组

就是包含从0开始的不连续索引的数组。也就是说数组中大部分的内容值都未被使用(或都为零)。

//生成稀疏数组的方法
var arr = new Array(3);   //数组没有元素,但是length是3
console.log(arr);    // [empty × 3]

//另一种生成稀疏数组的方法
var arr = []
arr[1000] = 1 //数组的长度为1001,但是实际的元素只有1个

实际上,JavaScript并没有常规的数组,所有的数组其实就是个对象,只不过会自动管理一些”数字”属性和length属性罢了。

说的更直接一点,JavaScript中的数组根本没有索引,因为索引应该是数字,而JavaScript中数组的索引其实是字符串:arr[1]其实就是arr[“1”],给arr[“1000”] = 1,arr.length也会自动变为1001。
这些表现的根本原因就是:JavaScript中的对象就是字符串到任意值的键值对。注意键只能是字符串。

数组是引用类型

基本数据类型:number、string、boolean、undefined、null
引用数据类型:object(array也属于object)、function

 var str = "Hello World";
 var str2 = str;//内存开辟另外一段空间存放str2
 var arr = [1,2,3,4,5,6,7,8,9];
 var arr2 = arr;//arr和arr2指向同一段存储空间

 var arr1 = [1,2,3];
 var arr2 = arr1;
 arr1[arr1.length] = 4;
console.log(arr1);
console.log(arr2);
//arr和arr2指向同一段存储空间

函数的值传递和引用传递

function fn1(a){
     a++;
 }
 var num = 10;
 fn1(num);
 console.log(num);

 function fn2(arr){
     arr[arr.length] = 20;
 }
 var arr1 = [1,2,3];
 fn2(arr1);
 console.log(arr1);

数组API
https://upload-images.jianshu.io/upload_images/15859737-d937a19e6edd7ed9.png?imageMogr2/auto-orient/strip|imageView2/2/w/829/format/webp

数组常用API

(concat\join\reverse\slice\splice\toString\sort)

concat()

连接两个或更多的数组,并返回结果。

var arr = [1,2,3];
var arr1 = [4,5,6];
var arr3 = [7,8,9]
var arr2 = arr.concat(arr1, arr3);
console.log(arr2);

join()

把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。

var str = arr.join("-");
console.log(str);

pop()

删除并返回数组的最后一个元素

//操作的是数组本身
var num = arr.pop();
console.log(num);
console.log(arr); //[1,2]

push()

向数组的末尾添加一个或更多元素,并返回新的长度。

var len = arr.push(4);
console.log(len); // 3
console.log(arr); //[1,2,4]

shift()

删除并返回数组的第一个元素

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.shift()//Orange,Apple,Mango

unshift()

向数组的开头添加一个或更多元素,并返回新的长度。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon","Pineapple");
//Lemon,Pineapple,Banana,Orange,Apple,Mango

reverse()

颠倒数组中元素的顺序。

//修改的是数组本身
arr.reverse();
console.log(arr);

slice()

从某个已有的数组返回选定的元素

//var arr5 = arr.slice(1, 2); //含头不含尾
//var arr5 = arr.slice(-3,-1); //负值指倒数第几个
var arr5 = arr.slice(-3); //一个参数代表截取到末尾
console.log(arr5);

sort()

对数组的元素进行排序
默认排序顺序为按字母升序.
注意:当数字是按字母顺序排列时”40”将排在”5”前面。
使用数字排序,你必须通过一个函数作为参数来调用。
函数指定数字是按照升序还是降序排列。
这种方法会改变原始数组!

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
//Apple,Banana,Mango,Orange

splice()

删除元素,并向数组添加新元素。

var arr6 = [2,3,45,6,7,8];
//arr6.splice(1,1); //从下标为1开始,截取1个
//arr6.splice(1,1,1);
arr6.splice(1,0,1,3,4,5);
console.log(arr6);

toString()

把数组转换为字符串,并返回结果。

var str1 = arr6.toString();
console.log(str1);

indexOf()

返回某个指定的字符串值在字符串中首次出现的位置。如果没有找到匹配的字符串则返回 -1。
注意: indexOf() 方法区分大小写。

var str="Hello world, welcome to the universe.";
var n=str.indexOf("welcome");//13

some()

方法用于检测数组中的元素是否满足指定条件(函数提供)。
some() 方法会依次执行数组的每个元素:
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
注意: some() 不会对空数组进行检测。
注意: some() 不会改变原始数组。

var ages = [3, 10, 18, 20];

function checkAdult(age) {
    return age >= 18;
}

function myFunction() {
    document.getElementById("demo").innerHTML = ages.some(checkAdult);
}
//true

案例1:

定义一个30项的数组, 按顺序分别赋予从2开始的偶数;
在每间隔 5个数 之后,求出前五个数的平均值;

var sum = 0;
var arr = new Array(30);
for(var i = 0; i < arr.length; i++){
    arr[i] = (i+1) * 2;
    //只要当前元素有值,那就可以累加
    sum += arr[i];
    //下标为4,9,14,19的时候应该计算平均值,并且重新从0开始加
    if(i%5 === 4){
        var avg = sum/5;
        sum = 0;
        console.log(avg);
    }

}

案例2:

var arr = new Array(5); //行数
for(var i = 0; i < arr.length; i++){
    //每一趟循环代表一行
    var subArr = new Array(5);
    for(var j = 0; j < subArr.length; j++){
        subArr[j] = 5*i+j+1;
    }
    arr[i] = subArr;
}
console.log(arr);
//坐下半角 i >= j
/* i   j   subArr[j]
0  0-4   1-5        j+1+i*5
1  0-4   6-10
2  0-4   11-15 */

var arr = [1,2,3,5,6,10];
var num = 4;
//把n跟数组每一个元素比较大小,直到找到比n大的数,那么就插入
//for(var i in arr){
//for(var i = 0; i < arr.length; i++){
for(var i = 0, len = arr.length; i < len; i++){
    if(num < arr[i]){
        //从i位置插入
        arr.splice(i,0,num);
        break;
    }
}
console.log(arr);

es5新增API

2个索引方法:

indexOf() 和 lastIndexOf()

var arr = [3,5,42,1,33,1,43,5];
console.log(arr);
console.log(arr.indexOf(1)); //从左往右寻找(括号内是要查找的元素,最后输出该元素的索引)
console.log(arr.lastIndexOf(1)); //从右往左寻找

5个迭代方法:

forEach()、map()、filter()、some()、every()

(1)forEach()

方法用于调用数组的每个元素,并将元素传递给回调函数。
注意: forEach() 对于空数组是不会执行回调函数的。

//语法:array.forEach(function(currentValue, index, arr), thisValue)
//currentValue必需。当前元素
//index 可选。当前元素的索引值。
//arr可选。当前元素所属的数组对象。
//thisValue 可选。传递给函数的值一般用 “this” 值。如果这个参数为空, “undefined” 会传递给 “this” 值

var arr = [3,5,42,1,33,1,43,5];
    console.log(arr);
arr.forEach(function(item,index){
    console.log(item, index);
});
(2) map()

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。

//语法:array.map(function(currentValue,index,arr), thisValue)
var arr = [3,5,42,1,33,1,43,5];
console.log(arr);

var arr2 = arr.map(function(item, index){
    return item * 2;});
console.log(arr2);
(3) filter()

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。

//语法:array.filter(function(currentValue,index,arr), thisValue)
var arr = [3,5,42,1,33,1,43,5];
console.log(arr);
var arr2 = arr.filter(function(item, index){
      return item < 10;
  })
  console.log(arr2);
(4) some()

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
some() 方法会依次执行数组的每个元素:
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
注意: some() 不会对空数组进行检测。
注意: some() 不会改变原始数组。

//语法:array.some(function(currentValue,index,arr),thisValue)
var arr = [3,5,42,1,33,1,43,5];
console.log(arr);

var isBig = arr.some(function(item, index){
    return index>10;});
console.log(isBig);
(5) every()

every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素:
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
注意: every() 不会对空数组进行检测。
注意: every() 不会改变原始数组。

//语法:array.every(function(currentValue,index,arr), thisValue)
var arr = [3,5,42,1,33,1,43,5];
            console.log(arr);
var isBig = arr.every(function(item, index){
                return index<10;
            })
            console.log(isBig);

2个归并方法:

reduce()、reduceRight()

(1)reduce()

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。

//语法:array.reduce(function(total(必需。初始值, 或者计算结束后的返回值)
 //currentValue(必需。当前元素), currentIndex, arr), initialValue)
//归并
var arr = [3,5,42,1,33,1,43,5];
console.log(arr);
//上一次迭代返回的结果作为下一次的prev
var sum = arr.reduce(function(prev, next){
    return prev+next;
},0);
console.log(sum);
(2) reduceRight()

reduceRight方法的功能和 reduce功能是一样的,不同的是 reduceRight从数组的末尾向前将数组中的数组项做累加。

//二元数组归并为一元数组
var arr = [
    [1,2,3],
    [4,5,6],
    [7,8,9]
]
var arr1 = arr.reduceRight(function(prev, next){
    return prev.concat(next.reverse());
},[]);
console.log(arr1);

数组去重的三种方法

方法1:

var arr = [2,3,4,2,2,2,2,3,4,2,5,6,8];
console.log(arr);
//i  起点值0,终点值length-2
for(var i = 0; i < arr.length-1; i++){
    //j  起始值i+1,终点值  length-1
    for(var j = i+1; j < arr.length; j++){
        if(arr[i] === arr[j]){
            //当删除一个值之后,后面的值得索引会全部减一
            //所以需要j--抵消for循环的j++
            arr.splice(j--, 1);
            //j--;
        }
    }
}
console.log(arr);

方法2:利用对象

//利用对象的属性名不能重复的特点
var arr = [2,3,4,2,2,2,2,3,4,2,5,6,8];
console.log(arr);

var obj = {};

for(var i = 0; i < arr.length; i++){
    //判断obj里面有没有arr[i]这个属性
    if(!obj[arr[i]]){
        //obj[arr[i]]不存在,第一次遍历到arr[i]
        //赋值
        obj[arr[i]] = 1;
    }else{
        //obj[arr[i]]已经存在了,arr[i]曾经被遍历到过
        arr.splice(i--, 1);
    }
}
console.log(arr);

方法3:ES6

var arr = [2,3,4,2,2,2,2,3,4,2,5,6,8];
console.log(arr);
//Set默认就不允许重复
var arr2 = Array.from(new Set(arr));
console.log(arr2);

文章作者: NekoDeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 NekoDeng !
评 论
 上一篇
CSS-SCSS代码规范
CSS-SCSS代码规范
1 注释规范2 缩进/空格/换行规范(1)每个缩进使用4个空格,不允许使用 2 个空格 或 tab //正确 .sample { display: flex; } //错误 .sample { di
2020-09-06
下一篇 
JS-设计模式
JS-设计模式
设计模式:代码经验的总结设计模式都是面向对象的 工厂模式工厂函数就是做一个对象创建的封装,并将创建的对象return出去 function newObj(name,age){ var o = new Object();
2020-09-04
  目录