javascript中的this

在js中,this的指向在函数定义的时候是确定不了的,在函数被调用的时候,才能确定this的指向。

下面通过例子来说明:

一、全局window中(默认绑定)

var a = 10; 
function foo(){
    console.log(this);
    console.log(this.a);
}

foo(); // window  10

在这个例子里,在全局window中直接调用函数foo,this指向就是全局的window对象,所以可以获取a的值,但是如果加上严格模式,就不一样了

"use strict"
function foo(){
    console.log(this);
}

foo(); // undefined

在严格模式下,全局window中调用函数foo时,this就不再是指向window对象,而是指向undefined,这时如果想获取this.a就会报错。

二、作为对象的方法(隐式绑定)

var a = 10
var obj = {
    a: 20,
    foo() {
        console.log(this);
        console.log(this.a);
    }
}
obj.foo(); // obj  20

在这个例子中,函数foo作为对象obj的方法被调用,此时this的指向就是obj对象,thisa.a就是obj.a。这个对象的结构还比较简单,如果对象的结构更加复杂时呢?

var obj = {
    a: 20,
    c: 'ccc',
    b: {
        a: 30,
        foo() {
            console.log(this.a); // 30
            console.log(this.c); // undefined
        }
    }
}

obj.b.foo(); 

可以看出,此时this.a的值时obj.b里面a的值,而不是obj中a的值,而this.c是undefined,说明了此时foo中this的指向是obj.b这个对象。

把上面例子再稍微变一下:

var obj = {
    a: 20,
    c: 'ccc',
    b: {
        a: 30,
        foo() {
            console.log(this.a); 
        }
    }
}

var bar = obj.b.foo; 
bar(); // undefined

只是把函数赋值给另一个变量,然后再调用这个函数类型的变量,结果就与上边完全不一样了。这是因为赋值操作只是把函数的地址给了bar,bar调用的时候还是在全局window之中,全局中没有a变量,所以就是undefined。

回调函数中:
var a = 10;
var obj = {
    a: 20,
    foo() {
        setTimeout(function (){
            console.log(this.a);
        }, 1000);
    }
}

obj.foo(); // 10

这个例子里的this.a不是obj.a,而是window.a,这个是由于foo里的回调函数导致的。表面上看起来是obj调用的函数,但是实际上回调函数在执行的时候,是在全局window环境中执行的,而不是在obj对象的环境中,所以这里的this指向的是window对象。

箭头函数中:
var a = 10;
var foo = () => {
    console.log(this.a);
}

var obj = {
    a : 20,
    foo: foo
}

foo(); // 10
obj.foo(); // 10

箭头函数没有自己的this,它的this是继承而来的,它会向上层查找,把上层的this当做是自己的this。

var a = 10;
var obj = {
    a: 20,
    foo: () => {
        console.log(this.a);
    }
}

obj.foo(); // 10

普通的对象没有this,所以箭头函数作为函数的属性值时,this指向的是对象所在环境中的this,这里还是window。

三、call,apply(显示绑定)

function foo() {
    console.log(this.a);
}
var a = 10;
var obj1 = {
    a: 20,
};
var obj2 = {
    a: 30,
};

foo.call(obj1); // 20
foo.apply(obj2); // 30

call和apply会修改函数中的this指向

四、构造函数中(new绑定)

function Person(){
    this.a = 10
    console.log(this);
}
var person = new Person();

console.log(person.a); // 10

在构造函数中,this的指向就是new出来的实例对象,所以这里的person.a等于构造函数里的this.a,但是遇到有返回值时,可能就有点不一样了:

function Person(){
    this.a = 10
    return 123; 
}
var person = new Person();

console.log(person.a); // 10
function Person(){
    this.a = 10
    return {
        a: 20
    }
}
var person = new Person();

console.log(person.a); // 20

当构造函数的返回值是基本数据类型时,this还是指向实例对象,当返回值是引用数据类型时,this指向的就是返回值了。

五、this绑定的优先级

  1. new绑定
  2. 显示绑定
  3. 隐式绑定
  4. 默认绑定

回调函数和箭头函数中的this指向和隐式绑定的不一样,这个就做隐式丢失。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值