2

私はここにこのコードを持っています:

var Person = (function() {
    var name;

    var PersonConstructor = function(n) {
        name = n;
    };

    PersonConstructor.prototype.getName = function() {
        return name;
    };

    return PersonConstructor;

})();

var people = [];
var person1 = new Person("Foo");
var person2 = new Person("Bar");
alert(person1.getName()); // I want it to be Foo
people.push(person1);
people.push(person2);

ここからクラスをエミュレートするというアイデアを思いつきました。var name;しかしもちろん、私はプライベート変数も静的変数であるという事実を無視しました。これは私の現在の努力を損なうので、この例でプライベートな振る舞いを維持する方法があるかどうか知りたいのですが、静的な振る舞いを避けますか?

4

3 に答える 3

2

を使用しthisます。

var Person = (function() {
  var PersonConstructor = function(n) {
    this.name = n;
  };

  PersonConstructor.prototype.getName = function() {
    return this.name;
  };

  return PersonConstructor;    
})();

残念ながら、これではプライベート状態は保持されません。

于 2012-04-08T11:54:57.743 に答える
1

これは単なるスコープの問題です。

var Person = (function(){

    var PersonConstructor = function(n){ 
        // *************************************************************** 
        // PRIVATE VARIABLES AND FUNCTIONS 
        // ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE 
        // *************************************************************** 

        var myName=n?n:"John Doe";

        // *************************************************************** 
        // PRIVILEGED METHODS 
        // MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS 
        // MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS 
        // *************************************************************** 
        this.toString=this.getName=function(){ return myName } 
    } 
    return PersonConstructor;
})();

var person1 = new Person("foo");
var person2 = new Person("bar");

alert(person1.getName());
alert(person1.toString());
alert(person1.myName);

// alerts "foo", "foo", undefined

編集-これが私の元の解決策です。

var Person = function(n){ 
    // *************************************************************** 
    // PRIVATE VARIABLES AND FUNCTIONS 
    // ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE 
    // *************************************************************** 

    var myName=n?n:"John Doe";

    // *************************************************************** 
    // PRIVILEGED METHODS 
    // MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS 
    // MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS 
    // *************************************************************** 
    this.toString=this.getName=function(){ return myName } 

} 

var person1 = new Person("foo");
var person2 = new Person("bar");

alert(person1.getName());
alert(person1.toString());
alert(person1.myName);

// alerts "foo", "foo", undefined
于 2012-04-08T13:13:51.387 に答える
0

プロトタイプで作業する場合、「プライベート」はありません。

私的な状態には価値がないことに注意する必要があります。疫病のように避けてください。クロージャーは醜くて高価です。

var o = {
    name: value
}

しかし、あなたが妄想的であることを主張し、私的な状態をひどく欲しがっているなら、

状態をクロージャに保存できます

function nameHolder(name) {
    return {
        get name() {
            return name
        },
        set name(n) {
            name = n
        }
    }
}

これは非常に非効率的であり、ほとんどメリットがないことに注意してください。

または、ウィークマップに状態を保存することもできます

function privates() {
    var map = new WeakMap()

    return function (key) {
        var v = map.get(key)
        if (!v) {
            v = {}
            map.set(key, v)
        }
        return v
    }
}

var NameHolder = (function () {
    var state = privates()

    return {
        constructor: function (name) {
            state(this).name = name
        },
        getName: function () {
            return state(this).name
        }
    }
}())

WeakMapブラウザのサポートは存在しないため、 pd.Nameを使用してエミュレートします

于 2012-04-08T11:57:33.230 に答える