什么是this
在JavaScript中,this是一个关键字,它代表函数运行时,自动生成的一个内部对象。随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是调用函数的那个对象。
this的多种绑定规则
1. 默认绑定规则
当函数被调用时,函数中this就会触发默认绑定规则。函数在哪个词法作用域里生效,this 就指向哪里,又因为函数内部没有词法作用域,所以this会一路向外寻找,最后指向全局对象,我们可以通过下列例子来解释清楚.
function Fa() {
var a = 2;
this.Fb();
}
function Fb() {
console.log(this.a);
}
Fa();
在上面代码中我们定义了一个Fa函数,一个Fb函数。Fah函数在全局中被调用,所以Fa函数中的this指向了全局对象。Fb在Fa函数中被调用,this本应指向Fa,但是函数内部没有词法作用域,所以this就往外找,指向了全局。6所以,我们称如果触发了默认绑定规则,那么this就是指向全局对象。
2. 隐式绑定规则
当函数被一个对象所拥有,再调用时,this 会指向该对象。 举个例子,在下面代码中我们定义了一个对象和一个函数。函数作为对象中key为fun键值对的value值。最后我们在第9行通过obj.fun调用这个函数。所以foo函数中的 this指向obj对象
function foo() {
console.log(this.a);
}
var obj = {
a: 'hello',
fun: foo
}
obj.fun(); // this指向obj
在函数被多个对象链式调用时,就会触发隐式丢失,此时this就会指向引用函数的对象。
function foo() {
console.log(this.a);//this指向obj
}
var obj = {
a: 'hello',
foo: foo,
};
var obj2 = {
a: 'world',
obj: obj,
};
obj2.obj.foo();//隐式丢失
3. 显示绑定规则
显式地使用 call,apply,bind 方法,this 会指向指定对象。 1.call()
function foo(n, m) {
console.log(this.a, n, m);
}
var obj = {
a:'obj' ,
};
// foo 的this显示绑定到obj上
foo.call(obj, 'hello', 'world');
2.apply()
function foo(n, m) {
console.log(this.a, n, m);
}
var obj = {
a: 'obj',
};
// foo 的this显示绑定到obj上
foo.apply(obj, ['hello', 'world']);//apply中有两个参数一个是绑定的对象,一个是数组里面装着要传入的值
3.bind()
function foo(n, m) {
console.log(this.a, n, m);
}
var obj = {
a: 'obj',
};
// foo 的this显示绑定到obj上
var bar = foo.bind(obj)();//bind的执行会返回一个函数体,必须要再次调用才能执行掉
bar('hello', 'world');
4. 箭头函数
箭头函数是 ES6 新增的一种函数表达式,它没有自己的 this,arguments,super,new.target,和原型链等属性,箭头函数的 this 是由外层作用域的 this 决定的。
var obj = {
name: "张三",
sayName: function sayName() {
var foo = () => {
console.log(this.name);//由于箭头函数没有this,它的this是外层function的this
};
foo();
},
};
obj.sayName();