强制打字稿将方法放在实例上而不是原型上

时间:2013-03-11 09:52:44

标签: typescript

是否可以强制使用typescript将方法放在实例上而不是原型上。我问这个是因为我经常遇到“这个”范围问题,原型上的方法会导致问题。

修改


例如在ts的输出中似乎不一致,我将FooAlert保留在FooViewModel函数中,但原型中的方法是openFooAlertDialogueAdd

的js

var FooViewModel = (function () {
    function FooViewModel (json) {
        this.Foolert = ko.observable();

    }
    FooViewModel.prototype.openFooAlertDialogueAdd = function () {
        this.FooAlert = something;
    };

TS

class FooViewModel{
     FooAlert = KnockoutObservableAny

      constructor(){
         this.FooAlert = ko.observable();
       }
     openFooAlertDialogueAdd() {
        this.FooAlert = something;
    };

}

3 个答案:

答案 0 :(得分:14)

如果你有范围问题我觉得你儿子不好,我有99个问题,但this不是一个!

史蒂夫的答案显示了定义类方法的正确方法,这些方法将在每个实例上公开。但是,如果您遇到范围问题,这可能是因为您从另一个上下文调用这些方法。

例如,如果您正在使用Knockout并将其中一个方法绑定到click绑定,则Knockout会将范围覆盖到绑定的当前范围,而不是您已定义方法的范围

有两种方法可以防止这种范围的损失。

首先,您可以在构造函数中定义方法,以在实例上而不是在原型上公开它们。

像:

class Greeter {
    greet:() => string;
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
        this.greet = () => {
            return "Hello, " + this.greeting;
        }
    }

其次,您可以使用=>语法来确定类方法的范围。

示例:

class Greeter {
    greeting: string;
    constructor() {
        this.greeting: "Blabla";
    }
    greet= () => {
        alert(this.greeting);
    }
}

答案 1 :(得分:5)

原型上的方法每个实例上可用的方法。

class Example {
    constructor(private someProperty: string) {

    }

    method() {
        return this.someProperty;
    }
}

var exampleA = new Example('A');
var exampleB = new Example('B');
var exampleC = new Example('C');

console.log(exampleA.method()); // A
console.log(exampleB.method()); // B
console.log(exampleC.method()); // C

每个实例都会将somePropertymethod()复制到其原型中。您可以使用以下方式检查:

alert(exampleC.hasOwnProperty('someProperty') ? 'Yes' : 'No');

只有当实例没有自己的属性时,JavaScript才会走向任何依赖链,以便在依赖关系链上方的类中查找属性。

如果您在this范围内遇到问题时提供代码,我们相信我们可以帮助您解决问题。

答案 2 :(得分:0)

看起来这是一个TypeScript / Knockout问题,正如@Anzeo在他的回答和编辑中指出的那样。我通过将我的方法声明放在构造函数中,但也使用Knockout's Computed Observable documentation中“管理'这个'”部分中指出的var self = this;约定来解决这个问题。您的TS代码可能如下所示:

class FooViewModel{
    FooAlert: KnockoutObservableAny;
    openFooAlertDialogueAdd: () => void;

    constructor(){
        var self = this;
        self.FooAlert = ko.observable();
        self.openFooAlertDialogueAdd = function(){
            self.FooAlert('whatever your FooAlert observable takes');
        };
    }
}

无论可能发生什么范围更改,self周围的JavaScript闭包都会让您不必担心this更改。这应该可以解决你的问题。