2012-12-05 97 views
3

在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淡出。)

+0

你想要一個只有特定類的實例才能訪問的私有函數嗎?這聽起來像一個'私人靜態',這是不可能的根據[這個答案](http://stackoverflow.com/questions/12827544/private-static-properties-in-typescript)。如果你想讓'foo3'公開,那麼簡單地將它變成一個靜態的工作? – apsillers

+0

是的,我正在尋找一個只能被實例訪問的私有函數。感謝您的鏈接和澄清。我能夠通過使用指針函數(lambda)實現相同的目標,因爲我試圖處理的問題是在內部作用域函數中失去外部'this'引用。 – danludwig

回答

6

作爲apsillers提到,private static可能是你想要的。儘管在當前版本中不支持,但您將來可以在TypeScript中使用private static成員(設計團隊根據與此類似的反饋改變了本意見)。

2

我剛剛發現了另一種在打字稿類中使用私有方法的方法,雖然這種模式可能會讓人覺得有點有趣。據我所知,你只能在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可以對MyTypeScriptClass實例調用foo2(),但既不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代碼仍然可以在外部訪問它們。

相關問題