What is the difference between extending an object using prototype or inline? [duplicate] - javascript

This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 9 years ago.
What's the difference? Is there any?
var Likes = function (el) {
this.el = $(el);
return this;
};
Likes.prototype.add = function (name) {
this.el.find('.no-results').remove();
$('<li>', { text: name }).appendTo(this.el);
};
and:
var Likes = function (el) {
this.el = $(el);
this.add = function (name) {
this.el.find('.no-results').remove();
$('<li>', { text: name }).appendTo(this.el);
};
return this;
};

The difference is in how the object gets created. When you define functions on an object's prototype, it's defined ONCE for every further instance of that object.
If you declare functions on an instance level, they get redefined each time you declare the function.
It actually has a performance impact http://jsperf.com/prototype-vs-instance-functions
It's generally considered a best practice to use the prototype for functions that will be re-used on multiple instances of a constructor. For example if you are using the new operator to create instances of a constructor..
var Likes = function (el) {
this.el = $(el);
return this;
};
Likes.prototype.add = function (name) {
this.el.find('.no-results').remove();
$('<li>', { text: name }).appendTo(this.el);
};
var oneLike = new Likes();
var twoLike = new Likes();
var threeLike = new Likes();
Since the add is defined on the object's prototype, it gets define just one time rather than each time the Likes is instantiated.

Yes, there is a difference.
If you uses prototype object, then all created objects of 'Likes' will have same reference to prototype object.
But if you use second method (this.add), it will add function to every created object.
First one is more prefer method than second one.

Example 2 is the better practice because it lends itself to implementing inheritance rather than making wasteful copies of object properties.
In a small application with no inheritance, there is probably not much of a practical difference between the two examples. But imagine that you had 10000 instances of the Likes constructor in a more complex application using inheritance. With the second example, each one of them will receive a copy of the add function locally.
This could theoretically cause memory bottlenecks in a larger application. Also, if you want to change the add method in the future, you would need to do so on each local object.

Related

What is the best practice when it comes to making constructor functions in JavaScript? [duplicate]

This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 7 years ago.
So I've been trying to figure out prototypal inheritance in Javascript and I'm still confused on one point. Let's say I want to make a constructor function for a person with a few functions of it's own.
function Person(name) {
this.name = name;
this.sayName = function() {
console.log("My name is " + name);
}
}
var john = new Person("John");
john.sayName();
So in this case I've created an object and called a function, however this doesn't seem to be the efficient way to do it. Another example I've seen this is this:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log("My name is " + name);
}
var john = new Person("John");
john.sayName();
Now I've read that the second object is more efficient because it's not storing the sayName function within itself, instead it's going up the prototype chain until it finds it within Persons prototype object.
What I'm unsure about is which I should use for complicated constructor functions. The first snippet, in my opinion, is much much easier to read than the second because there is a clear hierarchical structure to it, but the second snippet is supposedly more efficient.
In a real world scenario, which style of constructor function would I be more likely to use?
Edit: I have a follow up question. Is there any way to make the second snippet more readable?
Generally if you are going to have a class from which several instances will be created, you should add the methods to the prototype object. The main reason I believe is that all the instances of a class would reference the prototype object, and won't copy it. So if the prototype object changes, it would be reflected in the prototype object referenced by all the instances.
This is better than the first option where each method is created (copied) on each instance. And so a lot of instances would also mean a lot of those methods will be created, occupying memory. But in the second option, they all use the single method created on the prototype object.
if you use the first one , you'll be creating a new function object for sayName each time the constructor is called, while in the second way you avoid that overhead.
if you use a reference type in your constructor it will be shared,
for ex :
function Person(name){
this.name = name;
this.hobbies = [..some hobbies];
}
now hobbies will be shared by every object you create with this constructor , so it's best to put shared properties on prototype and only use unique one's in the constructor
In the first approach will create method function for every single instance. In the second one, all instances share the method defined in the prototype. So the second approach is better because of saving memory.
However, ECMAScript 6 is officially released several months ago, so why not try class:
class Person {
constructor(name) {
this.name = name;
}
sayName() {
console.log("My name is " + this.name);
}
}
var john = new Person("John");
john.sayName(); // "My name is John"
The feature is not well supported yet, if you want backward compatibility in browsers, use Babel.
Another syntax introduced in ECMAScript 5 for create instances of Classes is:
Object.create(prototype [, propertiesObject ] )
Example:
var MyClass = function (param) {
this.field1 = param;
}
MyClass.prototype.changeField = function(param){
this.field1 = param;
}
var instance = Object.create(MyClass.prototype);
If you are interested in learn advanced things about javascript I suggest a book called "Mastering Javascript design patterns".

