Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript when to use prototypes

I'd like to understand when it is appropriate to use prototype methods in js. Should they always be used? Or are there cases where using them is not preferred and/or incurs a performance penalty?

In searching around this site on common methods for namespacing in js, it seems that most use a non-prototype based implementation: simply using an object or a function object to encapsulate a namespace.

Coming from a class-based language, it's hard not to try and draw parallels and think that prototypes are like "classes" and the namespace implementations I mentioned are like static methods.

like image 531
opl Avatar asked Jan 19 '11 15:01

opl


People also ask

When should I use prototype JavaScript?

You should use prototypes if you wish to declare a "non-static" method of the object. var myObject = function () { }; myObject. prototype. getA = function (){ alert("A"); }; myObject.

When should you use prototypes?

Prototypes allow you to easily define methods to all instances of a particular object. The beauty is that the method is applied to the prototype, so it is only stored in the memory once, but every instance of the object has access to it. Let's use the Pet object that we created in the previous post.

Should I use prototype or class JavaScript?

To answer your question simply, there is no real difference. Straight from the MDN web docs definition: JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript's existing prototype-based inheritance.

What does prototype do in JavaScript?

The answer is Prototype. The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property (aka attribute) is not visible. Every function includes prototype object by default.


2 Answers

Prototypes are an optimisation.

A great example of using them well is the jQuery library. Every time you obtain a jQuery object by using $('.someClass'), that object has dozens of "methods". The library could achieve that by returning an object:

return {    show: function() { ... },    hide: function() { ... },    css: function() { ... },    animate: function() { ... },    // etc... }; 

But that would mean that every jQuery object in memory would have dozens of named slots containing the same methods, over and over.

Instead, those methods are defined on a prototype and all jQuery objects "inherit" that prototype so as to gain all those methods at very little runtime cost.

One vitally important part of how jQuery gets it right is that this is hidden from the programmer. It's treated purely an optimisation, not as something that you have to worry about when using the library.

The problem with JavaScript is that naked constructor functions require the caller to remember to prefix them with new or otherwise they typically don't work. There is no good reason for this. jQuery gets it right by hiding that nonsense behind an ordinary function, $, so you don't have to care how the objects are implemented.

So that you can conveniently create an object with a specified prototype, ECMAScript 5 includes a standard function Object.create. A greatly simplified version of it would look like this:

Object.create = function(prototype) {     var Type = function () {};     Type.prototype = prototype;     return new Type(); }; 

It just takes care of the pain of writing a constructor function and then calling it with new.

When would you avoid prototypes?

A useful comparison is with popular OO languages such as Java and C#. These support two kinds of inheritance:

  • interface inheritance, where you implement an interface such that the class provides its own unique implementation for every member of the interface.
  • implementation inheritance, where you extend a class that provides default implementations of some methods.

In JavaScript, prototypical inheritance is a kind of implementation inheritance. So in those situations where (in C# or Java) you would have derived from a base class to gain default behaviour, which you then make small modifications to via overrides, then in JavaScript, prototypical inheritance makes sense.

However, if you're in a situation where you would have used interfaces in C# or Java, then you don't need any particular language feature in JavaScript. There is no need to explicitly declare something that represents the interface, and no need to mark objects as "implementing" that interface:

var duck = {     quack: function() { ... } };  duck.quack(); // we're satisfied it's a duck! 

In other words, if each "type" of object has its own definitions of the "methods", then there is no value in inheriting from a prototype. After that, it depends on how many instances you allocate of each type. But in many modular designs, there is only one instance of a given type.

And in fact, it has been suggested by many people that implementation inheritance is evil. That is, if there are some common operations for a type, then maybe it's clearer if they are not put into a base/super class, but are instead just exposed as ordinary functions in some module, to which you pass the object(s) you want them to operate on.

like image 97
Daniel Earwicker Avatar answered Sep 22 '22 18:09

Daniel Earwicker


You should use prototypes if you wish to declare a "non-static" method of the object.

var myObject = function () {  };  myObject.prototype.getA = function (){   alert("A"); };  myObject.getB = function (){   alert("B"); };  myObject.getB();  // This works fine  myObject.getA();  // Error!  var myPrototypeCopy = new myObject(); myPrototypeCopy.getA();  // This works, too. 
like image 40
KeatsKelleher Avatar answered Sep 19 '22 18:09

KeatsKelleher