请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

现在碰到一个很有意思的this指向问题,卡了我半天终于找到了源头,提给老师

问题主要来自于在子类中调用action时,出现了Cannot read properties of undefined (reading 'generateGitAPI')的问题,拷了个简易版过来,实际版本与此类似,报的是this.generateGitAPI is not a function,都是由下面的这种写法引起的

/*
 * @Description: 封装install命令注册,继承自父类command
 */

/**
 * @description: 通过Builder模式对各个command完成注册
 */
'use strict';

let cmd = {
  action(fn) {
    fn()
  }
}

class Command {
  constructor(instance) {
	// Cannot read properties of undefined (reading 'generateGitAPI') ||  ...is not a function
    cmd.action(this.action)
	
	// 正常调用子类中的generateGitAPI,及searchGitAPI
    // cmd.action(() => {
    //   this.action()
    // })
  }

  get command() {
    throw new Error('command must implements')
  }

  get description() {
    throw new Error('description must implements')
  }

  get options() {
    return []
  }

  get action() {
    throw new Error('action must implements') 
  }

  preAction() {
    console.log('pre')
  }

  postAction() {
    console.log('post')
  }
}


class InstallCommand extends Command {

  constructor() {
    super()
  }

  get command() {
    return 'install'
  }

  get description() {
    return '下载项目'
  }

  get options() {
    return []
  }

  async action() {
    await this.generateGitAPI()
    await this.searchGitAPI()
  }

  /**
   * @description: 生成GitAPI
   */  
  async generateGitAPI() {
    console.log('generateGitAPI')
  }

  /**
   * @description: 在git进行搜索
   */  
  async searchGitAPI() {
    console.log('searchGitAPI')
  }
}

const comman =  new InstallCommand()

以前老师说过,碰到this之类的问题,等它执行时才能知道this指向哪,但上面这个例子我依旧有些懵逼,请老师帮忙解答下疑问

正在回答 回答被采纳积分+3

2回答

双越 2023-08-21 12:11:38

关键问题在这里,如下图

fn 作为一个单独的函数被调用时,this 就会变化。

https://img1.sycdn.imooc.com//szimg/64e2e398097d5bc705240296.jpg

例如 

const obj = {
    fn() { console.log(this) }
}
obj.fn() // obj

const fn1 = obj.fn
fn1() // window


0 回复 有任何疑惑可以回复我~
  • 提问者 见信 #1
    想起来了! cmd.action(this.action)其实完整版本应该写成const action = this.action; cmd.action(action); 这个常量action是一个块级作用域常量,无依无靠,内部this指向它又没有window,就指向了undefined
    回复 有任何疑惑可以回复我~ 2023-08-21 19:47:14
双越 2023-08-21 07:53:47

如下图

看你描述,应该就是这里报错的,对吧?那你就在这里打印一下 this 具体是什么?

https://img1.sycdn.imooc.com//szimg/64e2a773093b9e1206180218.jpg

0 回复 有任何疑惑可以回复我~
  • 提问者 见信 #1
    老师,通过cmd.action(this.action)传递的时候这里的图中的this指向undefined;通过cmd.action(() => {this.action()})的方式传递的时候,图中的this指向了InstallCommand构造出来的对象。我没明白super去调用父类的construct的时候,为什么会产生这种现象?
    回复 有任何疑惑可以回复我~ 2023-08-21 10:15:00
  • 双越 回复 提问者 见信 #2
    看我另一个回复
    回复 有任何疑惑可以回复我~ 2023-08-21 12:11:49
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信