4

I have the following constructor:

function Person(name, age) {
  this.name = name;
  this.age  = age;
}

Now if I say:

var p = new Person("jon", 25);

It will create an instance of Person but what if a user does the following:

var p = Person("jon", 25);

This will lead to name and age being defined on the window object.

My question is, is there a way to prevent the user from calling Person directly without new and thus not allowing window object to be augmented?

Paul Roub
  • 36,322
  • 27
  • 84
  • 93

4 Answers4

3

Here's a way around it using a scope safe constructor:

function Person(name, age) {
  if (this instanceof Person) {
    this.name = name;
    this.age = age;
  } 
  else {
    return new Person(name ,age);
  }
}

Read more: New/Scope Safe Constructors in OO JavaScript

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Ramanlfc
  • 8,283
  • 1
  • 18
  • 24
2

You can explicitly test for the condition:

function Person(name, age) {
  if (!this || this === window)
    return new Person(name, age);
  this.name = name;
  this.age = age;
}

Now, that still doesn't prevent somebody from doing something like

var obj = {};
Person.call(obj, "John", 22);

You can test with instanceof as in another answer, which deals with that problem:

function Person(name, age) {
  if (!(this instanceof Person))
    return new Person(name, age);
  this.name = name;
  this.age = age;
}
Pointy
  • 405,095
  • 59
  • 585
  • 614
1

See Can I construct a JavaScript object without using the new keyword?

This doesn't prevent the function from being called without new, but calling it with or without new will have the same effect.


If you want the function to only be constructable (i.e. "callable" with new), you have to look at ES6 and declare a class:

class Person {
  constructor() {
    // ...
  }
}

Constructor functions that are created from the class syntax must be called with new. Otherwise an error will be thrown.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0
function Person(name ,age){
    if ( ! (this instanceof Person) ) {
        return new Person(name, age);
    }
    this.name = name;
    this.age  = age;
}
ydaniv
  • 1,289
  • 11
  • 18