0

我有函数构造函数。我想控制什么函数(对象)可以调用它。这是示例:

function Bar() {

    // foo can be created only here, when Bar is instantiated
    var foo = new Foo();
}

function Foo() {

   // I'd like to have something like this here:
   if (caller != Bar) {
       alert("Not allowed, the caller is not Bar");
       return;
   }
}

var bar = new Bar();    // this is correct, Foo can be created inside Bar
var foo = new Foo();    // prints "Not allowed, the caller is not Bar" and exits

可以在JS中实现吗?这种控制有一些功能吗?

如果以这种方式中止创建,将从 Foo 创建什么?

4

4 回答 4

2

您无法跨浏览器可靠地识别构造函数中的调用者,尤其是在新的严格模式下。

相反,您可以在同一个自执行函数内部定义Foo()Bar()定义它们,这样Foo()在范围之外不知道,Bar()因此只能在那里创建。

一些例子:

// Bar() is only known within a single scope
var Foo;
(function(){
    Foo = function() {
    }

    function Bar() {
    }
})();


// Bar() is only known inside of Foo()'s constructor
function Foo() {
    function Bar() {
    }
}

您可能会发现这篇说明性的文章讨论了使实例数据真正私有的各种方法:http ://www.crockford.com/javascript/private.html 。它与您在此处询问的内容不完全相同,但使用了一些相同的技术(将私有数据隐藏在闭包中)。

于 2012-07-16T21:30:36.187 回答
1

您可以尝试类似的方法:(但不要认为这是跨浏览器解决方案)

var caller = Foo.caller.name;
if (caller != "Bar") {
}

有关更多详细信息,请参阅答案。

另一种选择是拥有一个默认为 false 的全局变量,然后在要允许的函数中分配为 true 并检查该函数。

于 2012-07-16T21:34:13.333 回答
0

如果要限制在 Bar 中创建 Foo 对象,则可以在 Bar 中定义函数。

例如:

function Bar() {
  var Foo = function Foo() {

    // I'd like to have something like this here:
    if (caller != Bar) {
       alert("Not allowed, the caller is not Bar");
       return;
    }
  }
  var foo = new Foo();
    .
    .
    .
    .
}

现在 Foo 在 Bar 范围之外是不可见的。

于 2012-07-16T21:31:06.393 回答
0

你不能简单地暴露Foo

(function() {



    function Bar() {
        var foo = new Foo();
    }

    function Foo() {

    }

    window.Bar = Bar; //Expose bar to global scope

})();

除非您显式返回非原始值,否则作为构造函数调用的函数将返回创建的对象。所以 havereturn;仍然会返回创建的对象。

于 2012-07-16T21:32:02.250 回答