方法
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;
}
};
}
网友评论