3

I need a constructor that shouldn't be called as a function:

function Foo() {
  ...
};

var f = new Foo(); // ok
Foo();  // throws error

Searched in here and found that maybe I can use following to check if it is called as a function

if (!(this instanceof arguments.callee))

If so then what error should I throw?

And, is there any better way to define a constructor?

Community
  • 1
  • 1
Deqing
  • 14,098
  • 15
  • 84
  • 131

3 Answers3

2

arguments.callee is (unfortunately, IMHO) deprecated in ES5 strict mode.

Instead of throwing an error, I recommend that you instantiate the object instead if the caller forgets to use new:

function Foo() {
    if (!(this instanceof Foo)) {
         return new Foo();
    }

    ...
};
Alnitak
  • 334,560
  • 70
  • 407
  • 495
1
if (!(this instanceof arguments.callee))

arguments.callee is deprecated. Just use the proper reference: this instanceof Foo.

If so then what error should I throw?

Just a normal error indicating the reason:

throw new Error("Foo must be called as a constructor");

Btw, you might as well tolerate it and create a new instance nonetheless: return new Foo().

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

How about this:

/*WARNING CALL THIS ONLY AS A CONSTRUCTOR, NOT AS A FUNCTION*/
Zak
  • 24,947
  • 11
  • 38
  • 68
  • 1
    Don't be so fatuous to assume every user would read (and follow) such docs :-) – Bergi Sep 10 '13 at 21:56
  • I'm being somewhat sarcastic, but at the same time, cars don't prevent you from driving without oil in the engine. You are supposed to know to use the car correctly, or read the docs to find out how to do so. – Zak Sep 10 '13 at 22:02
  • JSDoc format: `/** * @constructor */` –  Apr 18 '15 at 00:01