Reputation: 30805
I have function-constructor. I want to control what function (object) can call it. Here'e the example:
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
Is it possible to implement in JS? Are there some functions for such kind of control?
What will be created from Foo if the creation will be aborted this way?
Upvotes: 0
Views: 67
Reputation: 707556
You can't reliably identify the caller in a constructor across browsers, particularly in the new strict mode.
Instead, you can define Foo()
inside of Bar()
or define them both inside of the same self executing function so that Foo()
is not known outside the scope of Bar()
and can thus only be created there.
Some examples:
// 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() {
}
}
You may find this article instructional which discusses various ways of making instance data truly private: http://www.crockford.com/javascript/private.html. It's not exactly the same as what you're asking here, but uses some of the same techniques (hiding private data in a closure).
Upvotes: 2
Reputation: 5199
You can try something like: (don't think this is cross browser solution however)
var caller = Foo.caller.name;
if (caller != "Bar") {
}
See this answer for more details.
Another option is to have a global variable that is false by default and you assign to true in the functions you want to allow and to a check in that function.
Upvotes: 1
Reputation: 140228
You could simply not expose Foo
:
(function() {
function Bar() {
var foo = new Foo();
}
function Foo() {
}
window.Bar = Bar; //Expose bar to global scope
})();
A function, when called as constructor returns the created object unless you explicitly return a non-primitive value. So having return;
would still return the created object.
Upvotes: 0
Reputation: 82923
If you want to restrict the creation of the Foo object within Bar, then you can define the function with in 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();
.
.
.
.
}
Now Foo is not visible outside the Bar scope.
Upvotes: 0