Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of 'prototype' vs. 'this' in JavaScript?

What's the difference between

var A = function () {     this.x = function () {         //do something     }; }; 

and

var A = function () { }; A.prototype.x = function () {     //do something }; 
like image 458
sw234 Avatar asked Nov 22 '08 04:11

sw234


People also ask

What is the advantage of prototype in JS?

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.

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.

Does prototype improve memory optimization?

'Prototype' helps remove code redundancy which helps boost your app's performance. If you are seeking to optimize resources or memory on your application, you should use prototype .

What is the difference between prototype and object in JavaScript?

Well not exactly. Prototypes are a special type of object and exist as a property on function-objects. When we try to access a key on a function-object, JavaScript will look at its prototype property to see if it's there. If not it will go up the prototype-chain to try to find it.


1 Answers

The examples have very different outcomes.

Before looking at the differences, the following should be noted:

  • A constructor's prototype provides a way to share methods and values among instances via the instance's private [[Prototype]] property.
  • A function's this is set by how the function is called or by the use of bind (not discussed here). Where a function is called on an object (e.g. myObj.method()) then this within the method references the object. Where this is not set by the call or by the use of bind, it defaults to the global object (window in a browser) or in strict mode, remains undefined.
  • JavaScript is an object-oriented language, i.e. most values are objects, including functions. (Strings, numbers, and booleans are not objects.)

So here are the snippets in question:

var A = function () {     this.x = function () {         //do something     }; }; 

In this case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effective window.x. The result is that a reference to the function expression on the right-hand side is assigned to window.x.

In the case of:

var A = function () { }; A.prototype.x = function () {     //do something }; 

something very different occurs. In the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.

In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example in which object's x property is involved in the expression.

Another example is below. It's similar to the first one (and maybe what you meant to ask about):

var A = new function () {     this.x = function () {         //do something     }; }; 

In this example, the new operator has been added before the function expression so that the function is called as a constructor. When called with new, the function's this is set to reference a new Object whose private [[Prototype]] property is set to reference the constructor's public prototype. So in the assignment statement, the x property will be created on this new object. When called as a constructor, a function returns its this object by default, so there is no need for a separate return this; statement.

To check that A has an x property:

console.log(A.x) // function () {                  //   //do something                  // }; 

This is an uncommon use of new since the only way to reference the constructor is via A.constructor. It would be much more common to do:

var A = function () {     this.x = function () {         //do something     }; }; var a = new A(); 

Another way of achieving a similar result is to use an immediately invoked function expression:

var A = (function () {     this.x = function () {         //do something     }; }()); 

In this case, A assigned the return value of calling the function on the right-hand side. Here again, since this is not set in the call, it will reference the global object and this.x is effective window.x. Since the function doesn't return anything, A will have a value of undefined.

These differences between the two approaches also manifest if you're serializing and de-serializing your Javascript objects to/from JSON. Methods defined on an object's prototype are not serialized when you serialize the object, which can be convenient when for example you want to serialize just the data portions of an object, but not it's methods:

var A = function () {      this.objectsOwnProperties = "are serialized"; }; A.prototype.prototypeProperties = "are NOT serialized"; var instance = new A(); console.log(instance.prototypeProperties); // "are NOT serialized" console.log(JSON.stringify(instance));  // {"objectsOwnProperties":"are serialized"}  

Related questions:

  • What does it mean that JavaScript is a prototypal language?
  • What is the scope of a function in JavaScript?
  • How does the "this" keyword work?

Sidenote: There may not be any significant memory savings between the two approaches, however using the prototype to share methods and properties will likely use less memory than each instance having its own copy.

JavaScript isn't a low-level language. It may not be very valuable to think of prototyping or other inheritance patterns as a way to explicitly change the way memory is allocated.

like image 71
29 revs, 12 users 61% Avatar answered Oct 13 '22 08:10

29 revs, 12 users 61%