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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 03:52:25  来源:igfitidea点击:

Javascript: Calling private method from prototype method

javascript

提问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 thisbinding 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 Dogconstructor 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 thismeans 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 prototypeto.

调用超级构造函数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();