admin管理员组

文章数量:1279145

In TypeScript, I can't seem to declare a function in a class without the piler adding it to the prototype. For example:

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');
    //}
}

The above piles to this:

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

What I am looking for is typescript that can pile to the following 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;
    })();

Can it be done?

(As a side note, I know that foo3 would not be callable from external code. I would actually invoke foo3 from another method within the class, for example, to pass a function to a jQuery fadeOut.)

In TypeScript, I can't seem to declare a function in a class without the piler adding it to the prototype. For example:

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');
    //}
}

The above piles to this:

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

What I am looking for is typescript that can pile to the following 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;
    })();

Can it be done?

(As a side note, I know that foo3 would not be callable from external code. I would actually invoke foo3 from another method within the class, for example, to pass a function to a jQuery fadeOut.)

Share Improve this question edited Dec 6, 2012 at 9:33 Fenton 251k73 gold badges400 silver badges409 bronze badges asked Dec 5, 2012 at 19:24 danludwigdanludwig 47.4k27 gold badges163 silver badges238 bronze badges 2
  • You want a private function that is only accessible to the instances of a particular class? That sounds like a private static, which is not possible according to this answer. If you wanted foo3 to be public, would simply making it a static work for you? – apsillers Commented Dec 5, 2012 at 19:47
  • Yes, I was looking for a private function that was only accessible to instances. Thanks for the link & clarification. I was able to achieve the same goal by using a pointer function (lambda), because the issue I was trying to deal with was losing the outer this reference in an inner-scoped function. – danludwig Commented Dec 5, 2012 at 20:03
Add a ment  | 

2 Answers 2

Reset to default 7

As apsillers mentions, private static is probably what you want. While it's not supported in current builds, you will be able to have a private static member in TypeScript at some point in the future (the design team changed its mind on this one based on feedback similar to this).

I just discovered another way to have private methods in a typescript class, though the pattern may smell a little funny. As far as I can tell, you can only do this when you wrap the class in a module. For example:

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

The above piles into:

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 = {}));

With the above, external javascript could invoke foo2() on an instance of MyTypeScriptClass, but neither foo3() nor foo4() is accessible externally at runtime. The biggest caveat is that if your private method needs access to members of the instance, you have to pass this in as a function parameter. Essentially, these are private static methods.

var instance = new MyApp.MyTypeScriptClass();

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

// will not pile 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();

This approach also sort of works with scalar variables, but the variables are also essentially static -- you can't have different values for different class instances. To do that, as far as I can tell, you still need to declare them within the class. Marking them private will keep the typescript piler from allowing external calls to them, but other javascript code can still access them externally.

本文标签: javascriptWhy can39t I declare local variables and functions within a TypeScript classStack Overflow