1.基本类型和复杂类型的一个区别
1.1基本数据类型:以number类型为例
Number(xxx) //报错,Error: xxx is not defined
Number('xxx') //NaN,NaN是非数值,一个特殊的数值
Number(1) //1 一个单纯的数字
Number('1') //1 一个单纯的数字
new Number(1) //Number{1},一个对象,具有对象方法
也就是说Number()创建的是基本数据类型,new Number()创建的是一个对象,同理String,Boolean。
1.2复杂数据类型:Object
Object('x') // String {"x"},一个对象 (非数字一定要加引号)
new Object('x') // String {"x"},一个对象
对于复杂类型Object来说,两者方法是一样的,都是创建的对象。
2.什么是数组
ECMAScript数组和其他语言的数组一样,都是数据的有序列表,和其他语言不同的是JS中的数组的每一项都可以保存任何数据类型,且数组大小可以动态调整,即随着数据的添加自动增长以容纳新数据。
在JS中,数组的本质是原型链中有Array.prtotype的对象。
let obj = {
0:'1',
1:'2',
length:2;
} // 看起来像数组,但没有Array.prototype的,是伪数组
a = [1, 2] // 是真的数组,有Array.prototype,也就是说有pop和push方法
常见伪数组:arguments,DOM API获得的数组:NodeList 等
3.数组的遍历
3.1 for的两种遍历
首先我们定义一个复杂的数组:
var obj = {
'xx' : 1,
'yy' : 2,
'length' : 2}
var a = [1, 2, 'x', obj, 5, 'b'] // a是一个数组
第一种for遍历:
for (let i=0; i<a.length;i++){ // 这种for遍历只打印下标是数字的项,对于数组来说下标都是数字
console.log(i + ':' + a[i])
} // 打印结果 0:1 1:2 2:x 3:[object Object] 4:5 5:b
for (let i=0; i<obj.length;i++){ // 这种for遍历只打印下标是数字的项,对于obj来说就不一样了
console.log(i + ':' + obj[i])
} // 打印结果 0:undefined 1:undefined
第二种for遍历:
for (key in obj){ // 打印全部东西
console.log(key + ':' + obj[key])
} // 打印结果 xx:1 yy:2 length:2
对于数组和for(let...)一样,不赘述
3.2 forEach的遍历
forEach是接受一个函数为参数的API
a.forEach( function(x,y){
console.log('value', x)
console.log('key', y)
})
4.数组的常用API
4.1 join 连接成一个字符串返回
a = [1, 2, 3]
a.join() <=> a.join(',') // 字符串 "1, 2, 3"
a.join('嘿嘿') // 字符串 "1嘿嘿2嘿嘿3"
a + '' // 字符串 "1, 2, 3"
a.toString() // 字符串 "1, 2, 3"
4.2 concat 联结数组
var a = [1,2,3]; var b = [3,4,5];
var c = a.concat(b); //'1,2,3,3,4,5'
var d = a.concat([]); //'1,2,3',将a数组深拷贝给d数组
4.3 map 映射,有返回值的数组遍历
var a = [1,2,3];
a.map(function(value,key){
return value * 2;
}) //[2,4,6];
a.map(value => value * 2); //[2,4,6]
4.4 filter 过滤数组
var a = [1,2,3,4,5];
a.filter(function(value,key){
return value >= 3;
}) //[3,4,5]
a.filter(function(value,key){
return value % 2 === 0 ;
}) //返回偶数,[2,4]
4.5 sort 排序,reverse 反转数组
这两个API都会 改变原数组
var c = [2,3,1];
c.sort(); // [1,2,3],默认从小到大排序
c // [1, 2, 3]
c.sort(function(a,b){return b-a}) // [3,2,1],从大到小排序
c.reverse() // [3, 2, 1] 因为sort已经更改了原数组了,所以不是返回 [1, 3, 2]
4.6 reduce 归并方法
迭代数组中的所有项,构建一个最终的返回值
4.6.1 reduce实现map方法
a = [2, 4, 6]
a.reduce(function(arr,n){
console.log(arr, n) // 为了更清晰看出reduce方法的执行
arr.push(n*2);
return arr;
},[])
// [] 2 []的值赋给了arr,当前值n是2
// [4] 4
// [4, 8] 6
// [4, 8 ,12] 这是return返回的数组arr
4.6.2 reduce实现filter方法
a.reduce(function(arr,n){
if(n % 2 === 0){
arr.push(n)
}
return arr;
},[])
4.6.3 reduce实现数组求和
var total = [ 0, 1, 2, 3 ].reduce(
( acc, cur ) => acc + cur
); // total === 6
4.6.4 reduce实现数组去重
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current)=>{
if(init.length===0 || init[init.length-1]!==current){
init.push(current);
}
return init;
}, []);
console.log(result); //[1,2,3,4,5]
ES6实现数组去重:
let array = Array.from(new Set([1,2,1,2,3,5,4,5,3,4,4,4,4]));
//Set数据结构,类似于数组,但是它成员都是唯一的
//静态方法Array.from,可以把类似数组的对象转换为数组
console.log(array); //[1,2,3,4,5]
4.6.5 reduce实现数组计数
计算字符串中每个元素出现次数:
var arrString = 'abcdaabc1331';
arrString.split('').reduce(function(res, cur) {
res[cur] ? res[cur] ++ : res[cur] = 1
return res;
}, {}) // {1: 2, 3: 2, a: 3, b: 2, c: 2, d: 1},空元素也是可以计算的
4.7 splice 数组的删除,插入与替换操作
splice方法会 改变原数组
splice方法始终会返回一个包含从原始数组中删除的项,没有删除就返回空数组
arr.splice(开始位置,删除个数 ) //从开始位置删除,执行后arr数组已改变,arr.splice返回删除项
arr.splice(开始的位置, 删除的个数, 插入的数据1, 插入的数据2, 3...)
4.8 slice 基于当前数组创建新数组
不改变原数组
array.slice() //或array.slice(0),返回完整数组
array.slice(4) //返回位置4到最后的数据
array.slice(4,8) //返回位置4到7的数据