javascript - 这在 JavaScript 子类中不可用

标签 javascript class inheritance events constructor

我有以下 JavaScript 类,位于 onClickLesson的方法类 lessonObj属性未定义,但 init Lesson的方法类被正确调用。我该如何更改代码才能使其正常工作?

谢谢

class Item
{
    name;

    constructor(name)
    {
        this.name = name;
    }
}

class Page
{
    pageObj;
    
    constructor()
    {
        this.init();
    }  

    init()
    {
        this.pageObj = new Item('John');
    }  
}

class Lesson extends Page
{
    lessonObj;
    
    constructor()
    {
        super();
    }  

    onClick(event)
    {
        alert(this.pageObj.name);
        alert(this.lessonObj.name);
    }

    init()
    {
        super.init();

        this.lessonObj = new Item('Mary');
        document.addEventListener('click', event => this.onClick(event));            
    }  
}

new Lesson();
Click somewhere

最佳答案

这里是这一行:

class Lesson extends Page
{
    lessonObj; // <<<<<<<<<
    
    constructor()
    {
        super();
    }  

该行基本上添加了 this.lessonObj = undefinedsuper()之后的构造函数在任何其他代码之前调用。

所以整体的执行顺序是这样的:

        class Page {
 5.         pageObj;
            
 4.         constructor() {
 5.             //this.pageObj = undefined;
 6.             this.init();
            }  

11.         init() {
12.             this.pageObj = new Item('John');
            }  
        }

        class Lesson extends Page {
13.         lessonObj;
            
 2.         constructor() {
 3.             super();
13.             //this.lessonObj = undefined;
            }  

later       onClick(event) {
                alert(this.pageObj.name);
                alert(this.lessonObj.name);
            }

 7.         init() {
 8.             this.lessonObj = new Item('Mary');
 9.             document.addEventListener('click', event => this.onClick(event));
                
10.             super.init();
            }  
        }

 1.     new Lesson();

这样this.lessonObj = new Item('Mary');来自init()随后被 this.lessonObj = undefined; 覆盖在 constructor() .

这就是为什么当您进入点击处理程序时,this.lessonObj为空。

这里是执行 const me = new Lesson(); 时执行的代码的概要(按正确的顺序) 。自从我内联了函数调用的内容以来,我已经注释掉了它们。

    const me = {};
    Object.setPrototypeOf(me, Lesson.prototype);
//  Lesson.prototype.constructor.call(me);
//    Page.prototype.constructor.call(me);
      me.pageObj = undefined;
//    Lesson.prototype.init.call(me);
        me.lessonObj = new Item('Mary');
        document.addEventListener('click', event => me.onClick(event));
//      Page.prototype.init.call(me);
          me.pageObj = new Item('John');
    me.lessonObj = undefined;

What is now the best practice to solve that?

对此没有唯一的解决方案。

class Lesson extends Page {
  lessonObj;

  constructor() {
    super();

    this.lessonObj = new Item('Mary');

    document.addEventListener('click', event => this.onClick(event));
  }

  onClick(event) {
    alert(this.pageObj.name);
    alert(this.lessonObj.name);
  }
}

甚至这个

class Page {
  pageObj = new Item('John');
}

class Lesson extends Page {
  lessonObj = new Item('Mary');

  constructor() {
    document.addEventListener('click', event => this.onClick(event));
  }

  onClick(event) {
    alert(this.pageObj.name);
    alert(this.lessonObj.name);
  }
}

new Lesson();

或者如果您想保留init()但要确保init()在所有构造函数之后调用,您可以使用工厂函数:

class Item
{
    name;

    constructor(name)
    {
        this.name = name;
    }
}

class Page {
  static create() {
    // in here, `this` points to the current constructor()
    const instance = new this();
    instance.init();
    return instance;
  }

  pageObj;

  init() {
    this.pageObj = new Item('John');
  }
}

class Lesson extends Page {
  lessonObj;

  onClick(event) {
    console.log(this.pageObj.name);
    console.log(this.lessonObj.name);
  }

  init() {
    super.init();

    this.lessonObj = new Item('Mary');
    document.addEventListener('click', event => this.onClick(event));
  }
}

const instance = Lesson.create();
console.log("instance", instance);

或者您可以选择 fluid interface方法,让init()总是return this并写一些类似的内容

class Item
{
    name;

    constructor(name)
    {
        this.name = name;
    }
}

class Page {
  pageObj;

  init() {
    this.pageObj = new Item('John');
    return this;
  }
}

class Lesson extends Page {
  lessonObj;

  onClick(event) {
    console.log(this.pageObj.name);
    console.log(this.lessonObj.name);
  }

  init() {
    super.init();

    this.lessonObj = new Item('Mary');
    document.addEventListener('click', event => this.onClick(event));
    return this;
  }
}

const instance = new Lesson().init();
console.log("instance", instance);

关于javascript - 这在 JavaScript 子类中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76199007/

相关文章:

javascript - logOnce 高阶函数

python - 如何在Python中将方法作为属性调用?

c# - 我不明白有关 .NET 继承/转换的某些内容?

objective-c - Objective-C 中的继承是什么概念?

java - 使用继承和 Java 接口(interface)使用为 Java 创建 XML 模式

javascript - 使用控件创建一个 div 幻灯片

javascript - 如何检查是否按下了一个键(在键盘上)?

javascript - d3.js 中的 Z 索引

jQuery tmpl 插件 - 动态内容的模板结果问题(错误?)

java - 如何使用 Graphics 类从一个顶点到另一个顶点绘制一条线?