语法糖
在JavaScript推出到es5之后,官方语法糖越来越多,官方语法糖就是用语言底层官方自己封装好的方法供开发者使用,今天我就来解析一下Array中比较常用的一些语法糖,如forEach,map等。
forEach解析
想解析其底层原理,先要明白它怎么使用:
var arr = [1, 2, 3];
// forEach可以接收两个参数一个回调函数, 一个是回调中的this
arr.forEach(function (item, index, orgin) { //后调中可以传3个参数一个是遍历出的数组中的每一项,一个是数组的下标,一个是数组本省
console.log(item); // 1 || 2 || 3
console.log(index); // 0 || 1 || 2
console.log(orgin); // Array:[1, 2, 3]
console.log(this); // Object: {name: 'forEach'}
}, {name: 'forEach'});
好明白了用法,就开始解析,重新封装:
// 首先把方法定义到Array的原型链上,使方法可以供数组实例对象调用
Array.prototype.myForEach = function (callback, myThis) { //可接收两个参数回调和回调中的this
// 如果没有传第二个参数,回调的this则为window
var _that = myThis || window;
for (var index = 0; index < this.length; index ++) { // 底层还是for循环
// 回调调用时要call一下把要设置的this传进去
callback.call(_that, this[index], index, this);
}
}
ok是不是很简单呢,我们来实验一下:
var arr = [1, 2, 3];
arr.forEach(function (item, index, orgin) {
console.log(item); // 1 || 2 || 3
console.log(index); // 0 || 1 || 2
console.log(orgin); // Array:[1, 2, 3]
console.log(this); // Object: {name: 'myForEach'}
}, {name: 'myForEach'});
这里会不会还有隐藏的bug我没有测试出来,如果哪位大神看出来请拍砖。
filter解析
有了forEach的经验就可以照葫芦画瓢,当然在那之前我们还是先看看filter的具体用法:
var arr = [1, 2, 3];
// 在参数上filter与forEach一样,只是filter可以接收一个返回值是一个新的数组,返回值是由后调的返回值决定的
var newArr = arr.filter(function (item, index, orgin) {
console.log(item); // 1 || 2 || 3
console.log(index); // 0 || 1 || 2
console.log(orgin); // Array:[1, 2, 3]
console.log(this); // Object: {name: 'filter'}
return item > 1; // 这里为true时就会把数组的该属性push到新数组中最后由filter返回出去
}, {name: 'filter'});
console.log(newArr); // [2, 3] 大于1的属性
PS(filter的返回值不是深度拷贝,所以当数组的属性有引用值时,返回数组中有变化原数组也会跟着变化,开发者们注意喽)
ok明白了用法我们来,照葫芦画瓢:
Array.prototype.myFilter = function (callback, myThis) {
// 判断是否穿了相应的回调this, 创建新的数组用于方法返回值
var _that = myThis || window, newArr = [];
for (var index = 0; index < this.length; index ++) {
// 接收回调的返回值用于判断数组该项是否添加进返回数组中
var temp = callback.call(_that, this[index], index, this);
// 如果回调返回值为true则向返回数组中push进原数组该属性
if(temp) newArr.push(this[index]);
}
// 将过滤后的新数组返回
return newArr;
}
ok那来试验一下:
var arr = [1, 2, 3];
var newArr = arr.myFilter(function (item, index, orgin) {
console.log(item); // 1 || 2 || 3
console.log(index); // 0 || 1 || 2
console.log(orgin); // Array:[1, 2, 3]
console.log(this); // Object: {name: 'myFilter'}
return item > 1;
}, {name: 'myFilter'});
console.log(newArr); // [2, 3] 大于1的属性
还是那句话我没有测出bug不代表没有bug,欢迎大神拍砖,那有了上面的两个例子下面我就附上map等方法的封装不做详细的解析了:
map:
Array.prototype.myMap = function (callback, myThis) {
var _that = myThis || window, newArr = [];
for (var index = 0; index < this.length; index ++) {
var temp = callback.call(_that, this[index], index, this)
newArr.push(temp)
}
return newArr
}
some & every:
// mySome
Array.prototype.mySome = function (callback, myThis) {
var _that = myThis || window, verdict = false;
for (var index = 0; index < this.length; index++) {
var temp = callback.call(_that, this[index], index, this)
if (temp) {
verdict = true
break;
}
}
return verdict
}
// myEvery
Array.prototype.myEvery = function (callback, myThis) {
var _that = myThis || window, verdict = true;
for (var index = 0; index < this.length; index++) {
var temp = callback.call(_that, this[index], index, this)
if (!temp) {
verdict = false
break;
}
}
return verdict
}
欢迎大神拍砖!
ok今天就写到这里,闪人!!!