【问题标题】:Is it a way to capture the stack of closure definition?它是一种捕获闭包定义堆栈的方法吗?
【发布时间】:2012-07-19 09:12:05
【问题描述】:

我目前正在研究一种将 JavaScript 函数保护为 private 的方法,如果调用者无效,则会引发异常。那么我这里有个问题:如果一个闭包是在一个有效的调用者内部定义的,是不是一种从内部闭包中获取有效调用者的方法?

例如:

function validCaller() {
    var self = this;
    self.privateFunction1();
    $.each([/*...*/], function (key, val) {
        self.privateFunction2(); 
    });
}

当然,privateFunction1 会正确获取调用者validCaller,但privateFunction2 会获取匿名函数作为调用者,因此访问将被拒绝。

如果我通过表达式caller.caller.caller从调用堆栈中获取validCaller不是正确的方法,因为我无法确定我应该回溯多少层,并且在某些特殊情况下,匿名函数需要在validCaller之外调用。

也许我用复杂的方式问了这个问题,简单的方式是:

如何捕获函数的作用域链?

【问题讨论】:

标签: javascript oop closures callstack scope-chain


【解决方案1】:

保持隐私的合理方法就是不要告诉任何人...

function MyObject(a, b, c)
{
    this.a = a;
    this.b = b;
    this.c = c;

    // Note: NOT using this.private1 = function() { ... }
    function private1()
    {
       ...
    }

    function private2()
    {
       ...
    }

    // Public methods
    this.public1 = function()
    {
       ...
       private1(); // Note; not using "this." in the call
       ...
       private2();
    }
 }

使用这种方法,除了MyObject 的方法之外,没有人能够调用private1private2...,而且其他人甚至无法找到这些名称,并且不会有被意外的名称冲突。

您可以对私有数据成员使用相同的方法。只需在构造函数中将它们声明为简单的局部变量var x;,并且不要使用this.x 语法来访问它们,而只需使用x。至于方法,任何人都无法访问它们,甚至不存在被无意覆盖的风险。

如果您真的想要运行时检查以防止未经授权的函数调用您的方法,您可以使用某种“安全令牌”。

function MyObject()
{
   var authorization = []; // An empty array will do

   this.private_method = function(auth) {
       if (auth !== authorization) throw "Unauthorized call";
       ...
   };

   this.public_method = function() {
       ...
       this.private_method(authorization);
       ...
   };
}

通过这种方法,您甚至可以确定哪个实例正在调用私有方法。

如果您希望任何实例都具有此功能,则将构造函数本身设为闭包,从封闭范围捕获授权令牌。

PS:我不太了解您为什么要首先这样做,但听起来很奇怪。

【讨论】:

  • 你的'public1'是预定义的,所以很容易访问隐藏的'private1'和'private2';但我希望在运行时给出我的“validCaller”,所以不能隐藏“privateFunction1”和“privateFunction2”。
  • @Knly:如果可以在运行时添加有效的调用者,谁说哪个调用者是有效的,哪个不是?
  • 检查这个:define({name: 'ClassName', privates: {private1: function(){...}}, publics: {public1: function(){...}}} );
猜你喜欢
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 2020-06-11
  • 2021-05-13
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
相关资源
最近更新 更多