这是我参与更文挑战的第7天,活动详情查看:更文挑战
JSON拓展
parse
该方法是将json字符串解析为js对象的 使用方式: JSON.parse(str, fn)
str: 要处理的字符串
fn: 要处理的函数
返回值就是本次处理的结果
有两个参数
第一个参数: 属性名称
第二个参数: 属性值
从外部向内部遍历
举例:
// 定义json字符串
var str = '{"a": 1, "b": "2", "c": {"d": 3}}';
// 将str转为js对象
var result = JSON.parse(str, function(key, value) {
console.log(arguments);
// 对属性值进行判断
if (typeof value === "string") {
return +value;
}
return value;
});
输出:
// 我们希望将字符串转为数字
console.log(result);
结果:
stringify
该方法用于将js对象转为json字符串
使用方式: JSON.stringify(obj, fn)
obj: 要处理的对象
fn: 处理的函数
返回值就是本次处理的结果
有两个参数
第一个参数: 属性名
第二个参数:属性值
从内部向外部遍历
举例:
// 定义对象
var obj = {
a: 1,
b: "2",
c: {
d: 3
}
}
// 将obj转为json字符串
var result = JSON.stringify(obj, function(key, value) {
console.log(arguments);
// 我们想让所有的属性值作为数字保留
// 要对value进行判定
if (typeof value === "string") {
return +value;
}
return value;
});
输出:
console.log(result);
结果:
数组拓展
判断数组
第一种方式 判断对象类型是数组
Object.prototype.toString.call(obj)
第二种方式 判断构造函数是否是Array
obj.constructor === Array
第三种方式 判断是否是实例化对象
obj instanceof Array
第四种方式 判断数组的静态方法isArray
Array.isArray(obj)
举例:
// 第一种 instanceof
console.log(arr instanceof Array);
// 判断数组是准确的, 但是构造函数是Object也是true
console.log(arr instanceof Object);
console.log(obj instanceof Array);
// 第二种 constructor
console.log(arr.constructor === Array);
console.log(arr.constructor === Object); // false
console.log(obj.constructor === Array);
// 第三种 toString
console.log(Object.prototype.toString.call(arr) === "[object Array]");
console.log(Object.prototype.toString.call(obj) === "[object Array]");
// 第四种 数组的静态方法
console.log(Array.isArray(arr));
console.log(Array.isArray(obj));
获取成员的索引值
ES5为数组拓展了两个方法: indexOf, lastIndexOf , 分别用于获取数组中成员的索引值
参数就是要查找的成员
返回值就是成员的索引值
如果没有找到成员, 返回-1
在查找成员的时候不会做数据的类型转为,是真正的全等查找
举例:
// 兼容IE8
// 实例化对象拥有的方法应该在类的原型上
if (!Array.prototype.indexOf) {
// 拓展方法
Array.prototype.indexOf = function(item) {
// 遍历数组,就是遍历this
for (var i = 0; i < this.length; i++) {
// i 表示 索引值 arr[i] 表示成员值
// 判断arr[i]是否与item全等
if (arr[i] === item) {
// 如果找到成员,返回索引值
return i;
}
}
// 遍历完毕后,没有找到就返回-1
return -1;
}
}
forEach
该方法用于代替for循环,是数组的迭代器方法,并没有将for循环移除, 只是将循环封装在了数组迭代器方法forEach中。
使用方式: 数组.forEach(fn)
fn: 要执行的函数
有三个参数:
第一个参数:成员值
第二个参数:索引值
第三个参数: 原数组
作用域是window
函数的返回值对forEach的执行结果是没有影响的
forEach方法的返回值始终是undefined
jQuery中也有一个类似的方法, each方法,与forEach方法的区别是: 在jquery中的each方法,第一个参数是索引值,第二个参数是成员值
map
该方法用于遍历数组并映射结果, 与forEach方法类似,只是它的返回值是有意义的
参数是要执行的函数
函数中有3个参数:成员值, 索引值, 原数组
作用域是window
返回值就是执行结果的数组成员
map方法的返回值是一个新的数组,数组中的成员就是每一次函数执行的结果的成员
举例:
// 兼容IE8
if (!Array.prototype.map) {
// 拓展方法
Array.prototype.map = function(fn) {
// 创建数组结果容器
var result = [];
// 遍历数组
for (var i = 0; i < this.length; i++) {
// 执行fn并传递参数
// 传递三个参数: 成员值 this[i], 索引值 i, 原数组 this
result.push(fn(this[i], i, this));
}
// 返回新数组
return result;
}
}
fill
该方法用于填充数组 我们在使用new Array(len) 或者Array(len)来创建数组的时候,得到的只有长度没有成员,所以我们不能使用数组的迭代器方法(forEach, map), 就要填充数组
参数就是要填充的成员 即使是函数也不会执行
举例:
// 兼容IE8
if (!Array.prototype.fill) {
// 拓展方法
Array.prototype.fill = function(item) {
// 遍历数组
for (var i = 0; i < this.length; i++) {
// 填充数组
this[i] = item;
}
// 返回填充后的数组
return this;
}
}
some
数组中是否有成员满足条件
使用方式和forEach类似
参数就是要执行的函数
有三个参数: 成员值, 索引值, 原数组
返回值就是判断的依据
some方法的返回值:
true: 至少有一个成员满足条件
false: 都不满足条件
some方法对true敏感, 一但满足条件就立即停止遍历
举例:
// 兼容IE8
if (!Array.prototype.some) {
// 拓展方法
Array.prototype.some = function(fn) {
// 遍历数组 也就是遍历this
for (var i = 0; i < this.length; i++) {
// 执行函数 并判断结果
// 传递三个参数: 成员值 this[i], 索引值 i, 原数组 this
if (fn(this[i], i, this)) {
// 如果有满足条件的
return true;
}
}
// 遍历完毕, 没有成员满足条件, 返回false
return false;
}
}
every
数组中是否都满足条件
使用方式与forEach类似
参数就是要执行的函数
参数中有三个参数: 成员值, 索引值, 原数组
返回值就是判断的依据
every方法的返回值:
true: 全部满足条件
false: 有成员不满足条件
every对false敏感, 一旦遇到一个不满足条件的就会立即停止遍历
举例:
/**
* some方法 判断数组中是否有成员满足条件
* @arr 要判断的数组
* @fn 执行的函数
* return bool 是否有成员满足条件
**/
function some(arr, fn) {
// 遍历数组
for (var i = 0; i < arr.length; i++) {
// 执行函数并判断结果
// 传递三个参数: 成员值 arr[i], 索引值 i, 原数组 arr
if (fn(arr[i], i, arr)) {
// 如果有成员满足条件 返回true
return true;
}
}
// 遍历完成,没有成员满足 返回false
return false;
}
filter
实现对数组的过滤
使用方式和forEach方法类似
参数就是要执行的函数
函数中有三个参数: 成员值, 索引值,原数组
返回值就是过滤的条件
filter方法的返回值就是满足过滤条件的成员组成的新数组
举例:
/**
* 实现filter方法
* @arr 要过滤的数组
* @fn 执行的函数
* return [] 满足过滤条件的成员组成的新数组
**/
function filter(arr, fn) {
// 创建一个新的空数组
var result = [];
// 遍历数组
for (var i = 0; i < arr.length; i++) {
// 执行函数并传递参数
// 参数有三个: 成员值 arr[i], 索引值 i, 原数组 arr
if (fn(arr[i], i, arr)) {
result.push(arr[i]);
}
}
// 返回新数组
return result;
}
reduce、 reduceRight
这两个是累加的方法,reduce是从前向后累加, 而reduce是从后向前累加 对所有成员逐一处理,并将结果返回
参数就是要执行的函数
有四个参数: 上一次的累积结果,当前成员值, 当前索引值, 原数组
返回值就是当次累积的结果, 将会在下一次遍历的时候作为第一个参数传递
reduce是从第二个成员开始遍历, 第一个成员会在第一次遍历的时候做为第一个参数传递
reduceRight是从倒数第二个成员开始遍历,倒数第一个成员在第一次遍历的时候作为第一个参数
举例:
/**
* 实现reduceRight方法
* @arr 数组
* @fn 函数
* return 累积的结果
**/
function reduceRight(arr, fn) {
// 定义累积结果
// 由于是从倒数第二个成员开始遍历, 上次累积的结果应该是倒数第一个成员
var result = arr[arr.length - 1];
// 遍历数组 从倒数第二个成员开始遍历
for (var i = arr.length - 2; i >= 0; i--) {
// 执行函数: 上一次的累积结果, 当前成员值, 当前索引值, 原数组
result = fn(result, arr[i], i, arr);
}
// 返回结果
return result;
}
addNum
实现addNum(num1, num2)方法, 接受两个参数, 分别是两个整数,求两个整数之间的所有整数之和
addNum(1, 100)
可以包含两个参数, 可以不包含两个参数
我们统一包含两个参数
不要使用for循环
举例:
// 定义方法
function addNum(num1, num2) {
// 确定最大值与最小值
var max = Math.max(num1, num2);
var min = Math.min(num1, num2);
// console.log(max, min);
// (5, 10) 5, 6, 7, 8, 9, 10 10 - 5 + 1
// (5, 10) 6, 7, 8, 9 10 - 5 - 1
// 创建数组
return Array(max - min + 1)
// 为了遍历数组,所以要填充数组
.fill(1)
// 构建一个从小值到最大值之间的新的数组
.map(function(value, index, arr) {
// index是递加的, 用min + index 可以得到一个从最小值到最大值之间的数组
return min + index;
})
// 求累加的方法
.reduce(function(pre, value) {
return pre + value;
})
}