还在猜this指向谁吗?快来看看this的指向规则~
前言
为什么要有this?
为了让对象中的函数有能力访问对象自己的属性。
this的好处?
this可以显著的提升代码质量,减少上下文参数的传递。
正文
this的绑定规则
默认绑定
定义
当一个函数独立调用,不带任何修饰符的时候为默认绑定。
代码分析(该代码拿到页面的控制台运行,因为node没有window)
代码一
function foo() {
console.log(this); // window
}
foo();
代码二
function foo() {
console.log(this);
}
function bar() {
foo();
}
function baz() {
bar();
}
baz();
分析
该函数为独立调用,因此为默认绑定,这个时候就要看这个函数在哪个词法作用域下生效,foo在全局作用域下生效,因此this指向的window。
this指向分析
函数在哪个词法作用域下生效,函数中的this就指向哪(简述就是只要是默认绑定,this一定指向window)。
隐式绑定
定义
当函数的引用有上下文对象的时(当函数被某个对象所拥有时)为隐式绑定。
代码一
var obj = {
a: 1,
b: this,
foo: function() {
console.log(this); // obj
}
}
obj.foo();
分析
该函数的引用有上下文对象,因此为隐式绑定,隐式绑定的规则是this指向引用它的对象。
代码二
var obj = {
a: 1,
b: function() {
foo();
}
}
function foo() {
console.log(this.a);
console.log(this);
}
var a = 2;
obj.b();
分析
obj.b()相当于调用函数foo(),所以此时为默认绑定,this指向全局,那么这个时候就会去全局查找属性a,所以输出的为2。
this指向
函数的this指向引用它的对象。
隐式丢失
定义
当一个函数被多个对象链式调用时,函数的this指向就近的那个对象。
代码一
var obj = {
a: 1,
foo: foo
}
var obj2 = {
a:2,
obj: obj
}
function foo() {
console.log(this.a)
}
obj2.obj.foo();
分析
函数被多个对象链式调用时,函数的this指向就近的那个对象,此时this指向obj,所以输出的为1.
代码二
var obj = {
a: 1,
foo: foo()
}
function foo() {
console.log(this.a)
}
obj.foo;
分析
obj.foo就相当于foo(),所以此时为默认绑定,this指向全局,所以输出undefined。
显式绑定
call
代码
var obj = {
a: 1
}
function foo(x, y) {
console.log(this.a, x + y);
}
foo.call(obj, 2, 3);
分析
call可以让foo里的this绑定到obj,并且call还可以传递其他的参数给foo。
apply
代码
var obj = {
a: 1
}
function foo(x, y) {
console.log(this.a, x + y);
}
foo.apply(obj, [2, 3]);
分析
apply和call差不多,但是有一个区别就是,apply传递其他的参数给foo时是使用数组的形式进行传递的。
bind
代码
var obj = {
a: 1
}
function foo(x, y) {
console.log(this.a, x + y);
}
bind会返回一个函数,定义一个bar接收该函数,然后调用
方法一(通过bind传参,和call一样的形式)
var bar = foo.bind(obj, 2, 3);
bar();
方法二(bind和bar结合传参)
var bar = foo.bind(obj);
bar(2, 3);
方法三(bind和bar结合传参)
var bar = foo.bind(obj, 2);
bar(3);
方法四(bind和bar结合传参,多出的参数,根据就近原则,优先bind)
var bar = foo.bind(obj, 2, 3);
bar(4);
new 绑定
function Person() {
this.name= '李总'
}
let p = new Person(); //this指向实例对象
let p2 = new Person();
this指向
this指向创建的实例对象
箭头函数
箭头函数没有this这个机制,写在箭头函数中的this也是它外层非箭头函数的this。
代码一
function foo() {
var bar = () => {
console.log(this);
}
//箭头函数没有this,即bar没有this,不能说bar的this,只能说bar里的this
bar();
}
foo();
分析
箭头函数没有this这个机制,所以看他的外层非箭头函数bar,bar为默认绑定,所以this指向window。
代码二
var obj = {
a: 1,
b: function () {
const fn = () => {
console.log(this.a);
console.log(this);
}
fn();
}
}
obj.b();
分析
箭头函数没有this这个机制,看外层函数fn,绑定为隐式绑定,this指向obj,所以输出1。
结语
看完有没有对this指向清晰点呢?记得和我分享分享哦~
转载自:https://juejin.cn/post/7366426339278798884