简体   繁体   English

将Typescript转换为Javascript最佳做法

[英]Converting Typescript to Javascript Best Practices

How would you recommend I convert this JavaScript to TypeScript? 您如何建议我将此JavaScript转换为TypeScript?

JAVASCRIPT: 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;
    }
}

This is what I would like to do in TypeScript, or at least how I would expect to write it: 这是我想在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;
        }
    }
}

But the generated JavaScript puts everything on the prototype and I will have some "this" scoping issues: 但是生成的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 = {}))

I know I can declare the methods within the constructor, use lambda functions to get "_this" instead of "this", etc. but what are the best practices of "porting to TypeScript"? 我知道我可以在构造函数中声明方法,使用lambda函数获取“ _this”而不是“ this”,等等。但是“移植到TypeScript”的最佳实践是什么?

But the generated Javascript puts everything on the prototype 但是生成的Javascript将所有内容都放在了原型上

I think that's what you want to happen. 我认为这就是您想要发生的事情。 The only time it creates a "this" issue is when you want to pass the function as a callback. 它唯一创建“ this”问题的时间是当您要将函数作为回调传递时。 That's a known concern when passing callbacks and when doing so is the right time to worry about it. 在传递回调时,这是一个已知的问题,而这样做正是为此而担心的时候。 To me it feels like the JavaScript way and it's better to embrace the system rather than fight it. 在我看来,这就像JavaScript的方式,最好是拥抱系统而不是与之抗争。

If every instance has a unique function closure you're using a lot more memory or at a minimum creating way more work for the optimizer. 如果每个实例都有一个独特的函数闭包,则您将使用更多的内存,或者至少需要为优化器创建更多的工作。

I think the porting you have there looks right. 我认为您在那里的移植看起来不错。 You should consider letting class methods stay on the prototype for memory, performance, and reusability reasons. 由于内存,性能和可重用性的原因,您应该考虑让类方法保留在原型上。 But if you have some methods you really want to be on the instance for the purposes of keeping this , you can use the member initialization + lambda syntax: 但如果你有你真的想成为实例保持的目的,一些方法this ,你可以使用成员初始化+ lambda语法:

class MyClass {
    greeting = 'hello, ';

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

JavaScript determines the value of this when calling/invoking the method, not when you declare it. JavaScript的决定价值this打电话时/调用方法,而不是当你声明它。 https://stackoverflow.com/a/16063711/1641941 (under "The this variable") https://stackoverflow.com/a/16063711/1641941 (在“此变量”下)

To set the right context you can use => 要设置正确的上下文,您可以使用=>

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

var m = new MyClass();
setTimeout(() => {m.someFunc("hello")},100);

setTimeout will be passed a closure that is created in the current scope. setTimeout将传递在当前范围内创建的闭包。

If you were to set an interval or event handler and the current scope has a very large irrelevant variable(s) in it then it's better to declare a function that returns the closure somewhere outside of the current scope and pass it the only the variables that are relevant for this closure. 如果要设置时间间隔或事件处理程序,并且当前作用域中有一个非常大的不相关变量,那么最好声明一个函数,该函数将闭包返回到当前作用域之外的某个地方,并仅将其传递给与该关闭有关。

Code that will return a closure function for you and limit scope: 将为您返回关闭函数并限制范围的代码:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM