为什么我不能在TypeScript类中声明局部变量和函数?

时间:2012-12-05 19:24:16

标签: javascript typescript

在TypeScript中,如果没有编译器将其添加到原型中,我似乎无法在类中声明函数。例如:

class MyTypeScriptClass {
    // method, is added to prototype
    foo1(): void {
        alert('invoked foo1');
    }

    // private method also added to prototype
    private foo2(): void {
        alert('invoked foo2');
    }

    //// can I have a local function, without making it a private method?
    //function foo3() {
    //    alert('invoked foo3');
    //}
}

以上编译如下:

var MyTypeScriptClass = (function () {
    function MyTypeScriptClass() { }
    MyTypeScriptClass.prototype.foo1 = function () {
        alert('invoked foo1');
    };
    MyTypeScriptClass.prototype.foo2 = function () {
        alert('invoked foo2');
    };
    return MyTypeScriptClass;
})();

我正在寻找的是可以编译为以下JavaScript的打字稿:

var fvm = new FlasherViewModel2();
    var MyTypeScriptClass = (function () {
        function MyTypeScriptClass() { }
        MyTypeScriptClass.prototype.foo1 = function () {
            alert('invoked foo1');
        };
        MyTypeScriptClass.prototype.foo2 = function () {
            alert('invoked foo2');
        };
        function foo3() {
            alert('invoked foo3');
        }
        return MyTypeScriptClass;
    })();

可以吗?

(作为旁注,我知道foo3不能从外部代码调用。我实际上会从类中的另一个方法调用foo3,例如,将函数传递给jQuery fadeOut。)

2 个答案:

答案 0 :(得分:7)

正如apsillers所提到的,private static可能就是你想要的。虽然在当前版本中不支持它,但未来某个时候你可以在TypeScript中拥有一个private static成员(设计团队根据与此类似的反馈改变了对它的想法)。

答案 1 :(得分:2)

我刚刚发现了另一种在typescript类中使用私有方法的方法,尽管这种模式可能闻起来有点滑稽。据我所知,只有在module中包装课程时才能这样做。例如:

module MyApp {
    // not accessible externally, `this` must be passed in if needed
    function foo3(that: MyTypeScriptClass): void {
        that.foo1();
        alert('invoked foo3');
    }

    // not accessible externally
    function foo4(): void {
        alert('invoked foo4');
    }

    export class MyTypeScriptClass {
        // normal method, is added to prototype
        foo1(): void {
            alert('invoked foo1');
        }

        // private method also added to prototype, is accessible externally
        private foo2(): void {
            alert('invoked foo2');
            foo3(this);
            foo4();
        }
    }
}

以上编译成:

var MyApp;
(function (MyApp) {
    function foo3(that) {
        that.foo1();
        alert('invoked foo3');
    }
    function foo4() {
        alert('invoked foo4');
    }
    var MyTypeScriptClass = (function () {
        function MyTypeScriptClass() { }
        MyTypeScriptClass.prototype.foo1 = function () {
            alert('invoked foo1');
        };
        MyTypeScriptClass.prototype.foo2 = function () {
            alert('invoked foo2');
            foo3(this);
            foo4();
        };
        return MyTypeScriptClass;
    })();
    MyApp.MyTypeScriptClass = MyTypeScriptClass;    
})(MyApp || (MyApp = {}));

通过上述内容,外部javascript可以在foo2()的实例上调用MyTypeScriptClass,但foo3()foo4()都不能在运行时从外部访问。最大的警告是,如果您的私有方法需要访问实例的成员,则必须将this作为函数参数传递。基本上,这些是私有静态方法。

var instance = new MyApp.MyTypeScriptClass();

// public, accessible externally
instance.foo1();

// will not compile in a .ts file, but works at runtime from manual js file
instance.foo2();

// runtime exception, foo3 is not defined
foo3(instance);
MyApp.foo3(instance);

// runtime exception, foo4 is not defined
foo4();
MyApp.foo4();

这种方法也适用于标量变量,但变量本质上也是静态的 - 不同的类实例不能有不同的值。要做到这一点,据我所知,你仍然需要在类中声明它们。标记它们private将使打字稿编译器不允许外部调用它们,但其他javascript代码仍然可以从外部访问它们。