学习目标
ES6新的数字方法,帮助我们更容易的处理数据
- Array.from
- Array.of
- Array.prototype.fill
- Array.prototype.includes
- Array.prototype.find
思考
Jquery代码片段,使用css方法获取所有DOM节点,并将其设置为红色,如果不使用Jquery提供的方法,我们必须使用document.querySelectorAll,那么如何来遍历节点更新颜色?
$('.danger').css('color','red')
//我们都知道document.querySelectorAll方法返回的是一个NodeList伪数组
let domArr=document.querySelectorAll('.danger') //NodeList[]
复制代码
Array.from构建数组
案例:编写一个函数求平均数,这个函数接受任何的数字作为参数,然后返回平均值
function svg(){
const sum = arguments.reduce(function(a,b){
return a + b
})
return sum / arguments.length
}
console.log(svg(1,2,3,4)); //返回错误消息,因为arguments是伪数组
复制代码
上面的函数是错误的,运行会报错arguments.reduce不是一个函数
,所以我们需要将arguments转换为真正的数组。
ES6以前,我们将伪数组转换为数组的一种通用方式,是在伪数组的对象上使用Array.prototype.slice的方法,在数组上调用slice方法而不传任何参数的情况下会简单的创建一个浅副本数组,在类似数组的对象上使用也可以.
Array.prototype.slice.call(arrayLikeObject);
//或者使用简单的版本
[].slice.call(arrayLikeObject)
复制代码
所以我们使用这个方法将arguments转化为真正的数组
function svg(){
const args = [].slice.call(arguments)
const sum = args.reduce(function(a,b){
return a + b
})
return sum / args.length
}
console.log(svg(1,2,3,4)); //2.5
复制代码
终极方案
/*
接受一个类似数组的对象,获得真正的数组
类似数组的对象也就是上面我说的伪数组,是指具有length属性的任何对象
*/
Array.from(arguments)
复制代码
开篇案例重写
let domArr=document.querySelectorAll('.danger') //NodeList集合
let nodesArr=Array.from(domArr);
nodesArr.forEach(function(v,i,a){
//....
})
复制代码
注意:Array.from也可以任何拥有length属性的对象上使用,即使这个对象仅有length属性
Array.length({length:30})
/*
上面这段代码和 new Array(30)完全一样,创建了一个新数组,但是我们
如果仅仅是想创建只有单一值为30的数组呢?
*、
复制代码
Array.of构建数组
上面svg求平均数案例中,如果此时我们只给一个参数,那么这个svg函数应该返回本身对不对?毕竟一个数的平均数就是其本身,但是Array构造函数中有一个特殊行为,如果只有一个参数,并且为整数,那么他就创建一个长度为n的稀疏数组,其中n就是作为参数传入的数字,为了避免这个情况发生,es6给我们提供了Array.of的方法创建
let arr1=new Array(2) //创建c长度为2的空数组 [empty × 2]
let arr2=Array.of(2) // 单个值 [2]
复制代码
继续思考两个问题
1.我们为什么不直接使用字面量方式创建呢?
2.我们不光要创建单个数组2,有时候确实需要创建具有2个数值的数组呢?
Array.prototype.fill 构建数组
案例:编写一个井字棋游戏,需要初始化一个3*3的网格,我们通过一个数组表示,此数组需要使用九个空格来初始化
//错误代码
const board=new Array(9).map(function(i){
return ''
})
/*
错误思维:初始化九个未定义的值初始化数组,然后利用map转换为空格
new Array(9)创建数组时
{
length:9
}
并不是
{
lengt:9,
0:undefined,
1:undefined,
2:undefined,
3:undefined,
....
8:undefined
}
数组会从Array.prototype继承一些方法,执行迭代操作时,数组会在内部先检查长度,然后从索引为0开始等于length时结束,查看自身的任何属性
*/
复制代码
上面案例 length为9,而并不是实际有9个值,我们称这些缺失值为hole(孔),孔不能调用map这样的方法,因此这就是我们不能初始化创建九个空格字符串的原因,ES6给我们提供了一个fill()方法,可以指定值填充数组
const board=new Array(9).fill('*')
console.log(board); //[ '*', '*', '*', '*', '*', '*', '*', '*', '*' ]
复制代码
思考二者区别
let arr1=new Array(9).map(function(){
return ''
})
let arr2=new Array(9).fill(1)
console.log(arr1); //[ <9 empty items> ]
console.log(arr2); //[ 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
复制代码
Array.prototype.includes搜索数组
- 字符串的原型上有个includes方法,用来确定字符串是否包含了某个值
- 数组的原型也有一个includes方法,检查的是数组某个索引出的值是否为所检查的值
const A='a';
const B='b';
const C='c'
const CARD=[A,B,C]; //卡片
let optionA='a'
let optionB='b'
let optionC='ccc'
console.log(CARD.includes(optionA)) //true
console.log(CARD.includes(optionB)) //true
console.log(CARD.includes(optionC)) //false
复制代码
我们也可以 使用indexOf确定某个值是否在数组内部,但是如果实际开发中忘记将结果与-1而不是真值进行比较,往往会发生错误
/*
给定制的索引在0处就会返回0,也就是falsy值,反之找不到值就返回-1 也就是truthy值
falsy值是判定位false的任何值:false,undefined,null,NaN,0和空字符串
truthy值是判定为true的任何值,包括负数
*/
console.log(CARD.indexOf('a')); //0
console.log(CARD.indexOf('b')); //1
console.log(CARD.indexOf('aaa')); //-1
复制代码
使用Array.prototype.find搜索数组
对比Array.prototype.filter方法
- 假设1000条数据,如果找到第一条匹配就返回此数据 1.filter目标是返回所有匹配记录,查找后第一条,会继续检查剩余的 2.find只要找到匹配项,就立刻停止搜索数组 3.find的另一个好处就是,它返回的是匹配的项,而不是匹配项的数组,因此无需将匹配项从数组中提出来,可以直接返回find的结果
let arr=[1,2,3,4,5,6,7,8,9]
let res=arr.find(function(val){
return val>2
})
console.log(arr);
console.log(res); //返回3 而不是[3,4,5,6,7,8,9]
复制代码
重新开头的Jquery的css方法
function $(selector){
let nodes=document.querySelectorAll(selector);
return {
css:function(prop,value){
Array.from(nodes).forEach(function(node){
node.style[prop]=value;
})
return this
}
}
}
复制代码