使用技巧在javascript中强制执行私有继承

Using tricks to enforce private inheritance in javascript

本文关键字:继承 强制执行 javascript 使用技巧      更新时间:2023-09-26

所以我想出了一些技巧来检查并查看是否从对象内部调用了函数。有人能给我一些不做这种事的好理由吗?

function Poo(){
this.myFunc=function(){
    for(x in this)
    {
           if (this.myFunc.caller==this[x]) {
               alert(this.myFunc.caller==this[x]);
               return;}
     }
      alert(false);             
    }
    this.myFunc2=function(){this.myFunc();}
}
var mine=new Poo();
mine.myFunc(); //calling directly not allowed prints false
mine.myFunc2(); //called from a member function allowed prints true

你可以做任何你想做的事情,但是,我可以向你展示一个你的方法不起作用的例子:

function Poo(){
  this.myFunc = function () {
    for(x in this) {
      if (this.myFunc.caller == this[x]) {
        console.info('internal call, accepted');
        return;
      }
    }
    console.error('no external calls allowed');
  };
  this.myFunc3 = function () {
    var self = this;
    // this is a standard way of
    // passing functions to callbacks
    // (eg, ajax callbacks)
    this.myFunc4(function() {
      self.myFunc();
    });
  }
  this.myFunc4 = function (callback) {
    // do stuff...
    callback();
  };
}
var mine = new Poo();
mine.myFunc3();

myFunc3在对象中,所以我认为您会期望在它给myFunc4(也在对象中)的回调中调用myFunc。然而,调用者不能很好地处理匿名函数。

此外,在比较函数的同时迭代整个实例方法和属性绝对不是"面向对象"的方法。由于您试图模拟private方法,我假设OO就是您想要的。

您的方法没有利用JS提供的任何功能,只是以一种不雅的方式(重新)构建了现有的功能。虽然出于学习目的,这可能很有趣,但我不建议在发布生产代码时使用这种心态。

stackover上还有另一个问题,它有一个你可能感兴趣的答案:为什么arguments.callee.caller属性在JavaScript中被弃用?

edit:我如何从回调中调用myFunc的小更改,在匿名函数this中不是实例。

我不能给你一个不这样做的好理由,但有一个更简单的解决方案。

function Poo() {
     var myFunc = function() {
          alert('myfunc');
     };
     this.myFunc2 = function() {
         myFunc();
     }
}
var mine = new Poo();
var mine.myFunc();  // Won't work
var mine.myFunc2(); // Will work

为什么不使用类似模块模式的东西来隐藏"私有"方法的实现呢。

var poo = function(){
   var my = {},
       that = {};
   my.poo = function() {
      // stuff
   };
   that.foo = function(){
      my.poo(); //works
      // more stuff
   };
   return that;
};
poo.foo(); // works
poo.poo(); // error