网站首页 > 技术文章 正文
本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。
数组的操作:
concat()方法:
基于当前数组,将多个元素连接一起成为新的数组并返回;新数组中的元素按连接时的顺序排列。(具体来说,这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。当需要合并多个数组时,此方法比较方便);
语法:数组名.concat( [ item1, [ item2, [ item3 , […, [ itemN ] ] ] ] ] );
item:可选项,可以是数组对象也可以是单个数组元素,或者是其它对象;
var arr = [1,2];
arr = arr.concat();
arr = arr.concat(3,4);
arr = arr.concat(3,[4,5]);
arr = arr.concat([3,4],[5,6]);
arr = arr.concat([3,4],[5,6,[7,8]]);
console.log(arr);
concat()不会递归扁平化数组的数组,也不会修改原来的数组;当没有给concat()方法传递参数的情况下,它只是复制当前数组并返回副本。
slice()方法:
能够基于当前数组中的一个或多个项创建一个新数组;
语法:slice(start [, end]);
其接受一或两个参数,即要返回项的起始和结束位置;在只有start一个参数的情况下,slice()方法返回从该位置开始到当前数组末尾的所有项;如果两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项;
其不会影响原有数组;如:
var colors=["red","green","blue","yellow","purple"];
var c = colors.slice(1);
c = colors.slice(1,4);
c = colors.slice(1,-2);
c = colors.slice(-4,-2);
c = colors.slice(3,1);
console.log(colors);
console.log(c);
如果slice()方法的参数中有一个负数,则用数组长度加上该数来确定相应的位置;(如,在一个包含5项的数组上调用 slice(-2,-1)与调用slice(3,4)得到的结果相同;)
如果结束位置小于起始位置,则返回空数组。
splice()方法:
可以删除、替换或插入数组元素,是最强大的数组方法,有很多种用法;
具体作用是,从一个数组中移除一个或多个元素;剩下的元素组成一个数组,移除的元素组成另一个新数组并返回;同时,原数组可以在移除的开始位置处顺带插入一个或多个新元素,达到修改替换数组元素的目的;
语法:数组名. splice( start, deleteCount, [ item1 [, item2 [ , . . . [ , itemN ] ] ] ] );
start:必选项,表示从数组中剪切的起始位置下标索引号。
deleteCount:必选项,表示将从数组中切取的元素的个数。
item:可选项,表示切取时插入原数组切入点开始处的一个或多个元素;
- 1)删除:可以删除任意数量的项,只需要指定2个参数,如:splice(0,2);// 删除数组中前两项;如果只指定1个参数,则删除从该位置到结尾的元素;
- 2)插入:可以向指定位置插入任意数量的项,需要指定3个参数,其中第二个参数为0;如果要插入多个项,可再传入第4第5等任意多个项,如:splice(2,0,”red”,”green”);
- 3)替换:可以向指定位置删除任意数量的项,同时插入任意数量的项,需要指定至少3个参数;插入的项数不必与删除的项数相等,如:splice(2,1,”red”,”green”);
splice()方法始终会返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除任何项,则返回一个空数组);
var a = [1,2,3,4,5,6,7,8];
// var b = a.splice(4);
// var b = a.splice(1,4);
// var b = a.splice();
// var b = a.splice(1,0,'a','b');
// var b = a.splice(1,4,'a','b');
var b = a.splice(1,4,['a','b']);
console.log(a);
console.log(b);
区别于concat(),splice()会插入数组本身而非数组的元素;
第一个参数可以接受负数,如果为负数,则指定的位置是数组长度加上该负值,或者从后向前定位;
var a = [1,2,3,4,5,6,7,8];
var b = a.splice(-3, 2, 'a','b');
console.log(a);
console.log(b);
在实际的场景中,主要还是向数组的中部插入项;
delete运算符删除数组元素:
通常使用delete运算符删除一个指定的元素(与删除对象属性一样):
var colors=["red","green","blue","yellow","purple"];
delete colors[1];
console.log(colors);
此删除并没有真正删除数组元素,仅删除元素内容;(此删除与为其赋undefined值是类似的,但有一些微妙的区别);
delete删除不会修改数组的length属性;如果从数组中删除一个元素,该数组就变成稀疏数组;
删除数组元素有多种方式,如设置length属性小于数据长度,会删除数组尾部的元素;另外,还有前面所讲的方法。
注:如果需要删除全部元素只需要删除数组对象即可;
数组元素位置:
有关数组元素位置的方法:indexOf()和lastIndexOf(),两者会搜索整个数组中具有给定值的元素,并返回要查找的元素在数组中的第一个索引位置,或者在没找到返回-1;
这两个方法都是接收两个参数:要查找的项和(可选的)表示查找起点位置的索引;其中,indexOf()方法从数组的开头(位置为0)开始向后查找,lastIndexOf方向则从数组的末尾开始向前查找。
注:在查找时,使用是全等操作符;
var numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.indexOf(4)); // 3
console.log(numbers.lastIndexOf(4)); // 5
console.log(numbers.indexOf(4,4)); // 5
console.log(numbers.lastIndexOf(4,4)); // 3
var p={name:"wangwei"};
var p1 = p;
var people = [{name:"wangwei"},{name:"dawei"}];
var people = [p1,{name:"dawei"}];
var morePeople = [p];
console.log(people.indexOf(p)); // -1
console.log(morePeople.indexOf(p)); // 0
第二个参数也可以是负数,即为数组长度加上该负数的值为查找的索引开始位置,或者从后往前定位;
var numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.indexOf(4,-5)); // 5
封装一个函数,查找所有给定值的索引,并返回一个包含匹配索引的数组:
var numbers = [1,2,3,4,5,4,3,2,1];
function findAll(a,x){
var result = [], // 将会返回的数组
len = a.length, // 待搜索数组的长度
pos = 0; // 开始搜索的位置
while(pos < len){
pos = a.indexOf(x, pos);
if(pos === -1) break;
result.push(pos);
pos = pos + 1;
}
return result;
}
console.log(findAll(numbers,4));
字符串也有indexOf()和lastIndexOf()方法,它们和数组的方法功能类似;
对于数组这些方法,也可以重写,本质上就是修改其prototype对象的属性方法,如:
var arr = [1,2,3];
arr.push(4,5);
console.log(arr);
Array.prototype.push = function(){
for(var i=0; i<arguments.length; i++)
this[this.length] = arguments[i] * arguments[i];
}
arr.push(6,7);
console.log(arr);
遍历数组:
所谓的数组的遍历就是通过索引挨个取出数组元素;遍历目的是为了读取所有元素或者处理所有元素;使用for循环是遍历数组最常见的方法:
var citys = ["beijing","nanjing","bengbu"];
for(var i = 0; i<citys.length; i++)
console.log(citys[i]);
for(c in citys)
console.log(c, citys[c]);
var o = {name:"wangwei",age:18,sex:true};
var keys = Object.keys(o); // 获得o对象属性名组成的数组
console.log(keys);
var values = [];
for(var i=0;i<keys.length; i++){
values[i] = o[keys[i]]; // 取得对象的属性值
}
console.log(values);
// 优化的写法,数组的长度只查询一次
for(var i=0, len = keys.length; i<len; i++){
values[i] = o[keys[i]]; // 取得对象的属性值
}
// 练习:分别输出数组中的偶数、求数组奇数和偶数的个数、平均值、最大值
var arr = [1,3,16,8,57,22];
var result = 0, evenLen=0, max = arr[0];
for(var i=0; i<arr.length; i++){
result += arr[i];
if(arr[i] % 2 == 0){
console.log(arr[i]);
evenLen++;
}
if(max < arr[i])
max = arr[i];
}
console.log("偶数的个数:" + evenLen);
console.log("和为:" + result);
console.log("平均数:" + result / arr.length);
console.log("最大值:" + max);
在遍历稀疏数组,或者需要排除null、undefined和不存在的元素时,需要先检测:
var arr = [1,,3,null,undefined,6];
// 遍历所有
for(var i=0,len=arr.length; i<len; i++)
console.log(i,arr[i]);
// 跳过null、undefined和不存在的元素
for(var i=0,len=arr.length; i<len; i++){
if(!arr[i]) continue;
console.log(i, arr[i]);
}
// 只跳过undefined和不存在的元素
for(var i=0,len=arr.length; i<len; i++){
if(arr[i] === undefined) continue;
console.log(i, arr[i]);
}
// 只跳过不存在的元素
for(var i=0,len=arr.length; i<len; i++){
if(!(i in arr)) continue;
console.log(i, arr[i]);
}
使用for/in遍历稀疏数组:
for(var i in arr)
console.log(i, arr[i]);
但是,for/in能够枚举继承的属性名,如添加到Array.prototype中的方法;由于这个原因,在数组上不应该使用for/in循环,除非使用额外的检测方法来过滤不用的属性,如:
Array.prototype.company = "zeronetwork";
var arr = [1,,3,null,undefined,6];
arr.custom = "wangwei";
arr[-18.1] = 18;
// 只遍历元素
for(var i=0,len=arr.length; i<len; i++)
console.log(i,arr[i]);
// 把所有可枚举的属性全遍历出来
for(var i in arr)
console.log(i, arr[i]);
// 使用hasOwnProperty()方法过滤
for(var i in arr){
if(!arr.hasOwnProperty(i)) continue;
console.log(i, arr[i]);
}
// 跳过不是非负整数的i
for(var i in arr){
if(String(Math.floor(Math.abs(Number(i)))) !== i) continue;
console.log(i, arr[i]);
}
ES允许for/in循环以不同的顺序遍历对象的属性;通常数组元素的遍历实现是升序的,但不能保证一定是这样的;特别地,如果数组同时拥有对象属性和数组元素,返回的属性名很可能是按照创建的顺序而非数值的大小顺序;如何处理这个问题的实现各不相同,如果算法依赖于遍历的顺序,那么最好不要使用for/in而使用常规的for循环。
遍历数组的迭代方法:
ECMAScript5为数组定义了5个迭代方法;这些方法的第一个参数接收一个函数,并且对数组的每个元素调用一次该函数;第二个参数是可选的:其是运行该函数的作用域对象(影响this的值);或者说:调用的函数被当作是第二个参数的方法;
如果是稀疏数组,对不存在的元素不调用传递的函数;
这些方法不会修改原始数组;
参数函数使用三个参数:数组元素、元素索引和数组对象本身;通常,只需要第一个参数,可以忽略后两个参数;
参数函数可以修改原始数组;
根据使用的方法不同,这个函数执行后的返回值可能也会不同;
forEach()方法:
遍历数组,为每个元素调用指定的函数;该函数使用三个参数:数组元素、元素索引和数组本身;此方法没有返回值,本质上与使用for循环迭代数组一样;
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item,index,array){
console.log(item,index,array[index]);
});
// 为每个元素加1
var data = [1,2,3,4];
data.forEach(function(v,i,a){
a[i] = v + 1;
});
console.log(data);
如果只关心数组元素的值,可以只使用一个参数,额外的参数将被忽略:
// 求和
var data = [1,2,3,4];
var sum = 0;
data.forEach(function(value){
sum += value;
});
console.log(sum);
forEach()方法无法在所有元素都被传递给调用的函数之前终止遍历,即没有像for循环中使用的break语句;如果要提前终止,必须把forEach()方法放在try块中,并能抛出一个异常:
function foreach(a,f,t){
try{a.forEach(f, t);}
catch(e){
if(e === foreach.break) return;
else throw e;
}
}
foreach.break = new Error("StopIteration");
every()和some()方法:
最相似的是every()和some(),它们都是数组的逻辑判定:用于判定数组元素是否满足某个条件;
对every(),传入的函数必须对每一项都返回true,这个方法才返回true;
而some()是只要传入的函数对数组中的某一项返回true,就会返回true,否则返回false;
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item,index,array){
return (item > 2);
});
console.log(everyResult); // false
var someResult = numbers.some(function(item,index,array){
return (item > 2);
});
console.log(someResult); // true
一旦every()和some()确定该返回什么值时,它们就会停止遍历数组元素;(some()在判定函数第一次返回true后就返回true,但如果判定函数一直返回false,它将会遍历整个数组;every()恰好相反,它在判定函数第一次返回false后就返回false,但如果判定函数一直返回true,它将会遍历整个数组)。
根据数学上的惯例,在空数组上调用时,every()返回true,some()返回false;
filter()方法:
返回的是数组元素是调用的数组的一个子集;
回调函数是用来逻辑判定的,该函数返回true或false;如果返回的是true或真值,则该函数处理的数组元素就被添加到返回的子集数组中;
filter()方法会跳过稀疏数组中缺少的元素,它的返回数组总是密集的;
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item,index,array){
return item>2;
});
console.log(filterResult);
var evenResult = numbers.filter(function(value,index){
return index % 2 == 0; // [1, 3, 5, 3, 1] index是索引
});
console.log(evenResult);
// 压缩稀疏数组
var sparse = [1,,,4];
var dense = sparse.filter(function(){
return true;
});
console.log(dense);
// 压缩并删除undefined和null元素
var sparse = [1,null,3,undefined,,6];
var dense = sparse.filter(function(v){
return v !== undefined && v != null;
});
console.log(dense);
map()方法:
将调用的数组的每个元素传递给回调函数,并将调用的结果组成一个新数组返回;其不会修改原始数组,如果是稀疏数组,返回的也是相同方式的稀疏数组,即具有相同的长度、相同的缺失元素;
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item,index,array){
return item*2;
});
console.log(mapResult);
var a = [1,null,3,undefined,5];
var b = a.map(function(v){
return v * v;
});
console.log(b);
归并方法:
ECMAScript5还新增了两个归并数组的方法:reduce()和reduceRight();这两个方法都会迭代数组的所有项,然后构建一个最终返回的值;
其中,reduce()方法从数组的第一项开始,逐个遍历到最后;而reduceRight则从数组的最后一项开始,向前遍历到第一项;
语法:reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
这两个方法都接收两个参数:调用的函数callbackfn和作为归并基础的初始值initialValue(可选的);
这个函数接收4个参数:前一个值、当前值、项的索引和数组对象;其返回的任何值都会作为第一个参数自动传给下一项;第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项;
使用reduce()方法可以执行求数组中所有值之和的操作,如:
// 求和
var values = [1,2,3,4];
var sum = values.reduce(function(prev,cur,index,array){
return prev + cur;
});
console.log(sum); // 10
说明:第一次执行回调函数,prev与cur分别为数组的第1和第2项,即prev是1,cur是2;第二次,prev是第一次执行的结果,即3(1+2的结果),cur是数组的第三项,即是3,以此类推;
reduce()参数函数的参数也可以只使用两个参数,如:
// 求和
var values = [1,2,3,4];
var sum = values.reduce(function(prev,cur){
return prev + cur;
});
console.log(sum); // 10
// 求积
var product = values.reduce(function(prev,cur){
return prev * cur;
});
console.log(product); // 24
// 求最大值
var max = values.reduce(function(prev,cur){
return prev > cur ? prev : cur;
});
console.log(max); // 4
reduce()方法的第二个参数initialValue是回调函数的第一个参数previousValue的初始值;如:
// 把以上所有示例添加第二个参数,如:
var values = [1,2,3,4];
var sum = values.reduce(function(prev,cur){
return prev + cur;
},2); // 12
说明,第一次调用时,prev为initialValue值,即为2,cur为数组第一项,即为1;第二次调用,prev为3,cur为2,以此类推;
reduceRight()的作用类似,只不过方向相反,即按照数组索引从高到低(从右到左)处理数组;如:
var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev,cur,index,array){
console.log(prev,cur);
return prev + cur;
},6);
console.log(sum); // 15
// 求2^(3^4),乘方操作的优先顺序是从右到左
var a = [2,3,4];
var big = a.reduceRight(function(accu, value){
console.log(value);
return Math.pow(value, accu);
});
console.log(big);
在空数组上,不带初始值参数的reduce()将导致类型异常;如果数组只有一个元素并且没有指定初始值,或者一个空数组并且指定了一个初始值,该方法只是简单的返回那个值而不会调用回调函数;
var a = [];
// var b = a.reduce(function(x,y){return x + y}); //no initial value
// var b = a.reduce(function(x,y){return x + x});
var b = a.reduce(function(x,y){return x + y},3);
console.log(b);
使用reduce()还是reduceRight(),主要取决于要从哪头开始遍历数组;除此之外,它们完全相同。
reduce()和reduceRight()是典型的函数式编程;有些地方,会把其回调函数称为化简函数,这个化简函数的作用就是用某种方法把两个值组合或化简为一个值,并返回化简后的值;如以上的示例,化简函数通过各种方法,组合了两个值。
猜你喜欢
- 2024-09-30 JavaScript数组_数组方法「二」(二十七)
- 2024-09-30 table组件,前端如何使用table组件打印数组数据
- 2024-09-30 前端数组改字符串方法 前端数组改字符串方法是什么
- 2024-09-30 javascript复制数组的三种方式 javascript复制粘贴
- 2024-09-30 第21节 检测数组、类数组及多维数组-Web前端开发之Javascript
- 2024-09-30 前端系列——ES6中循环数组的方法
- 2024-09-30 前端已死?请用TS写出20个数组方法的声明
- 2024-09-30 springboot项目中,前端如何传递一个自定义对象数组给后端
- 2024-09-30 带你走进javascript数组的世界 javascript数组操作方法
- 2024-09-30 每天学点 ES6 —— 数组(二) es6数组处理方法
你 发表评论:
欢迎- 05-11FANUC修改前端目录教程
- 05-11前端分享-Set你不知道的事
- 05-11jq+ajax+bootstrap改了一个动态分页的表格
- 05-11千万级大表分页查询效率剧降,你会怎么办?
- 05-11Elasticsearch深度分页
- 05-11如何写一个简单的分页
- 05-11手速太快引发分页翻车?前端竞态陷阱揭秘
- 05-11「linux」Socket缓存是如何影响TCP性能的?
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端懒加载 (45)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle约束 (46)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)