一. 重写forEach方法及this指向问题
1. 重写forEach方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script type="text/javascript">
// console.log(Array);
//查看对象的
// console.dir(Array);
// console.dir(this.Array.prototype);
// this.Array.prototype.forEach=function(){
// }
var arr = [
{
id: 1,
age: 18,
},
{
id: 2,
age: 19,
},
{
id: 3,
age: 20,
},
];
var obj = [
{
id: 4,
age: 100,
},
{
id: 5,
age: 200,
},
{
id: 6,
age: 300,
},
];
function callback(item, index, array) {
console.log(this); //this指向问题,修改后,指向改变,打印出来的是obj对象
console.log(item);//某数组中某一个值
console.log(index);//下标
console.log(array);//对象,某个数组
}
// 源码如下:
this.Array.prototype.forEach1 = function (callback) {
var arg2 = arguments[1] || window; //获取第二个参数对象
var dataArr = this;
var length = dataArr.length;
for (let i = 0; i < length; i++) {
// callback(dataArr[i],i,dataArr)
//this指向 call apply bind
//call方法,第一个参数:指向对象,后面陆续传参
// callback.call(arg2, dataArr[i], i, dataArr);
//apply方法,第一个参数:指向对象,后面陆续传参,后面的整体用中括号括起来
// callback.apply(arg2,[dataArr[i],i,dataArr])
//bind方法一,第一个参数:指向对象,后面陆续传参,最后单独写一个括号
// callback.bind(arg2,dataArr[i],i,dataArr)()
//bind方法二,第一个参数:指向对象,将它单独括起来,后面陆续传参
// callback.bind(arg2)(dataArr[i],i,dataArr)
}
};
// 第二个参数,改变了this指向,由window改变成obj对象
arr.forEach1(callback,obj);//this指向obj
arr.forEach1(callback);//this指向window
</script>
</body>
</html>
2. 关于回调函数中this指向的问题
改变this指向的三个方法:
1. call方法
callback.call(arg2, dataArr[i], i, dataArr);
//call(指向的对象,item,index,array)
2. apply方法
callback.apply(arg2,[dataArr[i],i,dataArr])
//第一个参数:指向的对象,后面陆续传参,后面的整体用中括号括起来
3. bind方法
callback.bind(arg2,dataArr[i],i,dataArr)()
或
callback.bind(arg2)(dataArr[i],i,dataArr)