我使用闭包来创建具有私有和公共方法的对象。它看起来像这样 -
var Dog = (function() {
function Dog() {}
var size = 'big';
var _privateSaySize = function() {
return 'I am a ' + size + ' dog.';
}
Dog.prototype.publicSaySize = function() {
return _privateSaySize();
}
return Dog;
})();
但是现在我希望有一个只有私有函数并且由另一个对象继承的对象。但这在JavaScript中是否可行?
答案 0 :(得分:8)
不,你不能。
JavaScript继承是基于原型的,因此您只能“扩展”原型中的方法。
答案 1 :(得分:5)
JavaScript中的变量(函数)隐私是通过函数范围完成的。只有从封闭范围导出它们才能从外部访问它们,没有别的办法。
要创建一个方法可以访问私有函数的对象,您只需将它放在同一范围内。对象是否是从其他对象继承的对象是无关紧要的。
function Dog() {}
function Dalmatian() {}
Dalmation.prototype = Object.create(Dog.prototype);
Dalmation.prototype.size = "big";
function Dackel() {}
Dackel.prototype = Object.create(Dog.prototype);
Dackel.prototype.size = "small";
(function() {
// private function
function say(s) {
console.log("I'm a "+s+" dog");
}
// both accessible from the Dog and Dackel public methods
Dog.prototype.saySize = function() {
say(this.size || "normal");
};
Dackel.prototype.saySize = function() {
say(this.size + " but loud");
};
})();
new Dog().saySize();
new Dalmatian().saySize();
new Dackel().saySize();
答案 2 :(得分:2)
有点...... 正如Bergi所指出的那样,访问是由范围定义的,所以如果你在父母的直接内部定义继承者,你可以大致得到你想要的东西。
var BarkingDog;
var Dog = (function() {
function Dog() {}
var size = 'big';
var _privateSaySize = function() {
return 'I am a ' + size + ' dog.';
};
Dog.prototype.publicSaySize = function() {
return _privateSaySize();
};
BarkingDog = (function () {
function BarkingDog () {}
var say = 'woof';
BarkingDog.prototype = new Dog();
BarkingDog.prototype.bark = function () {
return _privateSaySize() + ' ' + say;
};
return BarkingDog;
})();
return Dog;
})();
var myDog = new BarkingDog();
console.log(myDog.bark());
console.log(myDog.publicSaySize());
不确定为什么你会想要...:D
答案 3 :(得分:1)
您希望一个实例继承另一个实例的私有状态吗?当然,你可以用JavaScript做到这一点。首先,我们需要定义一个效用函数:
function weakBind(functable, prototype, state) {
return function () {
return functable.apply(this, Object.getPrototypeOf(this) === prototype ?
[state].concat(Array.prototype.slice.call(arguments)) : arguments);
};
}
现在我们可以按如下方式创建基类:
var Dog = (function () {
function Dog() {
if (this instanceof Dog) {
// constructor code
} else return Object.create(private);
}
var public = Dog.prototype, private = Object.create(public, {
size: {
value: "big"
}
});
public.saySize = weakBind(function (private) {
return "I am a " + private.size + " dog.";
}, public, private);
return Dog;
}());
现在您可以按如下方式创建一只狗:
var dog = new Dog;
alert(dog.saySize()); // I am a big dog.
alert(dog.size); // undefined
我们可以按如下方式继承私有状态:
var Chihuahua = (function () {
function Chihuahua() {
Dog.call(this);
}
var private = Dog();
Object.defineProperty(private, {
size: {
value: "small"
}
});
var public = Chihuahua.prototype = Object.create(Dog.prototype);
public.saySize = weakBind(public.saySize, public, private);
return Chihuahua;
}());
现在您可以按如下方式创建奇瓦瓦州:
var chi = new Chihuahua;
alert(chi.saySize()); // I am a small dog.
alert(chi.size); // undefined
请参阅演示:http://jsfiddle.net/b3Eyn/
注意:我写这个答案只是为了表明可以在JavaScript中继承私有状态。但是,我建议你不要使用这种模式。如果你设计好你的代码,那么你首先不需要继承私有状态。
答案 4 :(得分:0)
您可以避免使用点表示法。但它并非真正私密。
var Dog = (function() {
function Dog() {}
var size = 'big';
Dog.prototype['-privateSaySize'] = function() {
return 'I am a ' + size + ' dog.';
}
Dog.prototype.publicSaySize = function() {
return this['-privateSaySize']();
}
return Dog;
})()