【问题标题】:Call Method from Constructor: Error: Uncaught TypeError: undefined is not a function从构造函数调用方法:错误:未捕获类型错误:未定义不是函数
【发布时间】:2014-05-21 18:52:06
【问题描述】:

任务:我需要在 Typescript 中构建一个类,在它自己的构造函数中调用它自己的一些方法。

问题:以下示例代码所代表的实际代码将编译成功,但在 Javascript 控制台中测试时,它没有。

示例:

export class volumeEQ
{
    constructor(ctx:any) 
    {
        this.ctx = ctx;         // Audio context saved into member variable of class
        this.setupAudioNodes(); // Sets up nodes made out of audio
    }

    setupAudioNodes()
    {
        this.sourceNode.connect(this.ctx.destination); // Connect to destination
    }
}

技术:Typescript 编译器没有this.setupAudioNodes() 的问题,但是一旦在浏览器的 Javascript 控制台中调用为 Javascript,我就会收到错误 Uncaught TypeError: undefined is not a function。实际上,这是 Javascript 的 this. 语法的问题,并且很容易与它混淆。但是因为我是用 Typescript 开发的,所以我想要一个更加 Typescript 风格的解决方案。

问题:如何在 Typescript 的构造函数中调用类的方法?

【问题讨论】:

  • 在正常情况下从构造函数调用方法是微不足道的,但是代码示例中没有足够的信息来重现您遇到的问题。
  • 在正常情况下从构造函数调用方法应该是微不足道的。能够从同一个类的构造函数中调用公共方法是有意义的。 Typescript Compiler 认为这是可能的,并且成功编译它是有道理的。 Javascript 的 this. 使用起来非常混乱,这太糟糕了。
  • @basarat 很棒的视频,这有助于我了解我是如何对this.感到困惑的
  • 投票结束,因为该问题实际上并不包含重现所声称的问题所需的信息(请参阅答案和 OP 的 cmets)。

标签: javascript html syntax typescript grammar


【解决方案1】:

下面是如何从构造函数调用方法:

class Thing {
    constructor(name: string) {
        this.greet(name);
    }

    greet(whatToGreet: string) {
        console.log('Hello, ' + whatToGreet + '!')
    }
}

var x = new Thing('world'); // Prints "Hello, world!"

【讨论】:

  • 这个答案很有道理。
  • 这应该被标记为答案。没有双关语。
【解决方案2】:

以下是我正在寻找的内容。

解决方案来源:
How can I preserve lexical scope in TypeScript with a callback function

如何在 Typescript 中保留 this. 的词法范围:

如果以下方法声明不起作用:

export class myClass
{
    constructor()
    {
        var myString:string = this.myMethod(true);
    }
    
    public myMethod(useBigString:boolean) : string
    {
        if(useBigString)
        {
            return "bigString";
        }
        return "smlStr";
    }
}

在 javascript 中生成一个方法,如下所示:

myClass.prototype.myMethod = function (useBigString) {



相反,请尝试以这种方式声明您的方法:

export class myClass
{
    constructor()
    {
        var initString:string = this.myMethod(true);
    }
    
    public myMethod = (useBigString:boolean) : string => {
        if(useBigString)
        {
            return "bigString";
        }
        return "smlStr";
    }
}

在构造函数中用javascript声明方法:

this.myMethod = function(useBigString) {



一个缺点是方法语法突出显示不会识别这种定义,但它绝对可以编译和工作!这种情况不适用于类变量,就像类方法一样。

【讨论】:

  • 为什么不包含一个实际重现问题的示例?
  • 不确定如何...我在练习 Typescript 之前还没有做到这一点。对于上下文:我正在使用 cocos2d-JS 制作工具和 UI 系统。我正在使用 Sublime Text 3 进行编程,并安装了 Better Typescript 包,也让 tsc 构建命令也能正常工作。我最初使用 node.js 安装了tsc。我的类是从 cocos2d 引擎调用的入口点构造函数调用的。我在 Chrome Canary 中运行它,因为我正在练习使用新的 webkitAudioContext()。该问题在常规 Chrome 中也仍然存在。
  • 您现在可能知道这一点,但您将无法覆盖/重载您的“myMethod”。
  • 你所做的就像创建一个静态方法
【解决方案3】:

研究:

临时破解:

  • 创建一个具有您希望调用的方法的类,但尽可能使构造函数保持基本。
  • 下一步创建第二个类,扩展第一个类。
  • 从超类中调用方法。 示例: super.myFunction();


示例:

export class basicEQ
{
    constructor(ctx:any)
    {
        this.ctx = ctx;         // Audio context saved into member variable of class
    }
    setupAudioNodes()
    {
        this.sourceNode = this.context.createBufferSource(); // Create Buffer Source Node
        this.sourceNode.connect(this.ctx.destination); // Connect to destination
    }
}

export class volumeEQ extends basicEQ
{
    constructor(ctx:any)
    {
        super(ctx);
        super.setupAudioNodes(); // Use super, Not this
    }

}


破解说明:
使用super. 而不是this. 用于构造函数内的方法调用。通过扩展你的类来做到这一点,这样你就可以首先调用 super 。 示例: export class myUsableClass extends myBaseClass。现在,myBaseClass 拥有所有方法,myUsableClass 可以从构造函数中调用它们。

我的解决方案是解决实际问题的方法,但很高兴知道有办法解决这个问题。如果其他人有其他方法可以解决问题,请发帖! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 2015-03-14
    • 2014-08-11
    • 2015-04-14
    • 2014-12-13
    相关资源
    最近更新 更多