数组
1.数组的基础
ECMAScript数组是有序列表,是存放多个值的集合。
有以下特性:
每一项都可以保存任何类型的数据。
数组的大小是可以动态调整。
数组的length属性:可读可写,可以通过设置length的值从数组的末尾移除项或向数组中添加新项
js中的数组是可以存放任意数据类型值的集合,数组的元素可以是任意数据类型,数组的长度可以动态调整。
2.数组的创建
初始化:
1.字面量创建数组
// 字面量创建数组
var arr1=['terry','lerry','zhangsan']
console.log(arr1,typeof arr1);//[ 'terry', 'lerry', 'zhangsan' ] object
// 获取数组长度
console.log(arr1.length);//3
// 通过索引获取对应的元素
console.log(arr1[1]);//lerry
// 数组的元素可以由任意数据类型的数组组成
var arr2=['lisi',true,123,{name:'zhangsan'}]
console.log(arr2);//['lisi',true,123,{name:'zhangsan'}]
2.构造函数创建数组
// 构建函数创建数组
var arr3=new Array();
arr3[0]='zahngsan';
arr3[1]='lisi';
arr3[2]='wangwu';
console.log(arr3);
// 使用构造函数创建数组时直接进行数组数据的添加
// 如果你在构造函数中传递的参数是一个number类型的整数
var arr4=new Array(3)//整数代表数组的长度
// 如果你在构造函数中传递的参数是一个number类型的小数
// var arr4=new Array(2.3);//Error: Invalid array length
var arr4=new Array(1,2,3,'zhangsan');
console.log(arr4);
3.数组的访问
格式: 数组变量名[索引]
访问数组的元素 通过数组索引来进行访问
1.[index] 数组索引从0开始 数组索引超过数组长度访问会返回undefined值不会报错
-
length-1=Max(index) 表示数组索引的最大值
-
length+N 开辟新的内存空间 数组元素的删除
length-- 表示数组的长度减一 也是对数组元素的删除, 删除数组的最后一位元素
length++ 表示数组长度的增加一 开辟新的内存空间 在元素组的后面
var arr=['zhangsan','lisi','wangwu']
// 通过索引下标 回去数组长度内的某一个元素
console.log(arr[0]);
console.log(arr[2]);
// 获取数组的最后一个元素
console.log(arr[arr.length-1]);
// 数组元素的新增和删除
// 新增
arr.length=6;
console.log(arr);
// 删除
arr.length=2;
console.log(arr);
4.数组API
4.1 数组序列化
toString() 在默认情况下都会一逗号为分隔符的形式返回数组项
join() 使用自定义的字符串作为分隔符 返回数组项
var arr = [1,5,2,8,10,{a:1}];
console.log(arr);//[ 1, 5, 2, 8, 10, { a: 1 } ]
console.log(arr.toString());//”1,5,2,8,10,[object Object]”
console.log(arr.join(""));//”152810[object Object]”
console.log(arr.join("-"));//”1-5-2-8-10-[object Object]”
// 数组也可以使用序列化工具进行转换,并且,数组也存在深拷贝浅拷贝的现象,也可以使用序列化工具解决此问题
var result = JSON.stringify(arr);
console.log(result);//”[1,5,2,8,10,{"a":1}]”
console.log(JSON.parse(result));//[ 1, 5, 2, 8, 10, { a: 1 } ]
4.2 构造函数的方法
-
Array.isArray() 用来判断某个变量是否是一个数组对象
-
Array.from() 从类数组对象或者可迭代对象中创建一个新的数组实例
var myArr = Array.from("BRIUP");
console.log(myArr);
//输出结果为["B","R","I","U","P"]
- Array.of() 根据一组参数来创建新的数组实例,支持任意的参数数量和类型
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
4.3 栈与队列方法
- Array.prototype.push() 可以向数组的末尾添加一个或者多个元素, 返回新的长度
( 有参数 改变原数组的长度 返回改变后数组的长度)
语法: array.push(item1, item2, …, itemX)
var fruits = ["Banana", "Orange", "Apple", "Mango"];
// push() 添加元素到末尾 参数是要添加的元素 返回值是修改之后数组的长度【改变原数组】
fruits.push("Kiwi")
console.log(fruits);
//fruits 结果输出:Banana,Orange,Apple,Mango,Kiwi
重构 myPosh () 方法:
var arr=['zhangsan','lisi','wangwu'];
Array.prototype.myPush=function(){
for(var i=0;i<arguments.length;i++)
{
// 数组的后面逐个添加元素
this[this.length]=arguments[i];
}
//返回数组的长度
return this.length;
}
console.log(arr); //['zhangsan','lisi','wangwu']
var result=arr.myPush('hello');//['zhangsan','lisi','wangwu','hello']
console.log(result,arr);
- Array.prototype.pop() 用于删除数组的最后一个元素并返回删除的元素
(无参数 改变原数组的长度 返回删除的元素)
**语法:**array.pop()
var fruits = ["Banana", "Orange", "Apple","Mango"];
fruits.pop();console.log(fruits);
//fruits 结果输出:Banana,Orange,Apple
重构myPop()方法:
var arr=['zhangsan','lisi','wangwu'];
Array.prototype.myPop=function(){
var temp=this[this.length-1];
this.length--;
return temp;
}
console.log(arr);
//['zhangsan','lisi','wangwu']var result=arr.myPop();console.log(result,arr);//wangwu ['zhangsan','lisi']
- Array.prototype.shift() 用于把数组的第一个元素从其中删除 ,并返回第一个元素的值
( 无参 改变原数组的长度 返回删除的第一个元素)
**语法:**array.shift()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.shift()console.log(fruits);
//fruits结果输出:Orange,Apple,Mango
重构myShift() 方法:
var arr=['zhangsan','lisi','wangwu'];
Array.prototype.myShift=function(){
var result=this[0];
for(i=0;i<this.length;i++)
{
this[i]=this[i+1];
}
this.length--;
return result;
}
console.log(arr);//['zhangsan','lisi','wangwu']
var result=arr.myShift();
console.log(result,arr);//zhangsan ['lisi','wangwu']
- Array.prototype.unshift() 可以向数组的开头添加一个或者更多的元素 ,并返回新的数组长度
(有参数 改变原数组的长度 返回改变后的数组长度)
语法:
array.unshift(item1,item2, ..., itemX)
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon","Pineapple");
console.log(fruits)
//fruits 将输出:Lemon,Pineapple,Banana,Orange,Apple,Mango
重构myUnshift() 方法
Array.prototype.myUnshift=function(){
var sum=this.length+arguments.length;
for(var i=sum;i>0;i--){
if(i>arguments.length){
this[i-1]=this[i-1-arguments.length];
}else{
this[i-1]=arguments[i-1]
}
}
return sum;
}
var arr=[1,2,3];
console.log(arr);
var result=arr.myUnshift('zhangsan','lisi');
console.log(result,arr);
4.4 排序方法
- Array.prototype.reverse() 用于颠倒数组中元素的位置
(无参数 改变原数组的顺序 返回排序后的数组)
**语法:**array.reverse()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.reverse();
console.log(fruits)
//fruits结果输出:Mango,Apple,Orange,Banana
重构myReverse() :
// myreverse() 方法用于颠倒数组中元素的顺序
function myReverse() {
for(var i=0;i<this.length/2;i++)
{
var x=this[i];
this[i]=this[this.length-1-i];
this[this.length-1-i]=x;
}
console.log(this);
}
var arr = ['zhangsan', 'lisi', 'wangwu','nn'];
arr.myReverse();//[ 'nn', 'wangwu', 'lisi', 'zhangsan' ]
-
Array.prototype.sort() 用于对数组的元素进行排序
(参数可有可无 改变原数组顺序 返回排序后的数组)
没有使用参数的情况下,默认按字母升序Ascall编码对数组进行排列
语法:array.sort(sortfunction)
var fruits = ["Banana", "Orange", "Apple", "Mango"];//默认按字母升序排序 fruits.sort(); console.log(fruits)//fruits 输出结果:Apple,Banana,Mango,Orange
**注意:**当数字是按字母顺序排列时"40"将排在"5"前面。
使用数字排序,你必须通过一个函数作为参数来调用。
函数指定数字是按照升序还是降序排列。
关于升序和降序的条件
当 a>b 时,
a - b > 0 ,排序结果 ===> b,a (升序)
b - a < 0 ,排序结果 ===> a,b (降序)
当 b>a 时,
a - b < 0 ,排序结果 ===> a,b (升序)
b - a > 0 ,排序结果 ===> b,a (降序)
当 a=b 时,
a - b = b - a =0 , 排序结果 ===> 保持不变
无论a>b还是b>a,return a-b 总能得到升序的结果,而 return b-a 总能得到降序的结果。
-
数字排序(升序):
var points = [40,100,1,5,25,10]; points.sort(function(a,b){ return a-b });//points输出结果:1,5,10,25,40,100
数字排序(降序):
var points = [40,100,1,5,25,10]; points.sort(function(a,b){ return b-a });//fruits输出结果:100,40,25,10,5,1
灵活排序:
// 灵活排序,在多维数组中可以自定义按需排序
//排序后的原数组也会发生改变var result=arr.sort(handler('sarlary'));
// key是传入数组的一个形参
function handler(key) {
return function (a,b) {
var c=a[key];
var d=b[key];
if(c>d)
{
return 1;
}else{
return -1;
}
}}
console.log(result);
console.log(arr);
4.5 操作方法
- Array.prototype.concat() 用于连接两个或多个数组
(有参数 不改变原有的数组 返回被连接数组的一个副本)
**语法:**array1.concat(array2,array3,…,arrayX)
//合并三个数组的值
var hege = ["Cecilie", "Lone"];
var stale = ["Emil", "Tobias", "Linus"];
var kai = ["Robin"];
var children = hege.concat(stale,kai);
//children 输出结果:Cecilie,Lone,Emil,Tobias,Linus,Robin
- Array.prototype.slice() 可以从已有的数组中返回选定的元素
参数可选 提取字符串的某个部分 并以新的字符串返回被提取的部分
**语法:**array.slice(start, end)
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1,3);
//citrus 结果输出:Orange,Lemon
参数特殊取值:slice(-2)表示提取原数组中的倒数第二个到最后一个元素
slice(-2,-1)表示原数组倒数第二个元素到最后一个元素,不包含最后一个元素,只有倒数第二元素
- Array.prototype.splice() 用于添加或删除数组中的元素
有参数 改变原始数组 返回改变后的数组
//数组中添加新元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
//从数组索引位置 2 开始,不删除元素,添加两个新的元素"Lemon","Kiwi"
fruits.splice(2,0,"Lemon","Kiwi");
//fruits输出结果:Banana,Orange,Lemon,Kiwi,Apple,Mango
//移除数组的第三个元素,并在数组第三个位置添加新元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2,1,"Lemon","Kiwi");//fruits输出结果:Banana,Orange,Lemon,Kiwi,Mango
//从第三个位置开始删除数组后的两个元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2,2);//fruits输出结果:Banana,Orange
4.6 位置方法
- Array.prototype.indexOf() 可以返回数组中某个指定的元素位置
有参数 不改变原数组 返回元素在数组的位置 没有则返回-1
**语法:**array.indexOf(item,start)
//查找数组中的 "Apple" 元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple");//a结果输出:2//以上输出结果意味着 "Apple" 元素位于数组中的第 3 个位置。
-
Array.prototype.lastIndexOf() 可返回一个指定的元素在数组中最后出现的位置,从该字符串的后面向前查找
语法:array.lastIndexOf(item,start)
//查找数组元素 "Apple"出现的位置 var fruits = ["Banana", "Orange", "Apple", "Mango"]; var a = fruits.lastIndexOf("Apple"); //a输出结果:2//以上实例输出结果意味着 "Apple" 位于数组中的第 2 个位置.
4.7 迭代方法
- Array.prototype.every() 用于检测数组所有元素是否都符合指定条件
(有参数 不会改变原数组 返回boolean值)
every() 方法使用指定函数检测数组中的所有元素:
- 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
- 如果所有元素都满足条件,则返回 true。
**注意:**every()不会对控数组进行检测
**语法:**everyevery(function(item,index,arr){},this对象)
1.第一个参数在数组中的每个元素都会执行到的函数,固定的
2.第二个参数是前面function内的this指向-- 第二个参数任意数据类型,传什么都可以
3.判断数组元素是否都满足某一条件,一项不满足直接跳出当前判断,符合短路原则
//检测数组 *ages* 的所有元素是否都大于等于 18
var ages = [32, 33, 16, 40];
var result = ages.every(function (age) {
return age >= 18
})
console.log(result);//输出结果为:false
重构myEvery()方法:如果有不满足的直接返回false,不再继续往后判断。如果全部满足,返回true
Array.prototype.myEvery=function(fun,obj){ for(i=0;i<this.length;i++){
//if判断是否有第二位参数obj ,如果有就修改this指向且利用bind返回修改后的函数,如果没有则直接调用函数
if(!(obj?fun.bind(obj)(this[i]):fun(this[i]))){
//不符合函数条件则返回false
return false;
}
}
return true;
}
var arr=[1,2,3,4,5];// 调用myEvery()方法
var result=arr.myEvery(function(item,index,arr){ console.log(this);
return item>1 },{name:'zhangsan'})
console.log(result);
-
Array.prototype.some() 用于检测数组中的元素是否满足指定条件(函数提供)
(有参数 不会改变原数组 返回boolean值)
some() 方法会依次执行数组的每个元素:
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
**注意:**some()不会对空数组进行检测
**语法:**some(function(item,index,arr){},this对象)
1.第一个参数在数组中的每个元素都会执行到的函数,
2.第二个参数是前面function内的this指向–
3.判断数组元素是否有一个满足条件,一项满足,跳出判断,返回true符合短路原则
//检测数组中是否有元素大于 18:
var ages = [32, 33, 16, 40];
var result = ages.some(function (age) {
return age >= 18})
console.log(result);//输出结果为:true
重构mySome()方法 如果有一项满足直接返回true,不再往后判断,直接返回true
Array.prototype.mySome = function (fun, obj) {
for (i = 0; i < this.length; i++) {
if (obj ? fun.bind(obj)(this[i]) : fun(this[i])) {
return true;
}
}
return true;
}// 调用mySome()方法
var arr = [1, 2, 3, 4, 5];
var result = arr.mySome(function (item, index, arr) {
console.log(this);
return item > 1;
}, { name: 'zhangsan' })
console.log(result)
-
Array.prototype.filter() 用于创建一个新的数组 新数组中的元素通过检查指定数组中符合条件的所有数组
有参数 不改变原始数组 返回符合条件的元素 ,没有则返回空数组
注意:filter()不会对空数组进行检测
语法:filter(function(item,index,arr){},this对象)
过滤出满足某一条件的元素,组成新的数组
//返回数组 *ages* 中所有元素都大于 18 的元素: var ages = [32, 33, 16, 40]; var result = ages.filter(function (age) { return age >= 18 }) console.log(result);//输出结果为:[ 32, 33, 40 ]
重构myFilter()方法
Array.prototype.myFilter = function (fun, obj) { var result = []; for (i = 0; i < this.length; i++) { // 如果第二个参数存在 ,修改this指向 bind返回修改后的函数,没有参数则直接调用函数 if ((obj ? fun.bind(obj)(this[i]) : fun(this[i]))) { result.push(this[i]); } } return result; } // 调用myFilter()方法 var arr = [1, 2, 3, 4, 5]; var result = arr.myFilter(function (item, index, arr) { // console.log(this); return item >2}, { name: 'zhangsan' }) console.log(result)
-
Array.prototype.map() 返回一个新的数组, 数组中的元素为原始数组元素调用函数处理后的值
(有参数 不改变原始数组 返回 数组元素调用函数处理后的值)
**语法:**map(function(item,index,arr){},this对象)
映射出元素的某一部分,组成新数组
//返回一个数组,数组中元素为原始数组的平方根
var numbers = [4, 9, 16, 25];
var result = numbers.map(function (number) {
return Math.sqrt(number)
})
console.log(result);//输出结果为:[ 2, 3, 4, 5 ]
重构myMap()方法 映射 对每一项数组项进行操作,返回的是操作后的一个新数组
Array.prototype.myMap=function(fun,obj){
var result=[];
for(var i=0;i<this.length;i++){
result.push(obj ? fun.bind(obj)(this[i]) : fun(this[i]))
}
return result;
}// 调用myMap()函数
var arr = [1, 2, 3, 4, 5];
var result = arr.myMap(function (item, index, arr) {
return item+1;
}, { name: 'zhangsan' })
console.log(result)
- Array.prototype.forEach() 用于调用数组的每个元素,并将元素传递给回调函数
(有参数 不会改变原数组 返回值undefined)
语法:array.forEach(function(currentValue, index, arr), thisValue)
遍历数组
//列出数组的每个元素
var numbers = [4, 9, 16, 25];
numbers.forEach(function (number, index)
{
console.log(index + ' -- ' + number);
})// 0 -- 4// 1 -- 9// 2 -- 16// 3 -- 25
重构myForEach()
Array.prototype.myForEach=function(fun){
for(var i=0;i<this.length;i++)
{
fun(this[i],i,this)
}}
var arr=['zhangsan','lisi','wangwu'];
var result=arr.myForEach(function(item,index,arr){
console.log(index+'--'+ item );
})
**迭代方法中没有第二个参数this指向全局对象 node里面是global html文档中指向window //有第二个参数this指向第二个参数,第二个参数可以是任意数据类型**