Javascript中的私人成员。它们可以是非静态的吗?

时间:2012-04-08 11:50:01

标签: javascript static private encapsulation members

我这里有这个代码:

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

我有了从here.模拟类的想法。但当然,我忽略了私有变量var name;也是静态变量的事实。由于这是在扼杀我目前的努力,我想知道是否有办法在这个例子中保持私有行为,但避免静态行为?

3 个答案:

答案 0 :(得分:2)

使用this

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

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

  return PersonConstructor;    
})();

不幸的是,这不会保留私人状态。

答案 1 :(得分: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

答案 2 :(得分: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

进行模拟