Within a Javascript function it is a rather simple detection whether the function has been simply executed or being executed as an object instance constructor (using new
keyword).
// constructor
function SomeType() {
if (this instanceof SomeType)
// called as an object instance constructor
else
// the usual function call
}
That's fine, this has been answered here at SO at least a few times before.
So let's suppose now that our constructor function calls another function that I defined directly on Function prototype and is therefore accessible to all functions - the main purpose why I'm doing it this way.
Function.prototype.doSomething = function doSomething() {
// what code here?
};
// constructor
function SomeType() {
SomeType.doSomething();
}
Main problem
How can we now detect within doSomething
the same for SomeType
function?
The reason why I'd like to detect it is I'm writing a function that adopts/injects constructor parameters as constructed object instance members with the same name. Of course this function should only execute when it's being called by a constructor function and not by a function called regularly.
This is my answer to another question where you can see my adoptArguments
function that puts object constructor arguments into constructed object instance as members.
Workaround that enforces specific usage = bad
I have a possible workaround that I don't want to use, because it enforces correct usage - execution context injection. This is the code that can detect object instance constructor execution:
Function.prototype.doSomething = function doSomething() {
if (this instanceof doSomething.caller)
{
// object instance construction
}
else return; // nope, just normal function call
};
// constructor
function SomeType() {
// required use of ".call" or ".apply"
SomeType.doSomething.call(this);
}
This idea may spark some ideas of your own to solve the original problem
One possible solution is passing the constructor context as parameter. There is no need to pass in the arguments object as it can be accessed through
this.arguments
, as you are doing inadoptArguments
on your linked answer.WARN: your
adoptArguments
function has a serious bug, see belowActually, that's impossible, one cannot know in JS whether an user function was called as a constructor. The
this instanceof
test is sufficient for the usual cases, but only checks whether the context does inherit from the class's prototype.You cannot for the same reason, and you cannot do the
instanceof
test without passingthis
as a parameter to yourdoSomething
.I recommend not to do so via a function call inside the constructor. Instead, try to decorate the constructor function, so that you will have access to all the values that you need right away:
Then instead of
do