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

时间:2012-07-16 21:27:51

标签: javascript oop constructor

我有函数构造函数。我想控制哪个函数(对象)可以调用它。这是一个例子:

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 个答案:

答案 0 :(得分: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。它与您在此处提出的内容并不完全相同,但使用了一些相同的技术(将隐私中的私有数据隐藏起来)。

答案 1 :(得分:1)

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

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

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

另一个选项是默认使用一个假的全局变量,并在要允许的函数中指定为true,并检查该函数。

答案 2 :(得分:0)

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

e.g:

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范围之外不可见。

答案 3 :(得分:0)

您根本不能公开Foo

(function() {



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

    function Foo() {

    }

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

})();

当作为构造函数调用时,函数返回创建的对象,除非您显式返回非原始值。所以让return;仍然会返回创建的对象。