一、默认绑定
函数独立调用,无论在哪里,都默认绑定全局window。
var obj1 = {
foo() {
console.log(this);
},
bar() {
return this.foo;
},
};
var a = obj1.foo;
obj1.bar()();//独立函数调用
a(); //独立函数调用
注意: 严格模式下,不能将全局对象用于默认绑定,this会绑定到undefined。
二、隐式绑定
当函数引用由上下文对象时,隐式绑定规则会把函数中的this绑定到这个上下文对象。对象属性引用链上只有一层或者说最后一层在调用中起作用。
var obj1 = {
foo() {
console.log(this);
},
};
var a = obj1.foo;
obj1.foo();//隐式调用
a();//独立函数调用
三、显示绑定(call/apply/bind)
先简单介绍一下call、apply、bind
call和apply的使用类似,call()
方法接受的是一个参数列表,而 apply()
方法接受的是一个包含多个参数的数组。
apply()
方法调用一个具有给定 this
值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。
function.apply(thisArg,[arg1,arg2,...]) //传入的参数以数组的形式传入
call()
方法用于调用一个函数,参数为给定 this
和若干个单独指定的参数序列。
function.call(thisArg, arg1, arg2, ...) //传入的参数直接拼接到后面
bind()
方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。(简而言之:返回一个函数)
来看下列代码,测试自己看看掌握如何
var name = "window";
var obj1 = {
name: "obj1",
foo() {
console.log(this.name);
},
};
var obj2 = {
name: "obj2",
foo() {
console.log(this.name);
},
};
function bar() {
console.log(this.name);
}
bar();
var a = obj1.foo;
a();
obj1.foo();
bar.apply(obj2);
bar.call(obj1);
var b = bar.bind(obj1);
b();
看答案,是否一样
四、new绑定
执行new操作的时候,将创建一个新的对象,并且将构造函数的this指向所创建的新对象。
new一个对象的过程:
-
创建/构造一个新对象
-
这个新对象会被执行[[Prototype]]连接
-
这个新对象会绑定到函数调用的this
-
如果函数没有返回其他对象,那么new表达式中的函数会自动返回这个新对象
function bar() {
console.log(this);
}
new bar();
bar();//独立函数调用
输出结果:
五、各绑定的优先级
- 默认绑定的优先级最低。存在其它规则就会通过其它规则来绑定this
- 显示绑定优先级高于隐式绑定
- new绑定优先级高于隐式绑定
- new绑定优先级高于bind
new绑定和call、apply是不允许同时使用的,不存在谁的优先级更高
new绑定可以和bind一起使用,new绑定的优先级更高
六、其它情况
1、箭头函数
箭头函数本身是没有this的,如果要找,则找上层作用域中的this。
var name = "window";
var obj = {
name: "obj",
foo: () => {
console.log(this.name);
},
};
function p() {
this.name = "p";
return () => {
console.log(this.name);
};
}
var p1 = new p();
p1();
obj.foo();
注意:obj中foo的上层作用域是全局
2、定时器
定时器中this指向window