栈/队列node
pop删除最后一项(栈)
shift删除第一项(队列)
push增长到最后(栈)
unshift增长到最前(队列)
reverse翻转
join转字符串
slice截取(切片)slice
splice剪接
concat数组合并
sort排序本质详解es6
isArray
indexOf取索引
lastIndexOf
some经常使用
every经常使用
filter
reduce详解
reduceRight
forEach
map
兼容低版本IE扩展的Array数组
类数组
通用类数组
特殊类数组,属性为0,1..含有length的{}
经常使用类数组arguments Nodelistapp
做为数组的字符串ide
Array.from
Array.of
copyWithin
find经常使用
findIndex经常使用
fill
entries(),keys()和values()遍历数组
includes
数组的空位wordpress
栈:桶。只有一个口(进出)。先进后出,后进先出 队列:人队。有两个口。先进先出,后进后出
删除元素的值
;若是数组为空则返回undefinevar a = [1,2,3,4,5]; a.pop();//a:[1, 2, 3, 4] a.pop();//a:[1, 2, 3] a.pop();//a:[1, 2]
删除元素的值
;若是数组为空则返回undefinevar a = [1,2,3,4,5]; a.shift(); //a:[2,3,4,5] a.shift(); //a:[3, 4, 5]
新数组长度
;var a = [1,2,3,4,5]; a.push(6);//[1, 2, 3, 4, 5, 6] aa.push('xx');//[1, 2, 3, 4, 5, 6, "xx"] 返回长度7 a.push('yy');//[1, 2, 3, 4, 5, 6, "xx", "yy"] 返回长度8
新数组长度
;var a = [1,2,3,4,5]; a.unshift();//[1, 2, 3, 4, 5] a.unshift("cc");//["cc", 1, 2, 3, 4, 5] 返回长度6 a.unshift("aaa");//["aaa", "cc", 1, 2, 3, 4, 5] 返回长度7
翻转后的原数组
,原数组翻转了var a = [1,2,3,4,5]; a.reverse()//a:[5, 4, 3, 2, 1] 返回[5, 4, 3, 2, 1]
字符串
,原数组木变
var a = [1,2,3,4,5]; var b=a.join('||');//b:"1||2||3||4||5" a:[1,2,3,4,5]
开始索引(包含)
到结束索引(不包含)
之间的项组成的新数组
,原数组木变 ,索引从0开始var a = ['a','b','c','d','e']; a.slice(1,3);//["b", "c"] a:['a','b','c','d','e'] a.slice(0,4);//["a", "b", "c", "d"] a.slice(3,4);//["d"] /*参数为1个*/ a.slice(2);["c", "d", "e"] //从第三个开始截取(包含),默认截到最后。索引为数组自己长度 a.slice(0);//['a','b','c','d','e'] //新数组和老数组同样 引用不同 值传递 引用传递 有关系 /*参数为0个*/ a.slice();//和a.slice(0)等价 //新数组和老数组同样 引用不同 值传递 引用传递 有关系 /*若是 slice()方法的参数中有一个负数,则用数组长度加上该数来肯定相应的位 置。例如,在一个包含 5 项的数组上调用 slice(-2,-1)与调用 slice(3,4)获得的 结果相同。若是结束位置小于起始位置,则返回空数组。*/ a.slice(3,4);//["d"] a.slice(-2,-1);//["d"] 这种方式:是从右面,最后一个元素开始计算的,右面的第一个为0,越靠左负数依次减一
剪接的元素数组
,原数组变化
,索引从0开始/*参数为0个*/ var a = ['a','b','c','d','e']; a.splice()//返回[] a:["a", "b", "c", "d", "e"] 截个空数组。 原数组没变。 /*参数为1个*/ var a = ['a','b','c','d','e']; a.splice(0);//['a','b','c','d','e']; a:[]//原数组清空[]。从第一位开始截取,长度默认数组长度。 var a = ['a','b','c','d','e']; a.splice(2);//返回["c", "d", "e"] 原数组a:["a", "b"] /*参数是2个*/ //第一参数是索引(从0开始),第二是长度 var a = ['a','b','c','d','e']; a.splice(0,2);//["a", "b"] a:["c", "d", "e"] a.splice(0,2);//["c", "d"] a:["e"] var a = ['a','b','c','d','e']; a.splice(0,1);//["a"] a:["b", "c", "d", "e"] 同shift前删除 var a = ['a','b','c','d','e'] a.splice(a.length-1,1)l//["e"] a:["a", "b", "c", "d"] 同pop前删除 var arr=[1,3,5,777,'e'] arr.splice(2,1) //arr:[1, 3, 777, "e"] 能够删除数组的随便的那个元素!! /*参数大于2个*/ //splice(start,deleteCount,val1,val2,...):从start位置开始删除deleteCount项,并从该位置起插入val1,val2,... var a = ['a','b','c','d','e']; a.splice(3,1,10,21,238,99);//["d"] a:["a", "b", "c", 10, 21, 238, 99, "e"] var a = ['a','b','c','d','e']; a.splice(a.length,100000000,88)//返回 [] 从最后元素后面的元素,截取长度任意个,确定是空 a:["a", "b", "c", "d", "e", 88] 同push后增长 var a = ['a','b','c','d','e']; a.splice(a.length,0,88)//返回 [] 从最后元素后面的元素,截取长度任意个,确定是空 a:["a", "b", "c", "d", "e", 88] 同push后增长 var a = ['a','b','c','d','e']; a.splice(0,0,88,99)//返回 [] 从第一个元素,截取长度0个 确定是空 a:[88, 99, "a", "b", "c", "d", "e"] 同unshift前增长
var a = ['a','b','c','d','e']; a.concat([88,99]);//["a", "b", "c", "d", "e", 88, 99] a:["a", "b", "c", "d", "e"] var b= [9999,10000] a.concat(b);// ["a", "b", "c", "d", "e", 9999, 10000] a:["a", "b", "c", "d", "e"]
//坑1:排序后,影响自己(而非生成新数组) //坑2:默认状况下sort方法是按ascii字母顺序排序的,而非咱们认为是按数字大小排序 var arr5=[100,19,52,502]; arr5.sort(); console.log(arr5); //arr5:[100, 19, 502, 52] //用法3:改变默认比较数字大小来排序 加入function(a,b){return a-b} //疑问4:a,b 表明.. arguments[0]和arguments[1]// function compare2Val(a,b){return a-b} var arr6=[100,19,52,502]; arr6.sort(compare2Val); //调用 不须要传参, console.log(arr6); //arr6: [19, 52, 100, 502] //调用 不须要传参的本质 function compare2Argument(){return arguments[0]-arguments[1]} var arr7=[100,19,52,502]; arr7.sort(compare2Argument); //[19, 52, 100, 502] console.log(arr7); //arr6: [19, 52, 100, 502] /*************总比较次数结论**************/ //疑问5 总比较次数:n(n-1)/2 n为数组长度 //答:1:各轮比较次数 的和 //答:2: (数组长度-1+数组长度-2+数组长度-3......+1) /* 例数组长度6 比较次数:5+4+3+2+1=15 例数组长度5 比较次数:4+3+2+1=10 例数组长度4 比较次数:3+2+1=6 //高中学的1+2+3+.....+n=? 答案: 设S=1+2+…+(n-1)+n, 则S=n+(n-1)+…+2+1 ∴2S=(1+n)+[2+(n-1)]+…+[(n-1)+2]+(n+1) =n(n+1) ∴S= n(n+1)/2, 即1+2+…+(n-1)+n= n(n+1)/2. */ //比较轮数:数组长度-1 每轮比较产生一个最大值放在数组最右,这个最大值不参与下轮比较 //当前轮比较次数:数组长度-当前轮数 /*************结论**************/ //轮数4()-1 3轮 //第一轮:4-1比较3次 [19,100,52,502]; [19,52,100,502]; [19,52,100,502]; 作3次比较 //第二轮:4-2 比较2次 抛弃502,--->[19,52,100,502]; [19,52,100,502]; 只作19 52 ,52 100的2次比较 //第三轮:4-3 比较1次 抛弃100,502--->[19,52,100,502]; 只作19 52 的1次比较 //5,开发中经常使用方式 //例:根据人的年龄排序 function person(name,age){ this.Name=name; this.Age=age } var personArray=[]; personArray.push(new person("LiKe",18)); personArray.push(new person("Tom",58)); personArray.push(new person("Lucy",22)); personArray.push(new person("Haimei",16)); function compareAge(a,b){ return a.Age-b.Age; } personArray.sort(compareAge); console.log(personArray);//Haimei LiKe Lucy Tom
ES5
函数Array.isArray(a)
判断a是否为为真正的Array
Array.isArray([]) //true Array.isArray({}) //false Array.isArray(11) //false Array.isArray(null) //false Array.isArray(undefined) //false
Array.prototype.indexOf(e,i)``起始位置i为可选
var arr=[1,5,7,'str','str','str',9,10] arr.indexOf('str')//3 arr.indexOf('str',4)//4 arr.indexOf('f');//-1
Array.prototype.lastIndexOf(e,i)``最后位置i为可选,默认arr.length-1
var arr=[1,5,7,'str','str','str',9,10] arr.lastIndexOf('str')//5 arr.lastIndexOf('str',4)//4 这是重点
如下context,都是灵活设置回调函数的执行上下文
测试some(fn,context)
数组中是否存在符合~.条件的元素
some(fn(value,index,array){return ..},undefined)``undefined可选,能够为undefined,能够灵活设置回调函数的执行上下文
,Array.prototype.some(fn,context)
var arr=[1,5,7,'str',[99]] arr.some(function(value,index,array){return Array.isArray(value)})//true //return“执行”的意思。 Array.isArray(value)“测试函数”的意思。“只要”元素value知足测试(测试返回true),some遍历函数返回true arr.some(function(value,index,array){return typeof(value)=='string'})//true
Array.prototype.every(fn,context)
var aa=[[],[1]]; aa.every(function(currentValue,index,array)){return Array.isArray(currentValue)}//true var bb=['',[]]; bb.every(function(currentValue,index,array){return Array.isArray(currentValue)},undefined)//false
返回经过测试fn的元素数组
Array.prototype.filter(fn,context)
var arr=[1,5,7,'str','str','str',9,10] arr.filter(function(value,index,array){return typeof(value)=='number'})//[1, 5, 7, 9, 10]
Array.prototype.reduce(fn,context)
,prev, cur, index, array
注意函数的参数通常来说prev是从数组中第一个元素开始的,cur是第二个元素
.可是当你传入初始值(initialValue)后,第一个prev将是initivalValue,cur将是数组中的第一个元素。
//预先知道:15+[6]=156 var values = [1,2,3,4,5,[6]]; var i = 0; var sum = values.reduce(function (prev, cur, index, array) { console.log('头值:',prev, '当前值',cur,'比较次数:',++i,'cur的索引:',index);//prev第一次循环,为第一个值。之后的循环的值,是逻辑出来算的 return prev + cur;//获得的头值,参与下次循环,赋值给prev。固然下次循环 头值也会和下次的当前值进行此种逻辑(这里是加) }); console.log(sum); /* 结果 头值: 1 当前值 2 比较次数: 1 cur的索引: 1 头值: 3 当前值 3 比较次数: 2 cur的索引: 2 头值: 6 当前值 4 比较次数: 3 cur的索引: 3 头值: 10 当前值 5 比较次数: 4 cur的索引: 4 头值: 15 当前值 [6] 比较次数: 5 cur的索引: 5 156 */ /*第二个例子,参考张鑫旭的例子*/ var matrix = [ [1, 2], [3, 4], [5, 6] ]; // 二维数组扁平化 var flatten = matrix.reduce(function (previous, current) { console.log(previous);//2次循环 length-1 return previous.concat(current); }); console.log(flatten);//[1, 2, 3, 4, 5, 6] /* [1, 2] [1, 2, 3, 4] */ /*第三个例子,里面用到了es6的of方法,将类数组,类数组变量转变成数组。相似new Array*/ var matrix = [ 999, [3, 4], [5, 6] ]; // 二维数组扁平化 var flatten = matrix.reduce(function (previous, current) { if (!Array.isArray(previous)) { previous = Array.of(previous); } return previous.concat(current); }); console.log(flatten);//[999, 3, 4, 5, 6] /*第四个例子,2个参数 参考:http://www.jb51.net/article/60502.htm*/ var arr = ["apple","orange"]; function noPassValue(){ return arr.reduce(function(prev,next){ console.log("prev:",prev); console.log("next:",next); return prev + " " +next; }); } function passValue(){ return arr.reduce(function(prev,next){ console.log("prev:",prev); console.log("next:",next); prev[next] = 1; return prev; },{}); } console.log("No Additional parameter:",noPassValue()); console.log("----------------"); console.log("With {} as an additional parameter:",passValue()); /* prev: apple next: orange No Additional parameter: apple orange ---------------- prev: Object {} next: apple prev: Object {apple: 1} next: orange With {} as an additional parameter: Object {apple: 1, orange: 1} */ //第5个例子:统计一个数组中有多少个不重复的单词 var arr = ["apple", "orange", "apple", "orange", "pear", "orange"]; function getWordCnt() { return arr.reduce(function (prev, next) { console.log(prev, next); prev[next] = (prev[next] + 1) || 1; //修改本次prev return prev;//返回的这个值,做为下次循环的prev的值 ,在前面外面能够将本次的prev变成任何类型 本质延伸到了initialValue设置的类型 }, {}); } console.log(getWordCnt()); Object {} "apple" Object {apple: 1} "orange" Object {apple: 1, orange: 1} "apple" Object {apple: 2, orange: 1} "orange" Object {apple: 2, orange: 2} "pear" Object {apple: 2, orange: 2, pear: 1} "orange" Object {apple: 2, orange: 3, pear: 1}
Array.prototype.reduceRight(r,v)
是Array.prototype.reduce的从右向左的版本。var matrix = [ 999, [3, 4], [5, 6] ]; var flatten = matrix.reduceRight(function (previous, current) { console.log(previous, current); if (!Array.isArray(previous)) { previous = Array.of(previous); } return previous.concat(current); }); /* [5, 6] [3, 4] [5, 6, 3, 4] 999 */
Array.prototype.forEach(fn,context)
,val, index, arr
[1, 2, 'str', ['a'], true].forEach(function (val, index, arr) { if (val) { console.log(val, index) } }) /* 1 0 2 1 str 2 ["a"] 3 true 4 */ {a:1,b:2}.forEach(function(val,index,obj){if(val){console.log(val)}})//object 报错
Array.prototype.map(fn,context)
,因此在fn中必定有return,参数必须是val,index,array
。这个fn能够是自定义,也能够是js内置的方法好比Math.sqaure使用函数fn修改每一个元素
,按顺序收集f的每一个返回值
,返回这个新组成的数组
。this
//参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map 第一:每项单词转换成对应的复数形式. function fuzzyPlural(single) { var result = single.replace(/o/g, 'e'); if( single === 'kangaroo'){ result += 'se'; } return result; } var words = ["foot", "goose", "moose", "kangaroo"]; console.log(words.map(fuzzyPlural)); // ["feet", "geese", "meese", "kangareese"] 第二:求数组中每一个元素的平方根 var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); /* roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9] */ 第三:String 上使用 map 方法获取字符串中每一个字符所对应的 ASCII 码组成的数组: var map = Array.prototype.map var a = map.call("Hello World", function(x) { return x.charCodeAt(0); }) // a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] 第四:一般状况下,map 方法中的fn函数只须要接受一个参数,就是正在被遍历的数组元素自己。但这并不意味着 map 只给fn传了一个参数。这个思惟惯性可能会让咱们犯一个很容易犯的错误。 // 下面的语句返回什么呢: ["1", "2", "3"].map(parseInt); // 你可能觉的会是[1, 2, 3] // 但实际的结果是 [1, NaN, NaN] // 一般使用parseInt时,只须要传递一个参数.但实际上,parseInt能够有两个参数.第二个参数是进制数.能够经过语句"alert(parseInt.length)===2"来验证. // map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, 元素索引, 原数组自己. // 第三个参数parseInt会忽视, 但第二个参数不会,也就是说,parseInt把传过来的索引值当成进制数来使用.从而返回了NaN. /* //应该使用以下的用户函数returnInt function returnInt(element){ return parseInt(element,10); } ["1", "2", "3"].map(returnInt); // 返回[1,2,3] *
权威指南定义es5
// Determine if o is an array-like object.断定o是不是一个类数组对象 // Strings and functions have numeric length properties, but are 字符串和函数有length属性,可是它们 // excluded by the typeof test. In client-side JavaScript, DOM text能够用typeof检测将其排除,在客户端js中,DOM文本节点 // nodes have a numeric length property, and may need to be excluded 也有length属性,须要额外判断o.nodeType!=3将其排除 // with an additional o.nodeType != 3 test. function isArrayLike(o) { if (o && // o is not null, undefined, etc. o非null undefined等 typeof o === 'object' && // o is an object o是对象 isFinite(o.length) && // o.length is a finite number o.length是个有限数值 o.length >= 0 && // o.length is non-negative o.length是非负值 o.length===Math.floor(o.length) && // o.length is an integer o.length是整数 o.length < 4294967296) // o.length < 2^32 o.length小于2^32 return true; // Then o is array-like else return false; // Otherwise it is not //不然它不是类数组 }
1:是{ 含有length键值对}2:[]都是类数组
//1:{ 含有length属性的键值对} isArrayLike({qq:"aa",ww:"bbb",ss:"ccc",length:3})//true isArrayLike({"0":"aa",1:"bbb",2:"ccc",length:3})//true 特殊的类数组 //2:[]普通数组 isArrayLike([])//true
像数组同样使用类数组(对象的属性是“数值”字符串,'0' '1' '2' '3'....)
/* 由于这些"{ 含有length属性的键值对}"类数组对象,不是经过new Array()构造函数构造出来的,因此这些不具有Array的原型方法。 可是咱们可使用改变做用域的方式来使用,[].map.call({},fn),[].slice.call({},..)等数组方法 若是想一想数组同样使用它们,除了加上length属性,须要这样作: 须要保证这个对象的属性必须是“数值”字符串,'0' '1' '2' '3'.... */ [].map.call({0:"aa",1:"bbb",2:"ccc",length:3},function(val){return val+"ooooooo"})//["aaooooooo", "bbbooooooo", "cccooooooo"] //常使用的功能:类数组对象转化为数组 [].slice.call({0:"aa",1:"bbb",2:"ccc",length:3},0)//["aa", "bbb", "ccc"]
/* 注意: 函数的内置对象arguments自己就是类数组,自己不能使用Array的原型实例方法,但能够经过call等改变做用域的方式来使用; */ //arguments a(1,"2") function a(){ console.log(arguments);//[1, "2"],这里打印出的虽然是[],看上去是数组,可是展开的以下图,和普通数组不同。 //console.log(arguments.slice())//这样会报错: Uncaught TypeError: arguments.slice is not a function console.log([].slice.call(arguments));//[1, "2"] } console.log([].slice.call({0:"a",1:"bbb",2:"ccc",str:"str",str2:"str2",length:5}))//slice会把属性不为数字的类数组去掉 //NodeList var falseArr=document.getElementsByTagName('div'); for(item in falseArr)console.log(item)//能够看到,item是 0 1 2 3...还有一些 id class等,证实NodeList是类数组 //falseArr.slice()//报错 console.log([].slice.call(falseArr))
截图
var str="asfwefwgw"; for(i=0; i<str.length;i++){console.log(i)} for(i=0; i<str.length;i++){console.log(str[i])}
//特殊类数组(键是数字) var o={"0":"aa",1:"bbb",2:"ccc",length:3};Array.from(o);//["aa", "bbb", "ccc"] //通常类数组 var o={qq:"aa",ww:"bbb",ss:"ccc",length:3};Array.from(o);//[undefined, undefined, undefined]
//类数组nodeList不能直接使用数组实例方法,要call apply改变做用域才能够 var nodes=document.getElementsByTagName('a'); // nodes.forEach(function(val,key){console.log(key);})//nodes.forEach is not a function //es5 //Array.prototype.forEach.call ,[].forEach.call [].forEach.call(nodes,function(val,key){console.log(key);}) //es6 var nodesArray=Array.from(nodes); nodesArray.forEach(function(val,key){console.log(key);})
//类数组arguments不能直接使用数组实例方法,要call apply改变做用域才能够 function foo(){ //arguments.forEach(function(val,index){console.log(index)})//arguments.forEach is not a function Array.prototype.forEach.call(arguments,function(val,index){console.log(index)})//1,2,3 Array.from(arguments).forEach(function(val,index){console.log(index)})//1,2,3 } foo(1,2,3)
//字符串
//Set
//Map
if (typeof Array.prototype.forEach != "function") { Array.prototype.forEach = function (fn, context) { for (var k = 0, length = this.length; k < length; k++) { if (typeof fn === "function" && Object.prototype.hasOwnProperty.call(this, k)) fn.call(context, this[k], k, this); } }; } if (typeof Array.prototype.map != "function") { Array.prototype.map = function (fn, context) { var arr = []; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { arr.push(fn.call(context, this[k], k, this)); } } return arr; }; } if (typeof Array.prototype.filter != "function") { Array.prototype.filter = function (fn, context) { var arr = []; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { fn.call(context, this[k], k, this) && arr.push(this[k]); } } return arr; }; } if (typeof Array.prototype.some != "function") { Array.prototype.some = function (fn, context) { var passed = false; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { if (passed === true) break; passed = !!fn.call(context, this[k], k, this); } } return passed; }; } if (typeof Array.prototype.every != "function") { Array.prototype.every = function (fn, context) { var passed = true; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { if (passed === false) break; passed = !!fn.call(context, this[k], k, this); } } return passed; }; } if (typeof Array.prototype.indexOf != "function") { Array.prototype.indexOf = function (searchElement, fromIndex) { var index = -1; fromIndex = fromIndex * 1 || 0; for (var k = 0, length = this.length; k < length; k++) { if (k >= fromIndex && this[k] === searchElement) { index = k; break; } } return index; }; } if (typeof Array.prototype.lastIndexOf != "function") { Array.prototype.lastIndexOf = function (searchElement, fromIndex) { var index = -1, length = this.length; fromIndex = fromIndex * 1 || length - 1; for (var k = length - 1; k > -1; k-=1) { if (k <= fromIndex && this[k] === searchElement) { index = k; break; } } return index; }; } if (typeof Array.prototype.reduce != "function") { Array.prototype.reduce = function (callback, initialValue ) { var previous = initialValue, k = 0, length = this.length; if (typeof initialValue === "undefined") { previous = this[0]; k = 1; } if (typeof callback === "function") { for (k; k < length; k++) { this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this)); } } return previous; }; } if (typeof Array.prototype.reduceRight != "function") { Array.prototype.reduceRight = function (callback, initialValue ) { var length = this.length, k = length - 1, previous = initialValue; if (typeof initialValue === "undefined") { previous = this[length - 1]; k--; } if (typeof callback === "function") { for (k; k > -1; k-=1) { this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this)); } } return previous; }; }
参考:
MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/