Javascript:从原型方法调用私有方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8580540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript: Calling private method from prototype method
提问by sixtyfootersdude
I am sure that this must be a pretty common question but after scouring the internets for several hours, I have not found an answer. Here is the question:
我相信这一定是一个很常见的问题,但在互联网上搜索了几个小时后,我还没有找到答案。这是问题:
Suppose that I have an interface called mammal. Every Mammal has to be able to sleep and eat. (In the future I may throw exceptions for the Mammal class to force children to implement the function).
假设我有一个叫做哺乳动物的接口。每个哺乳动物都必须能够睡觉和进食。(将来我可能会为 Mammal 类抛出异常以强制孩子们实现该功能)。
function Mammal() {};
Mammal.prototype.eat = function() {};
Mammal.prototype.sleep = function() {};
Now suppose that I have a Dog class who implements the Mammal class:
现在假设我有一个实现 Mammal 类的 Dog 类:
function Dog() {};
Dog.prototype = new Mammal();
Dog.prototype.eat = function() {
...
};
Dog.prototype.sleep = function() {
...
};
The dog's eat function is very complicated and I would like to use a helper function. I have not been able to figure out what the best way to do this is. Here are the points of consideration:
狗的吃函数很复杂,我想用一个辅助函数。我一直无法弄清楚做到这一点的最佳方法是什么。以下是考虑的要点:
- The helper function should never be called from outside of the dog class so ideally it should be private.
- The eat function does not have access to private functions (prototypes do not have access to private functions)
- I could put the helper function into a privalaged function but:
- This would still be a public function -> ie: everyone has the right to call it
- It would not be part of the prototype so every dog would need to have its own helper function. If there were lots of dogs this seems inefficient.
- I cannot make the eat function a privaliged function because in order for prototype inheritance to work it needs to be part of the prototype.
- 永远不应该从 dog 类外部调用辅助函数,因此理想情况下它应该是私有的。
- Eat 函数无权访问私有函数(原型无权访问私有函数)
- 我可以将辅助函数放入私有函数中,但是:
- 这仍然是一个公共功能 -> 即:每个人都有权调用它
- 它不会成为原型的一部分,所以每只狗都需要有自己的辅助功能。如果有很多狗,这似乎效率低下。
- 我不能让eat 函数成为一个私有函数,因为为了让原型继承工作,它需要成为原型的一部分。
Question: How can I call a private function from a prototype function? Or more generally: When an object (child object) inherits from another object (parent object) how should children methods use helper functions and is it possible to make these private?
问题:如何从原型函数调用私有函数?或者更一般地说:当一个对象(子对象)从另一个对象(父对象)继承时,子方法应该如何使用辅助函数,是否可以将它们设为私有?
回答by Alex Wayne
Define your Dog
"class" in a closure. Then you can have shared priveliged functions. Just know you will have to be careful about this
binding properly when you call it.
Dog
在闭包中定义您的“类”。然后您可以共享特权功能。只要知道this
在调用它时必须小心正确绑定。
var Dog = (function() {
function Dog() {};
// Common shared private function, available only to Dog.
var privateHelper = function() { ... };
Dog.prototype = new Mammal();
Dog.prototype.eat = function() {
privateHelper()
// Or this if the helper needs to access the instance.
// privateHelper.call(this);
...
};
return Dog;
})();
A function on a prototype is still just a function. So follows the same scope and closure access rules as any another function. So if you define your entire Dog
constructor and prototype and a secluded island of scope that is the self executing function, you are welcome to share as much as you like without exposing or polluting the public scope.
原型上的函数仍然只是一个函数。因此遵循与任何其他函数相同的范围和闭包访问规则。因此,如果您定义了整个Dog
构造函数和原型以及一个作为自执行函数的隐蔽作用域岛,那么欢迎您随意分享,而不会暴露或污染公共作用域。
This is exactly how CoffeeScript classescompile down to JS.
这正是CoffeeScript 类编译成 JS 的方式。
回答by Bergi
It's not possible. If you need access to private variables/functions, you must use privileged (helper) functions.
这是不可能的。如果您需要访问私有变量/函数,则必须使用特权(帮助程序)函数。
It sometimes is possible to use helper functions in a local closure scope instead of private helper functions (in the constructor scope), which would be accessible from prototype functions. See Alex Wayne's or Raynos' answers for that.
有时可以在局部闭包作用域中使用辅助函数而不是私有辅助函数(在构造函数作用域中),后者可以从原型函数访问。请参阅 Alex Wayne 或 Raynos 的答案。
You said:
你说:
I cannot make the eat function a privaliged function because in order for prototype inheritance to work it needs to be part of the prototype.
我不能让eat 函数成为一个私有函数,因为为了让原型继承工作,它需要成为原型的一部分。
Why not?
为什么不?
MammalPrototype = {
eat: function() {},
sleep: function() {}
};
function Dog(color) {
...
this.eat = function() {
... // using private functions
MammalPrototype.eat.call(this, options) // ?
};
};
Dog.prototype = Object.create(MammalPrototype); // inherit from an object
new Mammal()
is OK when Mammal really is only a empty function. See https://stackoverflow.com/a/5199135/1048572for how this works. The shim proposed there is of course not what a native implementation does, but it is exactly what we need here. Do not create a instance just to inherit from it!
new Mammal()
当哺乳动物真的只是一个空函数时是可以的。有关其工作原理,请参阅https://stackoverflow.com/a/5199135/1048572。那里提出的 shim 当然不是本机实现所做的,但它正是我们在这里所需要的。不要创建一个实例只是为了继承它!
Dog.prototype.sleep = function() {
...
};
function Dalmatian() {
Dog.call(this, "black.white");
...
}
Dalmatian.prototype = Object.create(Dog.prototype); // sic
Dalmatian.prototype.xyz = function() {};
To call the super constructor on this
means to receive all privileged methods, and their functionality. You will need to do this if you are using private variables and/or functions in "classes" you inherit from, otherwise all calls to inherited privileged functions will affect only the one instance you've set your prototype
to.
调用超级构造函数this
意味着接收所有特权方法及其功能。如果您在继承自的“类”中使用私有变量和/或函数,则需要这样做,否则对继承的特权函数的所有调用将仅影响您设置的一个实例prototype
。
回答by Raynos
When an object (child object) inherits from another object (parent object) how should children methods use helper functions and is it possible to make these private?
当一个对象(子对象)从另一个对象(父对象)继承时,子方法应该如何使用辅助函数,是否可以将它们设为私有?
You need some layers of abstraction to achieve what you want: Live Example
你需要一些抽象层来实现你想要的:Live Example
Uses klass
用途 klass
var Mammal = klass(function (privates) {
privates.local_helper = function () {
console.log("local_helper invoked");
}
return {
constructor: function () {
console.log("mammal constructed");
privates(this).caneat = true;
},
eat: function () {
privates.local_helper();
console.log("mammal eat");
},
sleep: function () {
console.log("mammal sleep");
}
};
});
var Dog = klass(Mammal, function (privates, $super) {
return {
constructor: function () {
$super.constructor.call(this);
console.log("dog constructed");
},
eat: function () {
$super.eat.call(this);
privates.local_helper();
console.log("dog eat");
console.log(privates(this).caneat);
}
};
});
var dog = new Dog();
dog.eat();