10

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

编辑


例如,在 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;
    };

}
4

3 回答 3

18

如果你有范围问题,我为你感到难过儿子,我有 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);
    }
}
于 2013-03-11T14:19:33.140 回答
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我相信我们可以帮助您修复它。

于 2013-03-11T10:11:22.387 回答
0

看起来这是一个 TypeScript/Knockout 问题,正如@Anzeo 在他的回答和您的编辑中指出的那样。我通过将我的方法声明放在构造函数中解决了这个问题,但也使用了Knockout 的 Computed Observable 文档var self = this;的“管理'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');
        };
    }
}

无论可能发生什么范围变化,JavaScript 闭包都self让您不必担心this变化。那应该可以解决您的两个问题。

于 2013-09-06T15:08:02.487 回答