javascript学习笔记——Array
Array介绍
Array是JavaScript的内置对象,同时也是一个构造函数
new Array(2) === Array(2),这个需要跟Boolean, Number, String 区分开
new Boolean(1) !== Boolean(1), String 和Number也一样,前者是一个对象,后者是一个值
var d = [1, 2].map(function(e) { return this[e]; }, arr); var e = new Array(2); console.log("arr", d, arr, e, e[0]); //arr Array(2) Array(3) Array(2) undefined
//new Array只是申请了空间,并没有具体的定义,故e[0]=undefined.new后的数组对象直接取键值是取不到的(map啥的不会触发函数)
Array最大的特点是参数不同生成的对象就不同,针对其这种行为,一般不使用Array申明而直接用'[]':
无参数 ——空数组
数字参数——对应空间的数组
小数,负数的参数——报错 (0作为参数生成空数组)
单个非Number的参数——参数作为数组成员返回一个长度为1的数组
多参数——所有参数为数组成员,返回数组
静态方法
Array.isArray() 弥补typeof:
var a = [1, 2, 3]; typeof a // "object" Array.isArray(a) // true
实例方法
valueOf() 返回对象本身
toString() 返回数组的字符串形式(中间家逗号 eg [1,2,3]——1,2,3)
push() 参数可以是多个,末端添加元素,返回新的数组长度,改变原数组
使用call调用,向对象中加入元素,是对象变为类数组结构(key=0,1,2,3... value=实际的value):
var a = {a: 1}; [].push.call(a, 2); a // {a:1, 0:2, length: 1} [].push.call(a, [3]); a // {a:1, 0:2, 1:[3], length: 2}
pop() 删除数组的最后一个元素,并返回该元素,改变原数组,与push形成栈结构,空数组调用pop()不报错,而是返回为undefined
join()将数组元素以指定分隔符连接起来并返回该字符串, 为空默认逗号。如果数组有位置为空则会转成空位(''),也可用call对类似数组对象使用
var obj = { 'c': 123, 0: 'a', 1: 'b', length: 3 }; var re = Array.prototype.join.call(obj, '-') console.log(re); // 'a-b-'
concat() 合并数组,新建原数组的一级拷贝(数组里的对象为浅拷贝),将新成员添加到新建数组的尾部,返回新建数组,所以原数组不会发生变化,接受多个参数,按顺序添加到尾部。call调用:
[].concat.call({a: 1}, {b: 2}) // [{ a: 1 }, { b: 2 }] [].concat.call({a: 1}, [2]) // [{a: 1}, 2] [2].concat({a: 1}) // [2, {a: 1}]
shift() 删除数组第一个元素并返回该元素,改变数组,与push()构成队列结构
unshift()添加元素到首位,返回数组长度,改变数组
reverse()颠倒数组顺序,返回改变后的数组,改变原数组
slice() 提取数组一部分,返回提取的数组,原数组不变,第一个参数为起始位置,第二个参数为终止位置,无第二个参数就是包括后续所有成员,第二个参数太大就复制到最后一个参数结束,slice()没有参数就是从零开始。
参数为负数表示从末尾计数,-1就是倒数第一个,第二个参数小于第一个参数返回空数组。call调用:
Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 }) // ['a', 'b']
splice() 删除数组的一部分,并可在删除的位置添加新成员,返回被删除的成员,改变原数组。 第一个参数是删除的位置(0开始),第二个参数是删除的个数,后面的参数为插入的成员。第一个参数如果是负数表示倒着开始计数,第二个参数可以是0,表示不删除,第二个参数没有表示删除后面所有的。
sort() 字典方法排序(按照字符串的方式排序),可以自定义函数作为参数,进行自定义排序
map() 对数组成员依次调用函数根据函数结果返回新数组,原数组不变。参数函数接受三个参数(ele,index,arr)分别是当前成员,当前成员位置,原数组。可以使用call对类似数组结构的对象(或字符串)调用:
var upper = function (x) { return x.toUpperCase(); }; [].map.call('abc', upper) // [ 'A', 'B', 'C' ] // 或者 'abc'.split('').map(upper) // [ 'A', 'B', 'C' ]
map()还可以接受第二个参数,表示回调函数执行时的this指针:
var arr = ['a', 'b', 'c']; [1, 2].map(function(e){ return this[e]; }, arr) // ['b', 'c']
var f = function(n){ return n + 1 }; [1, undefined, 2].map(f) // [2, NaN, 3] [1, null, 2].map(f) // [2, 1, 3] [1, , 2].map(f) // [2, , 3]
map会跳过空位,但是不会跳过null和undefined
var a = Array(2).map(function() { console.log('enter...'); return 1; }) console.log("a", a, Array(2)); // [empty × 2] [empty × 2]
forEach()方法与map一致,但是没有返回值,原数组不变。作为第一个参数的函数也接受三个值(ele,index,arr)也可以接受第二个参数,作为参数函数的this指针。
var obj = { name: '张三', times: [1, 2, 3], print: function () { this.times.forEach(function (n) { console.log(this.name); }); } }; obj.print() // 没有任何输出,this.times的this指向obj,内部的this.name的this指向window
var obj = { name: '张三', times: [1, 2, 3], print: function () { this.times.forEach(function (n) { console.log(this.name); }, this); } }; obj.print() // 张三 // 张三 // 张三
forEach()方法也可以用call调用rray.prototype.forEach.call
(obj,func)
filter() 参数是一个函数,所有数组成员都会执行这个函数,函数接受三个参数(ele,index,arr),函数返回为true的将加入新数组, filter()结果返回这个新数组,原数组不变。也可接受第二个参数,表示测试函数内部的this对象。
some(),every() some()接受一个函数,函数有3个参数(ele,index,arr),只要有一个返回true,结果返回为true。every()则是所有都返回为true,结果才为true. some和every也接受第二个参数,表示函数的this指针。注意,对于空数组,some()返回为false,every返回为true.
reduce(),reduceRight() 依次处理数组的每个成员,最终累计为一个值,reduce从左到右处理,reduceRight从右到左处理。这俩方法的第一个参数都是一个函数,函数接受4个参数:
- 累积变量,默认为数组的第一个成员
- 当前变量,默认为数组的第二个成员
- 当前位置(从0开始)
- 原数组
前两个必须:
[1, 2, 3, 4, 5].reduce(function(x, y){ console.log(x, y) return x + y; }); // 1 2 // 3 3 // 6 4 // 10 5 //最后结果:15
这两个方法可以接受第二个参数,为初始累计值:
[1, 2, 3, 4, 5].reduce(function(x, y){ return x + y; }, 10); // 25
这两个方法可以用来找出数组中的某个特定值(最大值或最小值等)
indexOf() 和lastIndexOf() 返回给定元素第一次出现的位置,没有则为-1,lastIndexOf
方法返回给定元素在数组中最后一次出现的位置,如果没有出现则返回-1
。特别注意NaN这个数字。NaN!==NaN ,NaN
是唯一一个不等于自身的值。 所以:
[NaN].indexOf(NaN) // -1 [NaN].lastIndexOf(NaN) // -1