Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The disadvantages of JavaScript prototype inheritance, what are they?

Tags:

I recently watched Douglas Crockford's JavaScript presentations, where he raves about JavaScript prototype inheritance as if it is the best thing since sliced white bread. Considering Crockford's reputation, it may very well be.

Can someone please tell me what is the downside of JavaScript prototype inheritance? (compared to class inheritance in C# or Java, for example)

like image 501
Vivian River Avatar asked Jul 05 '11 15:07

Vivian River


People also ask

What is prototype inheritance in JavaScript?

The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object. getPrototypeOf and Object.

What is the difference between prototype and inheritance in JavaScript?

Classes. The most important difference between class- and prototype-based inheritance is that a class defines a type which can be instantiated at runtime, whereas a prototype is itself an object instance.

What is prototypal inheritance give example?

In programming, we often want to take something and extend it. For instance, we have a user object with its properties and methods, and want to make admin and guest as slightly modified variants of it.

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.


2 Answers

In my experience, a significant disadvantage is that you can't mimic Java's "private" member variables by encapsulating a variable within a closure, but still have it accessible to methods subsequently added to the prototype.

i.e.:

function MyObject() {     var foo = 1;     this.bar = 2; }  MyObject.prototype.getFoo = function() {     // can't access "foo" here! }  MyObject.prototype.getBar = function() {     return this.bar; // OK! } 

This confuses OO programmers who are taught to make member variables private.

like image 141
Alnitak Avatar answered Oct 21 '22 19:10

Alnitak


Things I miss when sub-classing an existing object in Javascript vs. inheriting from a class in C++:

  1. No standard (built-into-the-language) way of writing it that looks the same no matter which developer wrote it.
  2. Writing your code doesn't naturally produce an interface definition the way the class header file does in C++.
  3. There's no standard way to do protected and private member variables or methods. There are some conventions for some things, but again different developers do it differently.
  4. There's no compiler step to tell you when you've made foolish typing mistakes in your definition.
  5. There's no type-safety when you want it.

Don't get me wrong, there are a zillion advantages to the way javascript prototype inheritance works vs C++, but these are some of the places where I find javascript works less smoothly.

4 and 5 are not strictly related to prototype inheritance, but they come into play when you have a significant sized project with many modules, many classes and lots of files and you wish to refactor some classes. In C++, you can change the classes, change as many callers as you can find and then let the compiler find all the remaining references for you that need fixing. If you've added parameters, changed types, changed method names, moved methods,etc... the compiler will show you were you need to fix things.

In Javascript, there is no easy way to discover all possible pieces of code that need to be changed without literally executing every possible code path to see if you've missed something or made some typo. While this is a general disadvantage of javascript, I've found it particularly comes into play when refactoring existing classes in a significant-sized project. I've come near the end of a release cycle in a significant-sized JS project and decided that I should NOT do any refactoring to fix a problem (even though that was the better solution) because the risk of not finding all possible ramifications of that change was much higher in JS than C++.

So, consequently, I find it's riskier to make some types of OO-related changes in a JS project.

like image 32
jfriend00 Avatar answered Oct 21 '22 21:10

jfriend00