this绑定的规则
1.默认绑定
独立函数调用
foo(){
console.log(this)
}
foo() //window
在浏览器中foo()函数时保存在window对象中,所以指向的是window
function test() {
console.log(this);//window
}
function test1() {
console.log(this);//window
test();
}
function test2() {
console.log(this); //window
test1();
}
test2();
同理test2也是保存在window对象中,是window对象调用了test2函数,所以当前的this指向的是window,但是test1函数的执行还是window调用的,当前的this还是指向window
2.隐式绑定
通过某个对象发起的函数调用
function foo() {
console.log(this); //obj
}
var obj = {
foo: foo,
};
obj.foo();
这里的函数调用是obj调用的,所以指向的是obj
function foo() {
console.log(this);//obj
}
var obj = {
foo: foo,
};
var obj1 = {
obj: obj,
};
obj1.obj.foo();
这里的foo的调用还是指向的是obj,因为foo函数是obj调用的,obj1调用obj,obj又调用了foo,所以当前的this指向还是obj
3.显示绑定
- 必须在调用的对象内部有一个对函数的引用(比如一个属性)
- 如果没有这样的引用,在进行调用时,会报找不到该函数的错误
- 正是通过这个引用,间接的将this绑定到了这个对象上
//通过apply绑定
function foo(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
//第一个参数表示的是需要绑定的this,可以是任意的数据类型
//apply调用函数的参数是放在数组中
foo.apply("bbbb", [20, 30]);//“bbbb”
//通过call调用
function foo(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
//第一个参数表示的是需要绑定的this,可以是任意的数据类型
//call调用函数的参数直接写
foo.call("aaa", 20, 30); //“aaa”
//通过bind调用
function foo(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
var bar = foo.bind("adc", 30, 20); //bind绑定this之后返回一个函数
bar();
4.new绑定
//new绑定
function Person(name, age) {
console.log(this); //person{}
this.name = name;
this.age = age;
}
var p1 = new Person("jack", 18);
console.log(p1);//person{name:"jack",age:18}
console.log(p1.name, p1.age);
通过new关键字来创建一个新的类,创建出来的类的this会绑定返回时的对象
一些其他的函数this指向
定时器
setTimeout(function () {
console.log(this); //window
});
可以理解为独立函数的调用
DOM事件监听
const boxdiv = document.querySelector('.box');
boxdiv.addEventListener('click', function () {
console.log(this);//boxdiv元素
});
boxdiv.onclick = function () {
console.log(this);//boxdiv元素
};
数组foreach,map
var names = ['jack', 'mask', 'kobe'];
names.forEach(function (item) {
console.log(item, this); //item+window
});//这里添加第二个参数可以指定this的指向
names.map(function (item) {
console.log(item, this); //item+window
});//这里添加第二个参数可以指定this的指向
规则的优先级
1.默认绑定的优先级最低
2.显示高于隐式绑定
- call和apply
var obj = {
foo: function () {
console.log(this);
},
};
obj.foo.call('adc'); //string{"adc"} ,apply也是一样的
- bind
function foo() {
console.log(this);
}
var obj = {
foo: foo.bind('adc'),
};
obj.foo();//string{"adc"}
- new高于隐式绑定
var obj = {
foo: function () {
console.log(this);
},
};
var bar = new obj.foo();//foo函数
- new高于显示绑定
new和call/apply都是主动调用改变的this的指向,所以一般不会同时使用,这里用new和bind进行实验
function foo() {
console.log(this);
}
var bar = foo.bind('adc');
var ad = new bar();//foo函数
new > 显示绑定>隐式绑定>默认绑定(独立函数调用)
5.其他的一些绑定
call/apply/bind绑定null/undefined
var obj = {
foo: function () {
console.log(this);
},
};
obj.foo.call(null);//window
obj.foo.apply(undefined);//window
var bar = obj.foo.bind(null);//window
bar();
间接函数的引用
var obj = {
foo: function () {
console.log(this);
},
};
var obj1 = {
name: 'jack',
};
(obj.bar = obj.foo)();//window,可以理解为独立函数的调用
网友评论