0

I have been trying to create my own Javascript function, and then add methods using Prototype

So I create a function:

function createObject(){
    this.value = 0;
}

And then I create the Prototype Method:

createObject.prototype.once = function(){
       return this.value+1
};

Then I create the instance of the object:

var x = createObject();

Then, when I try to run x.once() I get:

Uncaught TypeError: Cannot read property 'once' of undefined
at <anonymous>:1:2

And I have no idea why.

4
  • 1
    var x = new createObject(); to instantiate an object instead of just calling the function Commented Feb 26, 2017 at 4:32
  • If you intend to use a function as a constructor, it's standard practice to capitalize the function's name, so that you will remember to use the new keyword. There's some more good practices associated with the pattern at this question. Commented Feb 26, 2017 at 4:37
  • you should think of a better name for the object, because the name createObject actually makes the function sound like a function that creates an object - which you would expect to call without the new keyword - this doesn't address your problem, but it's probably something to keep in mind Commented Feb 26, 2017 at 4:43
  • Constructors are PascalCase (not camelCase) by convention; help people remember to use new (ignoring error-checking) by following it! Commented Feb 26, 2017 at 6:32

3 Answers 3

2

You could find this error by placing a breakpoint on the this.value = 0; line, and examining this; you will find that it is not what you expect.

The most robust solution is to rewrite your constructor to make sure it's being called with new, using new.target:

function CreateObject() {
  if (!new.target) throw new TypeError('CreateObject() must be called with new');

  this.value = 0;
}

const object = CreateObject();

Linters can help you find this type of error as well. For example, eslint has the new-cap option. It will complain if you call a non-capitalized function with new, or call a capitalized function without new. To take advantage of this, you'll have to follow the convention of capitalizing constructors, as in CreateObject.

TypeScript (or ES6 as well) would report an error if you used class and tried to instantiate it without new:

class CreateObject {
  value = 0;

  once() { return this.value = 0; }
}

var x = CreateObject();

Value of type 'typeof CreateObject' is not callable. Did you mean to include 'new'?

Sign up to request clarification or add additional context in comments.

1 Comment

ES6 classes will throw if you try to construct them without new, too (re: TypeScript).
1

You'll need to use var x = new createObject().

In short, the new keyword is what sets up the prototype chain and this bindings within the object that your function returns to x.

I'd recommend that you take a look at the MDN page for more details.

Comments

1

When you make instance of class, you have to use new keyword, before class name.

var x = new createObject();

The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

For more information MDN

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.