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

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.

Related

Why does a method defined within an object constructor work when creating objects using "new", but not when using "Object.create"? [duplicate]

This question already has answers here:
Understanding the difference between Object.create() and new SomeFunction()
(11 answers)
Closed 1 year ago.
I create a constructor for "car" and then create two cars, one using the "new" keyword, the other using "Object.create"
function car (name) {
this.name=name
}
let car1 = new car("volvo")
let car2 = Object.create(car.prototype)
car2.name = "hyundai"
BTW: is it possible to set attributes immediately with "Object.prototype" like it is done with "new"?
(so I wouldn't have to use the next line 'car2.name = "hyundai"')
If I then set a ".honk()" method to "car.prototype", it works for both "car1" and "car2":
car.prototype.honk= function (){
return `${this.name}'s honk`
}
However, if I define the ".honk()" method within the "car" constructor, then "car1" is able to use it, but "car2" is not! Why?
function car (name) {
this.name=name
this.honk = function(){
return `${this.name}'s honk`;
}
}
is it possible to set attributes immediately with "Object.create" like it is done with "new"?
No, it is not. This is the entire point why we use constructors, to be able to initialise the properties of the new instances without repetitive code. Object.create, on the other hand, only creates an empty object that inherits from the give prototype.
You've just discovered the main difference between the new operator and Object.create. Both leverage prototypal inheritance, but only new makes use of the constructor, while Object.create just creates an object with the first parameter as prototype.

let variables in classes with "this" context [duplicate]

This question already has answers here:
Javascript: Do I need to put this.var for every variable in an object?
(6 answers)
Closed 5 years ago.
So I have a question about this and just having normal variables in classes.
Normally we do something like this:
class Thingy {
constructor(thing) {
this.id = thing
}
printID() {
console.log(this.id)
}
}
let newthingy = new Thingy("ID1")
let newthingy2 = new Thingy("ID2")
newthingy.printID()
newthingy2.printID()
Which works just fine, however something like this will not:
class Thingy {
constructor(thing) {
let id = thing
}
printID() {
console.log(id)
}
}
let newthingy = new Thingy("ID1")
let newthingy2 = new Thingy("ID2")
newthingy.printID()
newthingy2.printID()
So I understand that newthingy will have no idea what id is, so won't it just look up the prototype chain back at the original class prototype? I realize it probably wouldn't get the right id but how come we get a id not defined error, should it attempt to look up the prototype chain first?
I believe it is all about scope. When you say...
let id = thing
... you are actually declaring a variable that is local to the constructor method. When you define ...
this.id = thing
... it is actually modifying a property value of the Thingy instance. And, when printID tries to access "id", it has no context to find "id" in.
This has absolutely nothing to do with the prototype. It's much simpler than you may make it out to be:
"Class methods" are merely functions which act on an object. The way they act on an object is through this. That is all. It's a normal function, which has implicit access to this, which is an object. Since in Javascript the value of this is decided at call time, this is an extremely malleable mechanism:
function foo() {
console.log(this.bar);
}
foo.call({ bar: 'baz' });
let baz = { bar: 'baz' };
baz.foo = foo;
baz.foo();
As you see, you don't even need a class for this to work. A class merely formalises this into a certain pattern:
new Thingy creates a new object and calls the Thingy constructor on it, in the constructor you set this.id = thing, creating the id property on that new object. When you then call newthingy.printID(), you're calling the printID function setting its this context to the object created previously (newthingy), so this.id works.
The id value is transported from constructor to printID as a property on an object. If you just use id (instead of this.id), you're merely trying to access a local variable which doesn't exist.
'constructor' and 'printID' are both functions.Variables defined at them cannot be reached by others.

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

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.

Javascript inheritance constructor [duplicate]

This question already has answers here:
What is the `constructor` property really used for? [duplicate]
(2 answers)
Closed 9 years ago.
While creating inheritance pattern in JS such as follows -
var Fruits = function(){};
var Apples = function(){};
Apples.prototype = new Fruits;
Apples.prototype.constructor = Apples;
Why do we change the constructor of the base class?
In this example apple inherits fruits constructor. The line Apples.prototype = new Fruits means any future Apple created will start as a fruit. The next line sets the constructor of Apple to fruits constructor. You could do the same thing with out the prototype but then it would only affect the one instance
Forget about the words "base class".
In JavaScript, a function which is used as a constructor (invoked with the new keyword) can have a prototype object. The members of the prototype object can be invoked or accessed as though they were members of objects created by that constructor.
Simple example: ( http://jsfiddle.net/G2CUp/ )
var djangoFett = { // note that Django here is an object,
// not a constructor function and not a "class"
shootBlaster: function() {
alert("Blam! Blam!");
}
};
function CloneTrooper() {
return this;
};
CloneTrooper.prototype = djangoFett; // note that the prototype
// is an object, not a "class"
var myCloneTrooper = new CloneTrooper();
myCloneTrooper.shootBlaster();
In this example we have an object djangoFett which is the prototype for objects created using the CloneTrooper constructor function. Of note is that djangoFett - the prototype for CloneTrooper - is an object, not a function or a "class".
Your code snippet is different though - your example has two constructor functions, so let's add another constructor function, to bring my code snippet more in line with yours: ( http://jsfiddle.net/r28QS/ )
function Mandalorian() {
this.shootBlaster = function() {
alert("Blam! Blam!");
}
return this;
};
var djangoFett = new Mandalorian();
function CloneTrooper() {
return this;
};
CloneTrooper.prototype = djangoFett; // note that the prototype
// is an object, not a "class"
var myCloneTrooper = new CloneTrooper();
myCloneTrooper.shootBlaster();
This time djangoFett isn't just an object literal - instead it's created by invoking the Mandalorian function while using the new keyword.
The above code snippet is very similar to the code snippet you provided in your question - I've just added a few more explicit steps along the way. Re-structuring the code to match your own a little more:
Mandalorian = function() {};
CloneTrooper = function() {};
CloneTrooper.prototype = new Mandalorian(); // note that the prototype
// is an object, not a "class"
So if I then change the CloneTooper.prototype.constructor value...
// this is the same as `djangoFett.constructor = CloneTrooper`
// it does not affect the `Mandalorian` constructor function
// in any way whatsoever
CloneTooper.prototype.constructor = CloneTrooper;
...it should now be clear that this doesn't affect the the Mandalorian constructor function (the "base class") in any way. It affects only one object, which happens to be an instance of Mandalorian.
So, why do we change the constructor of the base class? The answer is we don't. We change the constructor of the prototype object. Now, why we do that is another can of worms entirely - and there are already questions on SO which address it.

Javascript Object : Literal Vs Constructor [duplicate]

This question already has answers here:
Literal notation VS. constructor to create objects in JavaScript [duplicate]
(2 answers)
Closed 9 years ago.
For creating Javascript object, we can use Literal or Constructor way;
In Constructor way, we say;
function myObj(){
this.myProp1 = "abc";
this.myProp2 = "xyz";
}
In literal way, we say;
var myObj = {
myProp1:"abc",
myProp2:"xyz",
}
My question is when declaring properties, why there is a difference like why do we use "this.myProp1" in case of Constructor way and not use "this" in Literal way ?
The key difference between the two is in how they are intended to be used. A constructor, as its name suggests, is designed to create and set up multiple instances of an object. An object literal on the other hand is one-off, like string and number literals, and used more often as configuration objects or global singletons (e.g. for namespacing).
There are a few subtleties about the first example to note:
When the code is executed, an anonymous function is created and assigned to myObj, but nothing else happens. methodOne and methodTwo don't exist until myObj is explicitly called.
Depending on how myObj is called, the methods methodOne and methodTwo will end up in different places:
myObj():
Since no context is supplied, the this defaults to window and the methods will become global.
var app1 = new myObj():
Due to the new keyword, a new object is created and becomes the default context. this refers to the new object, and the methods will get assigned to the new object, which subsequently gets assigned to app1. However, myObj.methodOne remains undefined.
myObj.call(yourApp):
This calls my myObj but sets the context to be another object, yourApp. The methods will get assigned to yourApp, overriding any properties of yourApp with the same names. This is a really flexible method that allows multiple inheritance or mixins in Javascript.
Constructors also allow another level of flexibility since functions provide closures, while object literals do not. If for example methodOne and methodTwo rely on a common variable password that is private to the object (cannot be accessed outside the constructor), this can be achieved very simply by doing:
var myObj = function(){
var variableOne = "ABCD1234";
this.methodOne = function(){
// Do something with variableOne
console.log(variableOne);
};
this.methodTwo = function(){
// Do something else with variableOne
};
};
myObj();
alert(variableOne); // undefined
alert(myObj.variableOne); // undefined
If you wanted to make variableOne exposed (public) you'd do:
var myObj = function(){
this.variableOne = "ABCD1234";
this.methodOne = function(){
// Do something with variableOne
console.log(this.variableOne);
};
this.methodTwo = function(){
// Do something else with variableOne
};
};
myObj();
alert(variableOne); // undefined
alert(myObj.variableOne); // ABCD1234
When defining something literally, the object is being built directly in the code. It doesn't exist yet until it is complete. At that point, this would have no meaning (not that there is any need for it either).
To understand this in the object creation function, first realize that this is special in JavaScript. Whenever you call a function, you can pass anything you want to be this. In general, things like event handlers will pass the event-causing DOM object to be passed as this. In your code, you do this as: MyFunction.call(whatever_needs_to_be_this[, param0, param1]);. When you use the new operator, such as var mything = new SomeThing();, JavaScript is essentially doing something like:
var mything = {};
SomeThing.call(mything);
this in this case is going to be mything in your function.

Categories

Resources