我有函数构造函数。我想控制哪个函数(对象)可以调用它。这是一个例子:
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创建什么?
答案 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;
仍然会返回创建的对象。