どうしてこんなに長い間見逃してきたのかわかりません。私はプライベートインスタンス変数がこのように機能すると想定してきましたが、そうではありません。確かに、それらは(非グローバルのように)プライベートですが、変数はインスタンス間で共有されます。これは、いくつかの非常に紛らわしいバグにつながりました。
そこにあるいくつかの最高のライブラリによって実装されたベストプラクティスに従っていると思いましたが、何かを逃したようです。
var Printer = (function(){
var _Word;
Printer = function(Word){
_Word = Word;
}
_print = function(){
console.log(_Word);
}
Printer.prototype = {
print: _print
}
return Printer;
})();
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Bob (!)
b.print(); //Prints Bob
この投稿を見てきましたが、プライベートインスタンス変数を実装するためのベストプラクティスについては説明していません。 (これは私が欲しいものの名前でもありますか?) JavaScriptのプライベート変数とインスタンス変数のメソッドと変数のスコープ
私もこの投稿を見ましたが、「this」キーワードの使用は私が以前行っていたものです。難読化されていないので、避けようとしていました。これは本当に唯一の方法ですか? プロトタイプ継承でのインスタンスメソッド/変数の実装
あなたはその閉鎖でいくつかの奇妙なことをしています。 _Word
はPrinter
関数で宣言する必要があり、匿名閉鎖の土地では失われません。
function Printer(Word) {
var _Word = Word;
this.print = function () {
console.log(_Word);
}
}
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Alex
b.print(); //Prints Bob
これにより、すべてのprint
インスタンスで新しいPrinter
関数が作成される代わりに、_Word
がプライベートに保たれます。このコストを削減するには、_Word
を公開し、プロトタイプで単一のprint
関数を使用します。
function Printer(Word) {
this._Word = Word;
}
Printer.prototype.print = function () {
console.log(this._Word);
}
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Alex
b.print(); //Prints Bob
本当に_Word
が公開されているかどうかは問題ですか?個人的には、特に_
プレフィックスがあると、そうは思いません。
プライベートは存在しません。これをエミュレートするには、2つの方法のいずれかを実行できます。
function makePrinter(Word) {
return {
print: function () {
console.log(Word)
}
}
}
weakmaps のブラウザサポートはひどいです。おそらくエミュレーションが必要になるでしょう、私はお勧めします pd.Name
var Printer = (function () {
var privates = function (obj) {
var v = map.get(obj)
if (v === undefined) {
v = {}
map.set(obj, v)
}
return v
}, map = new WeakMap()
return {
constructor: function (Word) {
privates(this).Word = Word
},
print: function () {
console.log(privates(this).Word)
}
}
}());
var Printer = {
constructor: function (Word) {
this._Word = Word
},
print: function () {
console.log(this._Word)
}
}
ES2015クラスを使用する意思がある場合(私はすでに答えました ここ ですが、便宜上繰り返します)、
eSNextでは、次のように Javascriptプライベート変数 を使用できます。
class Foo {
#bar = '';
constructor(val){
this.#bar = val;
}
otherFn(){
console.log(this.#bar);
}
}
プライベートフィールド#barは、Fooクラスの外部からはアクセスできません。
this
を使用してコードを少し変更すると機能します。 Printer.prototype.print
の正しいインスタンスがa
オブジェクトに対してインスタンス化されていませんでした。
var Printer = (function(){
var _Word;
Printer = function(Word){
this._Word = Word;
}
_print = function(){
console.log(this._Word);
}
Printer.prototype = {
print: _print
}
return Printer;
})();
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Alex
b.print(); //Prints Bob