强制typescript将方法放在实例而不是原型上

强制typescript将方法放在实例而不是原型上,typescript,Typescript,是否可以强制typescript将方法放在实例而不是原型上。我这样问是因为我经常遇到“这个”范围的问题,在原型上使用方法会导致问题 编辑 例如,在ts的输出中,它似乎不一致,我将FooAlert保留在FooViewModel函数中,但将方法openFooAlertDialogueAdd保留在原型中 Js Ts 原型上的方法是每个实例上可用的方法 class Example { constructor(private someProperty: string) { }

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

编辑


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

Js

Ts


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

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
每个实例都将
someProperty
method()
复制到其原型中。您可以使用以下方法进行检查:

alert(exampleC.hasOwnProperty('someProperty') ? 'Yes' : 'No');
只有当实例没有自己的属性时,JavaScript才会遍历任何依赖链,在依赖链上更高的类上查找该属性


如果您在
这个
的范围有问题的地方提供代码,我相信我们可以帮助您解决它。

如果您有范围问题,我为您感到难过,儿子,我有99个问题,但是
这个
不是问题

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

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

有两种方法可以防止范围丢失

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

比如:

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

例如:

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

正如@Anzeo在他的回答和您的编辑中指出的,这似乎是一个打字/淘汰问题。通过将方法声明放在构造函数中,同时使用
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闭包都可以让您不必担心
这种变化。这应该可以解决您的两个问题。

我想我必须执行openFooAlertDialogueAdd=function等操作,因为这会给出正确的Js输出。暂时将输出Js放在一边—因为我认为这不重要—您能举一个范围问题的示例吗?i、 我想你想解决我的问题,使事物静止,但我认为可能有更好的方法。静态修复是在static关键字前面加上前缀:
static openfooartDialogueAdd()…
+1,以获取有关删除更改范围的注释。无法找出问题所在。难道没有办法告诉knockout不要这样做吗?我想在构造函数之外定义我的方法,因为它看起来更好:)@s093294 AFAIK还有一种方法只适用于单击处理程序。您可以使用
ko.contextFor(event.target)。$root
获取您刚才单击的项目的根范围。@感谢您让我们知道并更新答案。太棒了,这个功能终于被支持了!我在jQuery中使用callbacks()时遇到了这个问题,我需要使用
()=>
语法来确保我向该实例添加了回调,而不是一些原型引用。我最初尝试了
回调。添加($.proxy(this.methodName))
,但这很尴尬,我无法找到如何使用
=>
(箭头或lambda函数)将为您获取此范围副本,因此您不需要自己复制它。@Anzeo,它会的!谢谢你指出这一点。我想我还是喜欢带有自我约定的明确副本。但是,它确实会使构造函数变得混乱,因此我可能会更多地考虑使用lambda。
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);
    }
}
class FooViewModel{
    FooAlert: KnockoutObservableAny;
    openFooAlertDialogueAdd: () => void;

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