将Typescript转换为Javascript最佳实践

将Typescript转换为Javascript最佳实践,javascript,typescript,scope,Javascript,Typescript,Scope,您建议我如何将此JavaScript转换为TypeScript JAVASCRIPT: function MyClass() { var self = this, var1 = "abc", var2 = "xyz"; // Public self.method1 = function () { return "something " + self.var1; }; self.method2 = funct

您建议我如何将此JavaScript转换为TypeScript

JAVASCRIPT:

function MyClass() {
    var self = this,
        var1 = "abc",
        var2 = "xyz";

    // Public
    self.method1 = function () {
       return "something " + self.var1;
    };

    self.method2 = function (parm1) {
        var x = self.method1();
        return x + " something";
    };

    // Private 
    function func1(parm1, parm2) {
        return parm1 + parm2;
    }
}
这就是我希望在TypeScript中所做的,或者至少是我希望如何编写它:

module MyNamespace {
    export class MyClass {

        private var1: string = "abc";
        private var2: string = "xyz";

        constructor() {
        }

        // Public
        public method1() {
            return "something " + self.var1;
        }
        public method2(parm1) {
            var x = this.method1();
            return x + " something";
        }

        // Private 
        private func1(parm1, parm2) {
            return parm1 + parm2;
        }
    }
}
但是生成的JavaScript将所有内容都放在原型上,我会遇到一些“这个”范围问题:

var MyNamespace;
(function (MyNamespace) {
    var MyClass = (function () {
        function MyClass() {
            this.var1 = "abc";
            this.var2 = "xyz";
        }
        // Public
        MyClass.prototype.method1 = function () {
            return "something " + this.var1;
        };
        MyClass.prototype.method2 = function (parm1) {
            var x = this.method1();
            return x + " something";
        };

        // Private
        MyClass.prototype.func1 = function (parm1, parm2) {
            return parm1 + parm2;
        };
        return MyClass;
    })();
    MyNamespace.MyClass = MyClass;
})(MyNamespace || (MyNamespace = {}))

我知道我可以在构造函数中声明方法,使用lambda函数来获取“_this”而不是“this”,等等。但是“移植到TypeScript”的最佳实践是什么呢?

我认为您的移植看起来是正确的。您应该考虑让类方法留在内存、性能和可重用性的原型上。但是,如果为了保持
,您确实希望在实例上使用某些方法,则可以使用成员初始化+lambda语法:

class MyClass {
    greeting = 'hello, ';

    /** someFunc is safe to use in callback positions */
    someFunc = (msg: string) => {
        console.log(this.greeting + msg);
    }
}

我认为你的移植看起来是对的。您应该考虑让类方法留在内存、性能和可重用性的原型上。但是,如果为了保持
,您确实希望在实例上使用某些方法,则可以使用成员初始化+lambda语法:

class MyClass {
    greeting = 'hello, ';

    /** someFunc is safe to use in callback positions */
    someFunc = (msg: string) => {
        console.log(this.greeting + msg);
    }
}
但是生成的Javascript将所有内容都放在原型上

我想这就是你想要的。它创建“this”问题的唯一时间是当您希望将函数作为回调传递时。在传递回调时,这是一个众所周知的问题,而这样做是担心它的正确时机。对我来说,这感觉像是JavaScript的方式,最好是拥抱这个系统,而不是对抗它

如果每个实例都有一个唯一的函数闭包,那么您将使用更多的内存,或者至少为优化器创建更多的工作

但是生成的Javascript将所有内容都放在原型上

我想这就是你想要的。它创建“this”问题的唯一时间是当您希望将函数作为回调传递时。在传递回调时,这是一个众所周知的问题,而这样做是担心它的正确时机。对我来说,这感觉像是JavaScript的方式,最好是拥抱这个系统,而不是对抗它


如果每个实例都有一个唯一的函数闭包,那么您将使用更多的内存,或者至少为优化器创建更多的工作。

JavaScript在调用/调用该方法时决定该方法的值,而不是在声明该方法时。(在“该变量”下)

要设置正确的上下文,可以使用
=>

class MyClass {
    greeting = 'hello, ';
    someFunc(msg: string) {
        console.log(this.greeting + msg);
    }
}

var m = new MyClass();
setTimeout(() => {m.someFunc("hello")},100);
setTimeout将被传递一个在当前作用域中创建的闭包

如果要设置一个间隔或事件处理程序,并且当前范围中有一个非常大的不相关变量,那么最好声明一个函数,该函数返回当前范围之外的某个位置的闭包,并只传递与此闭包相关的变量

将为您返回闭包函数并限制范围的代码:

class MyClass {
    greeting = 'hello, ';
    someFunc(msg: string) {
        console.log(this.greeting + msg);
    }
    public static closures ={
        someFunc(me:MyClass,msg:string){
            return function(){
                me.someFunc(msg);
            };
        }
    }
}

var m = new MyClass();
setTimeout(MyClass.closures.someFunc(m,"hello"),100);

JavaScript在调用/调用方法时,而不是在声明方法时,确定
this
的值。(在“该变量”下)

要设置正确的上下文,可以使用
=>

class MyClass {
    greeting = 'hello, ';
    someFunc(msg: string) {
        console.log(this.greeting + msg);
    }
}

var m = new MyClass();
setTimeout(() => {m.someFunc("hello")},100);
setTimeout将被传递一个在当前作用域中创建的闭包

如果要设置一个间隔或事件处理程序,并且当前范围中有一个非常大的不相关变量,那么最好声明一个函数,该函数返回当前范围之外的某个位置的闭包,并只传递与此闭包相关的变量

将为您返回闭包函数并限制范围的代码:

class MyClass {
    greeting = 'hello, ';
    someFunc(msg: string) {
        console.log(this.greeting + msg);
    }
    public static closures ={
        someFunc(me:MyClass,msg:string){
            return function(){
                me.someFunc(msg);
            };
        }
    }
}

var m = new MyClass();
setTimeout(MyClass.closures.someFunc(m,"hello"),100);

如果您了解调用函数时此已解决,并且您知道可以将闭包而不是函数传递给超时或事件处理程序,则解决此应该没有问题。除非编写注册事件处理程序/设置超时的代码的人不了解JavaScript是如何工作的。通过创建另一个(不使用原型)来解决这个缺点似乎不是最好的方法。你在回答中已经提到了这一点,但我觉得有必要对未来的访客强调一点。原则上我完全同意,但是如果一个类将有许多不同的调用站点都在同一个方法上设置回调,那么让该类集中这个捕获闭包比让每个调用方为此创建一个新闭包更有效。在有效地记录和实施该行为方面,这一收益是否大于挑战可能是特定于项目的(甚至是特定于类的)。我在回答中提供了一个集中的示例,它可以更好地控制关闭范围内的内容。它应该更有效,因为另一个选项将在创建实例时创建闭包,该闭包可能会被使用,也可能不会被使用,或者在超级构造函数调用中。如果您知道调用函数时会解决此问题,并且您知道可以将闭包而不是函数传递给超时或事件处理程序,则解决此问题应该不会有问题。除非编写注册事件处理程序/设置超时的代码的人不了解JavaScript是如何工作的。通过创建另一个(不使用原型)来解决这个缺点似乎不是最好的方法。你在回答中已经提到了这一点,但我觉得有必要对未来的访客强调一点。原则上我完全同意,但是如果一个类将有许多不同的调用站点都在同一个方法上设置回调,那么让该类集中这个捕获闭包比让每个调用方为此创建一个新闭包更有效。这一收益是否超过了我所面临的挑战