Javascript 这是一种捕获闭包定义堆栈的方法吗?

Javascript 这是一种捕获闭包定义堆栈的方法吗?,javascript,oop,closures,callstack,scope-chain,Javascript,Oop,Closures,Callstack,Scope Chain,我目前正在研究一种将JavaScript函数保护为私有函数的方法,如果调用方无效,将引发异常。然后我在这里遇到了一个问题:如果在一个有效的调用方中定义了一个闭包,那么这是从内部闭包中获取有效调用方的一种方法吗 例如: function validCaller() { var self = this; self.privateFunction1(); $.each([/*...*/], function (key, val) { self.privateFu

我目前正在研究一种将JavaScript函数保护为私有函数的方法,如果调用方无效,将引发异常。然后我在这里遇到了一个问题:如果在一个有效的调用方中定义了一个闭包,那么这是从内部闭包中获取有效调用方的一种方法吗

例如:

function validCaller() {
    var self = this;
    self.privateFunction1();
    $.each([/*...*/], function (key, val) {
        self.privateFunction2(); 
    });
}
当然,
privateFunction1
将正确获取调用者
validCaller
,但是
privateFunction2
将获取匿名函数作为调用者,因此访问将被拒绝

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

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

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


保守秘密的合理方法就是不要告诉任何人

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
的方法之外,没有人能够调用
private1
private2
。。。但其他人甚至找不到这些名字,也不会有意外名字冲突的风险

您可以对私有数据成员使用相同的方法。只需将它们声明为简单的局部变量
varx,不要使用
this.x
语法来访问它们,而只使用
x
。至于这些方法,没有人能够访问它们,甚至不会有意外覆盖的风险

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

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

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


PS:我不知道你为什么要这么做,但听起来很奇怪。

你不应该重新发明轮子,而应该使用。使用
caller
不会奏效,因为您可能会遇到一个循环:您的“public1”是预定义的,因此很容易访问隐藏的“private1”和“private2”;但是我希望在运行时提供我的“validCaller”,所以“privateFunction1”和“privateFunction2”不能隐藏。@Knly:如果可以在运行时添加有效的调用方,谁说哪个调用方有效,哪个无效?检查这个:定义({name:'ClassName',privates:{private1:function(){…},publics:{public1:function(){…});
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);
       ...
   };
}