繁体   English   中英

Javascript:从原型方法调用私有方法

[英]Javascript: Calling private method from prototype method

我确信这一定是一个非常常见的问题但是在对互联网进行了几个小时的搜索之后,我还没有找到答案。 这是一个问题:

假设我有一个名为哺乳动物的界面。 每个哺乳动物都必须能够入睡和进食。 (将来我可能会抛出Mammal类的异常来强制孩子实现这个功能)。

function Mammal() {};

Mammal.prototype.eat = function() {};

Mammal.prototype.sleep = function() {};

现在假设我有一个实现Mammal类的Dog类:

function Dog() {};

Dog.prototype = new Mammal();

Dog.prototype.eat = function() {
    ...
};

Dog.prototype.sleep = function() {
    ... 
};

狗的吃功能非常复杂,我想使用辅助功能。 我无法弄清楚最好的办法是什么。 以下是要点:

  • 永远不应该从dog类的外部调用辅助函数,所以理想情况下它应该是私有的。
  • eat函数无法访问私有函数(原型无法访问私有函数)
  • 我可以将辅助函数放入一个privalaged函数,但是:
    • 这仍然是一个公共职能 - >即:每个人都有权称呼它
    • 它不会是原型的一部分,所以每只狗都需要有自己的辅助功能。 如果有很多狗,这似乎效率低下。
  • 我不能使eat函数成为一个私有函数,因为为了使原型继承工作,它需要成为原型的一部分。

问题:如何从原型函数调用私有函数? 或者更一般地说:当一个对象(子对象)继承自另一个对象(父对象)时,子方法应该如何使用辅助函数,是否可以使这些私有?

在闭包中定义你的Dog “class”。 然后你可以拥有共享的priveliged功能。 只要知道在调用它时你必须要小心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;
})();

原型上的函数仍然只是一个函数 因此,遵循与任何其他函数相同的范围和闭包访问规则。 因此,如果您定义整个Dog构造函数和原型以及作为自执行函数的隐蔽的作用域,欢迎您在不暴露或污染公共范围的情况下尽可能多地共享。

这正是CoffeeScript类编译成JS的方式。

这是不可能的。 如果需要访问私有变量/函数,则必须使用特权(辅助)函数。

有时可以在本地闭包范围中使用辅助函数而不是私有辅助函数(在构造函数范围内),这可以从原型函数访问。 请参阅Alex Wayne或Raynos的答案。

你说:

我不能使eat函数成为一个私有函数,因为为了使原型继承工作,它需要成为原型的一部分。

为什么不?

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

当Mammal真的只是一个空函数时, new Mammal()是可以的。 有关其工作原理,请参阅https://stackoverflow.com/a/5199135/1048572 提议的垫片当然不是本机实现的功能,但它正是我们在这里所需要的。 不要创建一个只是为了继承它的实例!

Dog.prototype.sleep = function() {
    ... 
};

function Dalmatian() {
    Dog.call(this, "black.white");
    ...
}
Dalmatian.prototype = Object.create(Dog.prototype); // sic
Dalmatian.prototype.xyz = function() {};

this调用超级构造函数意味着接收所有特权方法及其功能。 如果在继承的“类”中使用私有变量和/或函数,则需要执行此操作,否则对继承的特权函数的所有调用将仅影响您将prototype设置为的一个实例。

当一个对象(子对象)继承自另一个对象(父对象)时,子方法如何使用辅助函数,是否可以使这些私有?

您需要一些抽象层来实现您想要的: 实例

使用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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM