关于js中的this指向问题

每个函数的this是在函数执行时绑定的,完全取决于函数的调用位置(函数执行时地方)。
我把js中的this指向分为以下5大类

默认绑定

默认绑定时是把this绑定在window上;
如果使用严格模式,则会绑定到undefined上

function foo(){
	console.log(this.a)
}
var a = 2
foo() // 2

这里的this就绑定在window上,如果使用严格模式,则this指向的是undefined

function foo(){
	'use strict'
	console.log(this.a)  // typeError:this is undefined
}
var a = 2
foo() // 2

隐式绑定

隐式绑定指的是在调用的位置是否有上下文关系(是否被某个对象所包含),这种情况下谁调用指向谁

function foo(){
    console.log(this.a)
}

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

obj.foo()  // 2 
// 由于调用者是obj这个对象,所以foo中的this.a指向obj.a

一个多级对象在调用方法时,this绑定在离他最近的那个对象上

function foo(){
    console.log(this.a)
}

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

var obj1 = {
    a:3,
    obj:obj
}

obj1.obj.foo() // 2

此外,隐式绑定有一种特殊情况,就是隐式丢失
当并不是直接调用某个函数或方法时,这时候会出现this绑定丢失的情况。
以下是几种绑定丢失的情况

  1. 给函数起别名
function foo(){
    console.log(this.a)
}

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

var baz = obj.foo

var a = 'baz'
baz() // baz

// baz函数实际上引用的是foo函数本身,因此这时候使用了默认绑定
  1. 函数作为另一个函数的回调
function foo(){
    console.log(this.a)
}

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

function doFoo(fn){
    fn()
}
var a = 'baz'
doFoo(obj.foo)  // baz
显式绑定

显示绑定是指通过call/apply/bind绑定的this。

他们的区别主要如下:

  • call: 第一个参数是被绑定的this对象,之后依次写要传的函数参数
  • apply: 第一个参数是被绑定的this对象,之后是一个数组,需要的参数传入这个数组
  • bind:bind返回的是一个函数,需要加()再次执行
new绑定(构造函数绑定)

通过 new 构造的函数实例,this绑定在当前实例上

function Foo(a){
    this.a = a
}

var foo = new Foo(2)
console.log(foo.a) // 2

关于构造函数new的过程,主要分为以下四步:
1.创建一个对象
2.构造这个对象的prototype等属性
3.将这个对象绑定到this
4.返回这个对象

箭头函数中的this

箭头函数没有自己的 this,当在内部使用了 this时,它会指向最近一层作用域内的 this,箭头函数的this在定义时就确定了。

var name = 'xiaohong';
var obj = {
    name: 'xm',
    sayName: () => {
        console.log(this.name) 
    }
}
obj.sayName() // xiaohong

此时的箭头函数和sayName是同级的,它属于obj,由于箭头函数没有this,所以它的this指向离它最近的作用域的this,即指向window。

var obj = {
    name: 'xm',
    sayName: function(){
        return () => {
            console.log(this.name);
        }
    }
}
obj.sayName()()          //xm

由于箭头函数没有自己的 this,当在内部使用了 this时,它会指向最近一层作用域内的 this,箭头函数的最近一层的作用域为obj内,所以它的this指向obj

var obj = {
    name: 'xm',
    sayName: function(){
        return () => {
          return () => {
            return () => {
              console.log(this.name);
            };
          };
       };
    }
}
obj.sayName()()()() // xm

以上函数定义了三个箭头函数,由于三个箭头函数都不存在this,所以它的this指向了离箭头函数最近的obj.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值