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

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.

Related

Javascript constructor return values [duplicate]

This question already has answers here:
What values can a constructor return to avoid returning this?
(6 answers)
Closed 7 years ago.
Consider the following code:
function Foo() {
return "something";
}
var foo = new Foo();
According to the experts in JavaScript, they say that return "nothing" or just "this" from a constructor. Whats the reason for this?
I am aware that when used "new", the "this" would be set to the prototype object of the constructor but not able to understand this point alone.
That particular code will throw a ReferenceError because something is not declared.
You should either return this or have no return statement at all in a constructor function because otherwise you will have constructed a new instance of the class (the value of this, and the default return value) and then thrown it away.
I am aware that when used "new", the "this" would be set to the prototype object of the constructor
Incorrect. It will be set to an instance of the constructor.
When the code new Foo(...) is executed, the following things happen:
1- A new object is created, inheriting from Foo.prototype.
2- The constructor function Foo is called with the specified arguments and this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
3- The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
function Car() {}
car1 = new Car();
console.log(car1.color); // undefined
Car.prototype.color = null;
console.log(car1.color); // null
car1.color = "black";
console.log(car1.color); // black
You can find a complete description Here

JavaScript prototype vs. this in practice

I've read many questions with valid and understandable answers here in Stack Overflow and other sites over the web, and I think I understand everything I need for using JavaScript to make object-oriented apps, save one thing: What is the real, practical purpose of using a class' prototype over this?
I've read that any method, even one set as a this member, will be called from the constructor (class) function, and not re-created for each instance.
I've seen many examples of using prototype for setting methods, implying that it would save memory by using the original class-function's method on the instance, and not a brand new attribute.
So, along with remarking which of the two options above is true, I'd like to know: is a prototype method accessing the constructor's this ("public") variables or the instance's (which may have been set as different from the constructor's)?
Edit - is using this.prototype.method = function() inside the constructor's scope wrong? All examples I've seen set a prototype method after the function has been created.
I'll try to answer your question regarding the relationship between the prototype method and this by example.
From the moz docs:
If the method is on an object's prototype chain, this refers to the
object the method was called on, as if the method was on the object.
Example:
// Our constructor function
function Example() {
this.publicGreet = "Hello World";
};
// Here the function is set as a property of the constructors prototype
Example.prototype.greet = function() {
alert(this.publicGreet);
};
// This creates a new object and invokes the constructor function
// Sets publicGreet as a property of that object and assigns it the value "Hello World"
var exampleInstance = new Example();
// Looks up the prototype chain and invokes it as a method of exampleInstance
// Remember our definition of `this` for methods on the prototype chain?
// Hence, `this` refers to exampleInstance, therefore `this.publicGreet` is "Hello World"
exampleInstance.greet();
This test should explain the performance problem: http://jsperf.com/prototype-vs-instance-functions/6
But yes, prototype saves memory because one callback is defined and instances simply points to this callback. There's no need to declare bunch of copies of the same callback.
Access issue: "this" declared within function inside this.prototype refers to "this" of instance: http://jsfiddle.net/pHtjK/
var b = Function;
b.prototype.a = function(){alert(this.b);};
var xyz = new b();
b.b = 'what';
b.a();

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.

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.

Categories

Resources