Function as a class - create getters and setters for private properties

The way I figured, when creating a new function (that represents a class), it is considered a good practice to define additional functions with the help of the prototype. If functions are declared through this within an existing function, they get created for each instance, which we don't necessarily want.
So, my question is - if I want to have a property that is completely private and can be access only through getters and setters, is it even possible to achieve this by using the prototype?
Here's an example:
function Item() {
var title = '';
this.setTitle = function(_title) {
title = _title;
};
this.getTitle = function() {
return title;
};
}
var car = new Item();
car.setTitle('car');
console.log(car.getTitle()); //car
console.log(car.title); // undefined
/*
Alternative
*/
function _Item() {
this.title = '';
}
_Item.prototype.setTitle = function(_title){
this.title = _title;
};
_Item.prototype.getTitle = function() {
return this.title;
};
var _car = new _Item();
_car.setTitle('car 2');
console.log(_car.getTitle()); // car
console.log(_car.title); // car
as can be seen from the example above, in the case of Item, I declared getters and setters within a function - not a good practice. But in this way, I managed to keep the title property private. However, in case of _Item, I'm using the prototype approach, which is preferred, but my title property is not private at all.
So, what's the best approach at creating private properties of "classes" in JavaScript?
No, if you want a private property, which by definition is a variable local to the constructor, then obviously methods which access it must also be defined within the constructor.
Many people worry about the efficiency implications of defining a method once on a prototype, versus defining it once on every instance. This might have been a valid concern ten years ago, or today in applications that are creating thousands or millions of objects. Otherwise, realistically it's not something you need to worry about.

Is there a performance penalty associated with methods created in the constructor versus methods created on the prototype?

I can declare methods of an object in two ways:
The first way uses the self=this idiom.
function SelfIdiomExample(name){
var self = this;
self.sayHello = function (name){
alert("Hello, "+name);
}
}
Which is useful when you need a reference to the object in a method (for example if the method will be passed as a callback). The other way is to do it by modifying the prototype:
function PrototypeModExample(){
//pass
}
PrototypeModExample.prototype.sayHello = function(name){
alert("Hello, "+name);
}
Both have the same result:
var sieg = new SelfIdiomExample();
var pmeg = new PrototypeModExample();
sieg.sayHello("Barnaby");
pmeg.sayHello("Josephine");
While I understand the use case for the self=this idiom, I am wondering:
Is there a performance penalty to using the methods created in the constructor versus methods created on the prototype?
Well this here:
var self = this;
Is not something has performance implications at all. It's wicked fast as it's simply accessing a local variable. Even from nested funcitons, this is a very fast operation in JavaScript.
However, methods created in the constructor versus methods created on the prototype has a huge performance difference.
In this example:
var PrototypeModExample = function(){
this.name = "Joe";
};
PrototypeModExample.prototype.sayHello = function(){
alert("Hello, " + this.name);
};
var a = new PrototypeModExample();
var b = new PrototypeModExample();
console.log(a.sayHello === b.sayHello); // true
Every instance of the constructor gets access to the same function objects. Which can be proved by using the === operator to compare the function objects on two instances. It will only return true when they are the same object. So globally we now have 2 instances, but they share one function object for the implementation of the sayHello method. This means that function is already setup and created when you want to make a new instance.
In other words, for all instance obj.sayHello points to the same function object, which was created before any instances existed at all.
But this on the the other hand:
function SelfIdiomExample(name){
var self = this;
this.name = "Joe";
this.sayHello = function(){
alert("Hello, " + self.name);
}
}
var a = new SelfIdiomExample();
var b = new SelfIdiomExample();
console.log(a.sayHello === b.sayHello); // false
Works differently. Now we see that the === comparison is false. That's because a new function object was created for each instance. Creating this function takes time (it needs to be parsed) and memory (this unique version of that function needs to be stored). So when creating lots of these instances, this method will be both slower and consume more memory.
In other words, for all instance obj.sayHello points to a unique function object which was created when the instance itself was created.
So usually, the prototype method is preferred. Especially in cases where a large number of instance might exist, since each instance can share function objects for it's methods.
As always, you have to test in order to answer questions like this: http://jsperf.com/this-vs-self/2.
When you test, there appears to be not much difference (less than few percent with a slight advantage to self in some cases). One advantage to self is that it can be minimized better by changing it to a one character variable name and that is apparently why some frameworks use it.
In your example, I would say that the use of self is extranous and not neccessary. Normally folks only use self when a closure is used and the value of this in some callback is no longer what you want it to be like this:
counter.prototype.incrementWithDelay(delay) {
var self = this;
setTimeout(function() {
self.counter++;
}, delay);
}
But, if you just have a normal method, there is little reason to use self.
counter.prototype.set(val) {
this.counter = val;
}

