1、默认绑定
当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定:绑定到全局的window对象
function a () {
console.log(this)
}
a(); // 输出window
2、隐式绑定
当函数引用有上下文对象时,函数调用中的this会绑定到这个上下文对象
function foo() {
console.log(this.a)
}
let obj = {
a: 2,
foo: foo
}
obj.foo(); // 输出2
2.1、隐式丢失
直接调用引用的函数时,函数是没有上下文对象的,隐式绑定的this丢失了
function foo() {
console.log(this.a)
}
let obj = {
a: 2,
foo: foo
}
let a = 3; // a是全局对象的属性
let foo2 = obj.foo; // 这里foo2将引用foo函数本身,所以不带有函数对象的上下文
foo2(); // 输出3
3、显示绑定
采用call()和apply(),通过传入一个对象(若为基本类型,会被封装函数转为对象—装箱),将this绑定到该对象
function foo() {
console.log(this.a)
}
let obj = {
a: 2,
foo: foo
}
let a = 3; // a是全局对象的属性
let foo2 = obj.foo; // 这里foo2将引用foo函数本身,所以不带有函数对象的上下文
foo2(); // 输出3
foo2.call(obj); // 输出2
foo2.apply(obj); // 输出2
使用bind也可以将this绑定到一个对象,但是bind不执行函数,只返回一个可供执行的函数
let b = foo2.bind(obj); // 此时返回一个可供执行的函数
b(); // 输出2
4、new绑定
任何函数都可能被用作构造函数,当函数被new操作符“构造调用”时,会执行下面操作:
- 创建一个新对象(若该函数不是JS内置的,则创建一个新的Object对象);
- 将this绑定到这个对象;
- 执行构造函数中的代码(为这个新对象添加属性);
- 若函数没有返回其他对象,则自动返回这个新对象;若函数有return返回的是非对象,则还是自动返回这个新对象,即覆盖那个非对象。
function foo (a) {
this.a = a;
}
var a1 = new foo (1);
var a2 = new foo (2);
console.log(a1.a); // 输出1
console.log(a2.a); // 输出2