this的四个绑定规则分为:
- 默认绑定
- 隐式绑定
- 显式绑定
- new绑定
默认绑定
function foo() {
console.log(this);
}
foo()//this指向window
当一个函数独立调用,他的this就指向window。
而当一个函数内部返回一个函数再调用时,他的this指向又是什么呢?
function foo(){
function bar(){
console.log(this)
}
return bar
}
var fn = foo()
fn()//this指向window
此时this依然指向window。因为执行foo函数后将返回的bar函数赋值给fn变量,执行fn(),此时函数依然是独立调用。this自然还是指向window。
隐式绑定
var obj = {
name: "lt",
foo: function() {
console.log(this.name);
},
};
obj.foo()//结果为lt
var fn = obj.foo
fn()//结果为undefind
此时执行obj.foo(),为隐式绑定,this绑定为调用这个函数的对象,在这个对象中找到name属性,然后打印。而将obj.foo赋值给fn变量,再调用,就是默认绑定,this默认绑定到window中找到name属性,而name属性的值默认为undefind。
显式绑定
function foo(name, age) {
console.log(this);
}
const obj = {
name: "foo",
age: 18,
};
//三种显式绑定的方式
foo.apply(obj);
foo.call(obj);
var fn = foo.bind(obj);
fn();
此时被apply,call,bind函数绑定的foo函数的this都指向obj对象,这就是显式绑定。
new 绑定
function Person(name, age) {
(this.name = name), (this.age = age);
}
var f = new Person("发发发", 178);
console.log(f); //Person {name: '发发发', age: 178}
当将一个函数用new关键字时,这个函数将会默认生成一个对象然后赋值给this,然后返回出去
四种绑定优先级比较
显式绑定和隐式绑定
const obj = {
name: "hhh",
foo: function() {
console.log(this);
},
};
obj.foo.apply("aaa");//"aaa"
obj.foo.call("bbb");//"bbb"
var f = obj.foo.bind("jhjh");
f();//"jhjh"
由此例子可知显式绑定是高于隐式绑定的。
而下面这个例子
function bar() {
console.log(this);
}
const obj = {
name: "hhh",
foo: bar.bind("qqq"),
};
obj.foo();//"qqq"
同样这种情况打印的依然是qqq,所以显式绑定高于隐式绑定。
new绑定和显式绑定的优先级比较
由于new关键字不能和call和apply同时使用,所以只能和bind比较
function bar() {
console.log(this);
}
const obj = {
name: "hhh",
foo: bar.bind("qqq"),
};
var c = new obj.foo();//this指向bar函数
所以new绑定高于显式绑定