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

来源:3-20 【任务】总结 vue 高级特性

见信

2023-08-21

问题主要来自于在子类中调用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指向哪,但上面这个例子我依旧有些懵逼,请老师帮忙解答下疑问

写回答

2回答

双越

2023-08-21

关键问题在这里,如下图

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

https://img.mukewang.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
共1条回复

双越

2023-08-21

如下图

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

https://img.mukewang.com/szimg/64e2a773093b9e1206180218.jpg

0
2
双越
回复
见信
看我另一个回复
2023-08-21
共2条回复

2024版 前端框架及项目面试 聚焦Vue3/React/Webpack

面向1-3年前端的框架及项目面试“刚需内容”

4663 学习 · 1644 问题

查看课程