这个 this 指向哪里?

clipboard.png

一个按钮组件 onClick 的时候会调用箭头所指的 onClick
但是图上定义的3个click都没被调用到,控制台也没报错,到底调用的哪里?this指向哪?

阅读 3.7k
7 个回答

说 this 指向 window 的,你们都没看到 class Profile extends Component 么?

题主你用的这个特性叫 class properties,就是让你不用在构造器里用 this.xxx 来声明 class properties。但是 babel 翻译后,本质还是把这坨代码放到 constructor 里的,所以,property 的声明和赋值的顺序对结果是有影响的。譬如你这个场景下,一个 property 中用到了另一个 property 当引用。

所以,把 click = () => {} 挪到 payResultBtn 前面去就行了。

Example:

class Whatever {
  a = 1  
  b = {
      x: this.a 
  }
}

property b 引用了 this.a, 所以 property a 的声明赋值要放在 b 前面。

Babel online try it out

这个问题应该准确的说是书写的不当,this是执行上下文的一部分,this的指向有几个很明显的判断方法,

  1. 在全局执行上下文中,this一般指向window/global,严格模式的话就是undefined
  2. 函数上下文的话场景,

    • 如果是被对象调用,如console.log(),那么在log的方法体内的this就是console;
    • 如果是直接调用,alert(),那么alert()方法内的this就是window
    • 如果是构造函数,那么就是 指向这个构造函数的new的实例
  3. 最新的class,es6的class特性,可以有方法、静态方法、静态属性和实例属性,this都会指向class实例,

其他的,看看题主的this出现在组件也就是class的实例属性中,这个属性的内部的this就是指向这个对象的实例;所以这里的this并不会指向success[0]payresaultBtns,而是指向题主写的component这个对象,由于在class内部同样会被babel转为构造函数,函数内部存在变量提升,所以在给payresaultBtns赋值时,由于click函数声明提前,但是没有赋值为function所以,this.click指向了刚声明的click,但是没有赋值,也就是undefined',所以方法是吧click`方法提前赋值即可,
看一段代码就明白了对象中的this指向,这个class不同,

var a='a in window'; //全局 a属性
var f = function(){  //全局f方法
console.log(this.a);
}
var obj = {
    a: 'a in obj', //对象a属性
    f: this.f    //对象f方法,去了全局的f方法,因为是方法属性,所以f方法内的this就是obj对象
}
console.log(obj.f())
//输出  a in obj

需要注意的时,题主的书写方式是把所有的属性都写成了实例的属性,而不是class的属性,可以考虑写成class的属性,那样就没有这个属性的书写顺序问题了,,也就是属性书写的时候不用=等号。使用构造函数constructor来初始化属性,方法的话直接写具名函数即可,不用写成实例方法+箭头函数,同样可以使用this来获取。感谢@will 的纠正。参考class实例属性链接

你箭头指的地方的this指向的是全局Window,所以this.click会调用全局函数click,但是你的全局click函数放在obj对象下面,变量提升只提升了定义,所以obj在绑定的时候,this.click是undefined。你只要把全局click函数提到obj前面就可以了。

题主的这个问题需要知道this上下文的指向细节,首先看到

click = () => {
        console.log(3);
    }

这个是函数表达式,this.click这个调用并没有执行函数,所以控制台不会有输出。因为js是顺序编译和执行的,click这个函数表达式变量放置于调用后面,会有变量提升,可以把click放到被调用的前面,同时click函数内部可以用自执行方式取到值。

你要确保代码执行到那个onClick事件处了啊,可以想办法打个断点,打印下this就知道了

不用箭头函数的方式试试

你好,看了你的问题,我到console里面去验证了一下我的想法,希望对你有用。
图片描述

代码如下:

let obj = {a:'1',b:'2',c:this};
obj
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题