What is the difference between myObject.someFunc = function(){...}; or myObject.prototype.someFunc = function(){...} in javascript? [duplicate]

This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Prototyped and a non-prototyped method? [duplicate]
(1 answer)
Closed 8 years ago.
Suppose I create an object in javascript.
var myObject = {};
What is the difference between...
myObject.someFunc = function(){...};
and
myObject.prototype.someFunc = function(){...}
in javascript?
I am having trouble understanding the difference or if there is a difference and how and when to use either of these syntaxes.
It seems when I code something like this that there really is no difference.
I am looking for both a client side (browser) and server side (like node.js) answers.
I want to code properly and accurately and this is really bothering me.
In this case:
var myObject = {};
myObject.someFunc = function(){...};
All you're doing is creating a plain object, which happens to have a property which is a reference to a function. This is often done just for name spacing, i.e. to group a whole load of functions in one place under a common object.
Note however that var myObject = {} doesn't actually have a prototype so your second example is impossible.
For an object to have a prototype it must be the result of a constructor function, i.e.
function MyObject() {
...
}
MyObject.prototype.someFunc = function() { }
var myObject = new MyObject();
// myObject.someFunc can now be used
The prototype is a property of the constructor function - not of any instance of that class.
If you put the function on the prototype only one instance of the function object exists and will be shared by all instances of the class. This is more memory efficient that having a copy on each instance.
All of this applies regardless of whether the code is in a browser or on a server - it's still the same language.
Essentially this represents a static method (or a method attached to only that object (myObject in this case):
myObject.someFunc = function () {...};
This represents a method attached to the prototype of the object (an instance method):
myObject.prototype.someFunc = function () {...};
myObject.someFunc = function(){...} is a one time instance of that function, who's return value is being assigned to the someFunc property of myObject.
myObject.prototype.someFunc = function(){} is actually creating a method that can be called anywhere on myObject and will change the same instances of values each time.
myObject.prototype.someFunc = function(num){
this.num_to_be_stored = num;
}
will change the value of num_to_be_stored not someFunc which is what is happening in the first instance.
edit: sorry early morning was not clear on what I was trying to say.

What’s the purpose of prototype? [duplicate]

This question already has answers here:
Use of 'prototype' vs. 'this' in JavaScript?
(15 answers)
Closed 2 years ago.
Possible Duplicate:
Use of 'prototype' vs. 'this' in JavaScript?
OK, So I am somewhat new to the idea of OOP in JS.
What is the difference between these two snippets of code written below:
function animal(){
this.name = 'rover';
this.set_name = function(name){
this.name = name;
}
}
function animal(){
this.name = 'rover';
}
animal.prototype.set_name = function(name){
this.name = name;
}
They both do the same thing, so what’s the difference?
Using the prototype makes faster object creation since properties/methods on the prototype don't have to be re-created each time a new object is created.
When you do this:
function animal() {
this.name = 'rover'
this.set_name = function (name) {
this.name = name
}
}
The set_name method is created every time you create an animal. But when you do this
animal.prototype.set_name = function (name) {
this.name = name
}
The method does not have to be re-created each time; it exists in one place in the prototype. So when you call someAnimal.set_name("Ubu"); the this context will be set to someAnimal and (the one and only) set_name method will be called.
There is one advantage to using the first syntax though: methods created in this manner will have access to private data:
function animal() {
var privateData = 'foo'
this.name = 'rover'
this.set_name = function (name) {
this.name = name
alert(privateData) //will alert 'foo'
}
}
Douglas Crockford calls methods created like this "privileged" for that reason: they have access to both public and private data.
The difference appears when you create new object from these function
var animal1 = new animal();
All objects created by the first function will have different name and set_name properties. However, all objects created by the second function will share the set_name property.
In the first example, each separate animal has an own property for the set_name function, while in the second example they share the same function via their prototype.
The advantage of the first version is that the methods can access local (private) variables declared inside the constructor.
The advantage of the second method is that it needs less memory (since you only store the method once instead of a million times) and is more performatic in current JS engines.
Using the second method you can also modify or add methods to a class in a way that also affects instances that were already created.

Categories

Resources