Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance in JavaScript causes Uncaught TypeError

May be I'm missing something here. Please bear with me as I'm new to OOP in javascript. But I need to find a solution to my problem.

I have this code.

var parent = function() {}
parent.prototype.someFunc = function() {
  return "a string";
}

Now I'm trying to inherit the parent using the code like below,

var child = function() {
    parent.call(this);
}
child.prototype = new parent();

When I do like this it works.

var obj = new child();
obj.someFunc();

But I would like to have someFunc() inside child like below,

var child = function() {
  parent.call(this);
  var someVal = this.someFunc(); // method from parent.
}
child.prototype = new parent();

Doing that will throw me an error as Uncaught TypeError: Object [object global] has no method 'getLightBox' But as I know this refers to the current object and I'm just confused here about how to solve this problem. Please correct me if I'm wrong. Or if there is a better way then I would like to know about it.

like image 450
Vinay Avatar asked Jun 08 '13 07:06

Vinay


People also ask

Is inheritance possible in JavaScript If yes what type is possible?

When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

What is uncaught TypeError in JavaScript?

The TypeError object represents an error when an operation could not be performed, typically (but not exclusively) when a value is not of the expected type. A TypeError may be thrown when: an operand or argument passed to a function is incompatible with the type expected by that operator or function; or.

What is true about inheritance in JavaScript?

Inheritance enables you to define a class that takes all the functionality from a parent class and allows you to add more. Using class inheritance, a class can inherit all the methods and properties of another class. Inheritance is a useful feature that allows code reusability.

How is inheritance supported in JavaScript?

In JavaScript, inheritance is supported by using prototype object. Some people call it "Prototypal Inheriatance" and some people call it "Behaviour Delegation". Let's see how we can achieve inheritance like functionality in JavaScript using prototype object.


2 Answers

You are forgetting to use new. I.E. you have code that does child(...) instead of new child(...)

Some tips:

  • Run code in strict mode so forgetting new will cause instant error
  • Always capitalize constructor names I.E. Parent not parent so forgetting new will stick out like a sore thumb. In fact JSHint can statically find where you forgot to use new if you follow this practice.
  • Always give sensible noun names to your constructors as it doesn't make sense to call a noun as a function so forgetting new will again stick out like a sore thumb.

Also

  • Don't use new for linking prototype, just do Child.prototype = Object.create(Parent.prototype)
like image 148
Esailija Avatar answered Sep 28 '22 03:09

Esailija


The preferred solution

Javascript OOP is specific in context handling: if your parent works with context (this), just call the parent in the child with its context (note the new function(), which sets the context from global to the newly created object):

var parent = function() { // constructor, should be called with new
  this.someFunc = function() { return "a string"; }
}

var child = new function() { // object, was already called with new
  parent.call(this); // set parent context to child's, don't create new one
  var someVal = this.someFunc(); // method from parent.
}

console.log(child.someFunc()); // a string

Alternative, non-standard solution, close to your approach

If you set the parent prototype instead of working with its context, you may use non-standard __proto__ member, which has access to its prototype:

var parent = function() {} // constructor to create empty object
parent.prototype.someFunc = function() { // someFunc is in parent prototype
  return "a string";
}

var child = new function() {
  this.__proto__ = new parent(); // set prototype to parent with its own context
  var someVal = this.someFunc(); // method from parent.
}

console.log(child.someFunc()); // a string

Compared to your working example

You may also set the prototype to the constructor, not to the object using standard prototype. Note the object is created AFTER the prototype is set, see the position of new calls and compare it to the Felix Kling's comment to the question:

var parent = function() {}
parent.prototype.someFunc = function() {
  return "a string";
}

var child = function() { // no new here
  var someVal = this.someFunc();
}
child.prototype = new parent();

console.log((new child).someFunc()); // new moved here

The error explained

Function with new creates a constructor from function in javascript. It means that the context becomes the function itself. Without the new (and with default non-strict behavior), the context is global context, hence your error

Object [object global] has no method 'someFunc'
like image 42
Jan Turoň Avatar answered Sep 28 '22 03:09

Jan Turoň