我有这段代码:
var Human=function(name){
this._name=name;
};
Human.prototype.Shout=function(){
alert(this._name);
};
var tom=new Human("tom");
var john=new Human("john");
alert(tom.Shout===john.Shout);
现在._name不是“私人”。我想使._name“私有”,但同时我不希望为每个人类实例创建额外的函数(换句话说,tom.Shout必须是===到john.Shout),因为创建了附加函数每个实例都很好..不必要(ok offtopic - 我们可以在另一个线程上讨论这个)
我的结论是,我想要实现的目标(将._name设为“私有”,同时拥有tom.Shout===john.Shout
)是不可能的。
但我只想在得出任何结论之前保持200%的肯定。
(只要符合要求,我就欢迎任何黑客攻击,即不为每个实例创建额外的功能)
如果我们必须创建其他函数来进行范围确定,那么这个数字应该是一个固定的数字,并且该数字不应该随着每个额外的Human实例而增加。
答案 0 :(得分:3)
<强>更新强>
您正在寻找@name
这是一个实例变量。在es.next中祈祷它,但我们还没有。也许两年后。
如果您关心干净的API,那么这是您的解决方案:
function Class(foo) {
Class.priv(this).foo = foo;
}
Class.priv = (function() {
var cache = [],
uid = 1;
return function(obj) {
if (!this.__id) {
this.__id = uid;
cache[uid++] = {};
}
return cache[this.__id];
};
}());
Class.prototype.bar = function() {
console.log(Class.priv(this).foo);
}
将所有数据存储在缓存中,作为构造函数的函数。对象上没有数据混乱。
<强>原始强>
然而,没有“私人”这样的东西。
您所能做的就是在函数内创建一个局部变量。
构造函数
var Human = function(name) {
// local variable.
var _name = name;
}
有一个局部变量由于本地的定义,在构造函数之外是不可用的。
这意味着您无法在原型等外部代码中访问它。
但是,您可以使用ES5
进行只读var Human = function(name) {
Object.defineProperty(this, "name", { value: name });
}
如果你能真正实现你的要求,你就会在js上取得巨大的突破。我试图这么做几个小时。
不同的模式是:
var Human = function(name) {
this.name = name;
return {
Shout: this.Shout.bind(this)
};
}
Human.prototype.Shout = function() {
console.log(this.name);
}
这会产生调用.bind
并为每个实例创建新对象的开销。
答案 1 :(得分:1)
怎么样?
var Human = function (name) {
var _name = name;
this.getName = function () {
return _name;
}
};
Human.prototype.Shout = function () {
alert(this.getName());
};
var tom = new Human("tom");
var john = new Human("john");
tom.Shout(); // tom
john.Shout(); // john
alert(tom.Shout === john.Shout); // true
编辑: 前者为GET属性创建了另一个函数, 没有创建额外的功能是不可能的。
答案 2 :(得分:1)
读过这个问题,不明白,因为this._name
不是私密的,所以问题有点奇怪。这就是my test中原型方法添加一次并可用于所有实例的方式。我再说一遍:this._name
在这里不是私密的。如果添加局部变量,并希望通过原型方法中的闭包访问它,则调用局部变量的值将为所有实例生成相同的值。
无论如何,使用这个构造函数,this._name getter和shout方法被添加到原型链中一次,从而可用于Human的所有实例。
function Human(name) {
if (!(this instanceof Human)){
return new Human(name);
}
this._name = name;
if (!Human.prototype.Name){
Human.prototype.Name = function(val){
if (val){
this._name = val;
return this;
}
return this._name;
};
Human.prototype.shout = function(){
alert(this._name);
}
}
}