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 回答