是否可以在函数构造函数中识别哪个对象调用它,并在错误的对象调用时中止创建

Is it possible to identify in the function-constructor what object calls it and abort creation if the wrong object calls?

本文关键字:对象 调用 错误 创建 函数 构造函数 识别 是否      更新时间:2023-10-24

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

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创建什么?

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

相反,您可以在Bar()内部定义Foo(),也可以在同一个自执行函数内部定义它们,这样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.它与您在这里所要求的不完全相同,但使用了一些相同的技术(在闭包中隐藏私有数据)。

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

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

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

另一种选择是有一个默认为false的全局变量,并在要允许的函数中指定为true,并在该函数中进行签入。

如果您想限制在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范围之外不可见。

您根本无法公开Foo:

(function() {

    function Bar() {
        var foo = new Foo();
    }
    function Foo() {
    }
    window.Bar = Bar; //Expose bar to global scope
})();

函数在作为构造函数调用时会返回创建的对象,除非显式返回非基元值。因此,拥有return;仍然会返回创建的对象。