JavaScript中this指向

大多数的this指向我还是能辨别,但是偶尔遇到特殊的情况我还是会懵圈儿,所以整理整理。

首先,最为常见的this ,全局情况下(与严格非严格模式无关):
// 浏览器中的this
console.log(this);  // 输出window对象

// 在NodeJS中的this对象
console.log(this); // 输出一个空对象:{}
在函数中,this 的指向又有些不同:
function test() {
    console.log(this); 
}
// 在浏览器中 宽松模式下输出window对象, 严格模式下输出undefined
// 在NodeJS中 宽松模式下输出global对象,在严格('use strict')模式下输出undefined

其实无论是nodejs中还是JavaScript中,函数的this指向的都是全局对象,主要区别在于这个函数在执行作用域中是否是严格模式非严格模式,换句话说就是是谁执行了test() 函数,是严格模式要是非严格模式

在对象的方法中, this 指向:
var obj = {
    name: 'zhangsan',
    fun: function () {
        console.log(this.name);
    }
}

obj.fun(); // 输出 'zhangsan'

var test = obj.fun; // 得到fun函数
test(); // 输出window对象

上例中的第一个this 指向的是当前obj这个对象。
第二个this 指向的全局对象;通过obj.fun 获得单独的函数,而此时的函数已经独立在obj 之外了,最后调用test() 相当于就是直接调用fun()函数,所以this 的指向就变成了window 对象。

回调函数中的this

以上的这些this都是比较常见,比较容易的,但是遇到稍微复杂的回调函数,就容易掉入坑:

var obj = {
    name: 'zhangsan',
    foo: function () {
        console.log(this);
    },
    foo2: function () {
        console.log(this);
        setTimeout(this.foo, 1000);
    },
}

obj.foo2();

输出的结果为:这里写图片描述

发现输出两个不同的结果,第一次输出的是foo2中的this, 这个this 就指向的obj 这个对象,第二个this 却是指向的全局对象,这是为什么呢?
其实setTimeout 也是一个函数,我们需要给它传入参数,这里把this.foo 当做一个参数传入,实际上就做了这样的操作func = this.foo, 直接把func指向了this.foo 的引用,在执行的之后this.foo 就与obj 这个对象无关了,相当于直接调用了一个普通的函数,因此this 就指向了全局对象。

我们可以使用闭包的方式来解决这个坑:

var obj = {
    name: 'zhangsan',
    foo: function () {
        console.log(this);
    },
    foo2: function () {
        console.log(this);
        var _this = this;
        setTimeout(function () {
            console.log(this); // window对象
            console.log(_this); // obj对象
        }, 1000);
    }
}
obj.foo2(); /

输出结果:这里写图片描述

在构造函数中使用this

在JavaScript中,为了实现类,需要定义一些构造函数。

function Person(name){
    this.name = name;
    console.log(this);
}
var p = new Person('zhangsan'); // Person {name: 'zhangsan' }

调用这个构造函数时,this 指向了这个构造函数调用时候实例化出来的对象。

构造函数其实也是一个函数,如果我们把他当做一个普通函数, this 仍然指向window对象。

function Person(name) {
    this.name = name;
    console.log(this);
}
var p = Person('zhangsan'); // window

这两者区别就在于一个new

ES6规范中的箭头函数

在ES6中新增加了箭头函数,他和普通函数有点不一样,区别在于this 的指向问题。

var obj = {
    name: 'zhangsan',
    foo: function () {
        console.log(this);
    },
    foo2: function () {
        console.log(this);
        setTimeout(()=> {
            console.log(this); // 输出 obj 对象
        }, 1000);
    }
};
obj.foo2();

在前面 setTimeout() 回调函数中的this指向的是window,而在这里指的就是obj 对象,就是因为setTimeout() 函数传入的函数是一个箭头函数。

函数体内的this对象,就是定义所在的对象,而不是使用时所在的对象

简单说箭头函数中的this 纸盒定义它时候的作用域的this 有关,而与它在哪里以及符合调用它无关,同时它的this指向是不可改变的。

call, apply, bind

在JavaScript中,函数也是对象,使用callapplybind 更改this的指向

//call 

function call(thisArg[, arg1[, ...]])

第一个参数是指定执行函数this 的上下文,后面的参数是执行函数需要传入的参数。

// apply

function apply(thisArg[, arg1,arg2, arg3,...])

第一个参数是指定执行函数中this 上下文,第二个参数是一个数组,传给执行函数的参数

//bind
var foo = func.bind(thisArg[, arg1[, arg2[, ...]]])

他不会执行函数,而是返回一个新的函数,这个新的函数被指定了this 上下文,后面的参数是执行函数需要传入的参数。

例子:

var obj = {
    name: 'zhangsan'
}
function foo() {
    console.log(this);
}

foo.call(obj); // {name: 'zhangsan'}
var obj = {
    name: 'zhangsan',
    foo: function () {
        console.log(this);
    }
}
var obj2 = {
    name: '123455',
};

obj.foo.call(obj2); // {name: '123455'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值