At what point is the prototype Object born in JavaScript? - javascript

Let's say I have a constructor function:
function Cat()
{
this.tail = "long";
this.colour = "black";
}
console.log(Cat.prototype);
// returns an empty [object Object] with no properties (checked with `for...in` loop).
So it seems at this point Cat.prototype doesn't havetail and colour.
var Charlie = new Cat();
console.log(Charlie.tail);
So how does Charlie inherit the properties of Cat if they are not defined in its prototype. I was under the assumption that the whole point of the prototype object is to mirror or store the properties of the constructor that will be inherited by all instances of cat- is this wrong?
At what point does the prototype Object get filled up with these properties? Or does this happen only when I explicitly set Cat.prototype.eyes = brown as an example?
Moreover, what is the correct approach for querying the properties of an Object's prototype? Is it a for...in loop? I guess it can't be Object.getOwnPropertyNames(Cat.prototype) because that would not return inherited properties.

You are defining the tail and colour properties directly on the instance. Those properties are not defined on the prototype object.
Btw, every function has a prototype property and it is created at the time when the function itself is created.

prototype is completely seperate from this.
All the things in this will not get inherited, the things in prototype will.
By default you inherit from Object.prototype (which is empty)
function Cat()
{
this.tail = "long";
this.colour = "black";
}
Cat.prototype.getColour = function () {
return this.colour;
}
WhiteCat.prototype = Cat.prototype;
WhiteCat.prototype.constructor = WhiteCat;
function WhiteCat(name){
Cat.call(this);
this.colour = "white";
}
var c = new Cat();
console.log(c.getColour()); // "black"
var w = new WhiteCat();
console.log(w.getColour()); // "white"

Prototypes in Javascript are a little different than what you are describing. In this case Charlie does have a tail because Charie IS A Cat that is, he is an instance of Cat the Cat class. In your Cat function you add the tail property to all cats with the this.tail = line. This happens entirely because you called the function Cat with the new keyword. When you do that, javascript creates a new object and then makes this point to that object in the context of the function.
Now prototypes work differently, they are best thought of as a chain that will be followed if a you go looking for a property or function that is not present in an object. For example, if try to go:
Charlie.tickle_wiskers();
Javascript will go looking for a function called tickle_wiskers in the charlie object. If it does not find that function it will look in Charlies prototype (which by default is Object.prototype if you don't set it explicitly). Finally I could give all Cats that function by going like this:
Cat.prototype.tickle_wiskers = function() {
alert('meow');
}

The prototype will never get the properties that you put in the object. The object has the members of the prototype, but the prototype doesn't have the members of the object.
The object doesn't inherit anything from the prototype, the members in the prototype still only exists in the prototype, they are only accessible from the object. If you remove something from the protype after an object is created, that member is no longer accessible from the object either.
A function has a prototype property, and when you use the new keyword to call the function as a constructor, the object that is created gets the prototype from the function.
If you add something to the prototype of a function, it will also be accessible by objects that were created using the function, even if you created them before adding it to the prototype:
function Cat() {}
var c = new Cat();
Cat.prototype.test = function() {
alert('test');
};
c.test(); // alerts 'test'

Moreover, what is the correct approach for querying the properties of an Object's prototype?
var myProto = Object.getPrototypeOf(someObject);
var names = Object.getOwnPropertyNames(myProto);
names.forEach(function (name) {
value = myProto[name];
...
});
Or does this happen only when I explicitly set Cat.prototype.eyes = brown as an example?
Yes, properties on the [[Prototype]] of an object are only set when you set them manually.
But since every "instance" of a prototype has a live pointer to the prototype object, these changes will reflect after the object has been created.
store the properties of the constructor that will be inherited by all instances of cat- is this wrong?
We don't store properties of objects on the prototype. We store properties (mainly methods) that we want to share among all instances of a prototype/constructor.

Related

Why is prototype of my object undefined?

I created a Car object like this.
var Car = Object()
Then I added some properties to it like
Car.price = 5000;
Car.color = "red";
Then I created an instance of it like
var car1 = Object.create(Car);
What I don't understand is, when I call car1.prototype or Car.prototype, I get undefined.
According to what I've read, every Object is a prototype of something.
Can someone explain why it's "undefined"?
every Object is a prototype of something
No. Every object has a prototype (except the root object). However, only functions have a prototype property.
The value of that property will become the prototype of the objects that are created by calling the function as constructor function (e.g. var obj1 = new Constr();).
What I don't understand is, when I call car1.prototype or Car.prototype, I get undefined.
As just explained, only functions have a prototype property. car1 and Car are objects and therefore don't have such a property.
To get the prototype of an arbitrary object, you can use Object.getPrototypeOf:
var car1Prototype = Object.getPrototypeOf(car1);
Then I created an instance of it like var car1 = Object.create(Car);
You didn't create an instance of Car. If you created a new object and explicitly set its prototype to Car. Alternatively you could have defined Car as constructor function:
function Car(price, color) {
this.price = price;
this.color = color;
}
var car1 = new Car(5000, 'red');
Now that Car is a function, Car.prototype would yield the prototype of car1, i.e.
Car.prototype === Object.getPrototypeOf(car1);
See also Introduction to Object-Oriented JavaScript
Functions have prototypes. Object instances, like car1, don't.
It's correct to say that every object is a copy of some prototype. By default, objects are a copy of the prototype of the Object "function". However, object instances don't have a prototype themselves.
Think of a prototype as a "model" for a new Object. In Object Oriented languages, a class or a struct act like a strict model for new instances. That is, every instance of the Car class necessarily have motor, for instance. Likewise, in JavaScript, function prototypes act like the "model" for new instances of that function, but they are not strict. Once you create an instance from that model, you can add and remove members, because the language is dynamic.
EDIT
As Pointy clarified, it seems that object instances are not a copy of the "model" function prototype property. It seems that the prototype is copied to an internal object that is looked up when you try to access a property of the instantiated object.
Example:
var car1 = new Car();
// car1 now is not a copy of Car.prototype, but it has an internal object that is.
car1.motor = new V8Motor();
// even though motor is not a property of car1, this will work because JavaScript will find this property in the car1 prototype as it's not a member of the instance itself

why instances doesn't inherit property added to constructor function without prototype keyword

in this example a property called 't' is added to speak function.Speak.t=5;when i call speak() it prints the value 5 via another function called show.But when i create new instance of Speak it doesn't inherit the property t.Why is that so??i mean if it is a property of Speak constructor all its instances should inherit it??
<html>
<body>
<script>
function Speak(){
show(Speak.t);
}
Speak.t=5;
function show(v){
console.log('value is : '+v);
}
Speak();
var s1=new Speak();
console.log(s1.t);
</script>
</body>
</html>
"i mean if it is a property of Speak constructor all its instances should inherit it?"
No. Its instances inherit from the constructor's prototype, not the constructor itself. JavaScript is prototype-based, not "Constructor-based". If you are familiar with other OOP languages, Speak.t will be similar to a public static property.
Changing it to Speak.protoype.t = 5 will add the property t: 5 to the prototype which will be inherited to all of its instances:
function Speak(){
show(this.t);
}
Speak.prototype.t = 5;
function show(v){
console.log('value is : '+v);
}
var s1 = new Speak(); //"value is : 5"
console.log(s1.t); //5
Since instances inherit from its constructor's prototype, you can actually achieve class inheritance by doing this:
function SpecialSpeak(){}
SpecialSpeak.prototype = new Speak();
This creates a Speak instance and assign it as the SpecialSpeak's prototype.
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
Since all Speak instances will be updated if its prototype has changed, it will also update SpecialSpeak's prototype and also update all SpecialSpeak's instances.
var s = new SpecialSpeak();
s.v; //undefined
Speak.prototype.v = "text";
s.v; //text
This demonstrates how inheritance works in JavaScript. The chaining of prototypes is sometimes called a "prototype chain".
You might also want to check out this great article about inheritance.
Side note: Since all prototype chains must have a starting point,
Object.prototype instanceof Object; //false
Although Object.prototype is an object, it is the very top prototype (object) that everything* inherits from, therefore it's not an instance of Object. It is the Object!
* Starting from ES5, Object.create is introduced which lets you create objects that doesn't inherit from Object.prototype.
This happens because you don't set internally the value of t. You should instantiate the value of t inside the constructor of Speak like this :
function Speak(){
this.t = 5;
show(this.t);
}
function show(v){
console.log('value is : '+v);
}
Speak();
var s1=new Speak();
console.log(s1.t);
You could also attach the showmethod inside the constructor to access the prototype of it.
var Speak = (function() {
function Speak() {
this.t = 5;
this.show();
}
Speak.prototype.show = function() {
return console.log('value is : ' + this.t);
};
return Speak;
})();
var s1=new Speak();
console.log(s1.t);
When the new operator is called on a constructor function, the JavaScript engine executes a few steps behind the scene:
It allocates a new object inheriting from your constructor function's prototype
It executes your constructor function, passing the newly created object as this
If your constructor function returns an object, then it uses it. Otherwise it uses the this object.
At no time it considers the class properties attached to the constructor function. This is why Speak.t = 5 doesn't create an inherited property.
However, those pieces of code will do:
// By attaching `t` to the prototype
function Speak1() {}
Speak1.prototype.t = 5;
// By attaching `t` to the newly created object
function Speak2() {
this.t = 5;
}
// By returning an object containing `t` (thus overriding the formerly allocated this)
function Speak3() {
return {
t: 5
};
}
DEMO
You can read here for more information.
Since functions are just objects t becomes a property of the function Speak, which is not shared with the instances.
for e.g functions by default get a property called length ( gives arity of the function)
which will not be shared with the instances.
function Speak(){}
var obj = new Speak();
console.log("length" in Speak); // true
console.log("length" in obj); // false
you can see quite clearly the length is not shared with the instances.
In javascript the only way to have a property or a method shared is through the prototype pattern.
Creating a property this way, makes it behave like a static variable on Speak

Setting function prototype to a new object

I've been seeing this pattern in code recently:
function Person(){
this.name = "Dan";
}
Person.prototype = {
whatAmI: function(){
alert("I am a person")
}
}
On the above object person object, you can only reference the function whatAmI by calling Person.prototype.whatAmI() instead of Person.whatAmI() .
Is there any particular reason that this is done? Tt seems like its becoming popular and I cant see the benifit other than having methonds hidden on the prototype object instead of the Person object.
I understand the basics prototypes in Javascript, and I understand that using Person.prototype.whatAmI is a little unconventional in code instaed of just calling new Person(). However, I'm talking about places where the Person object is returned from another function call, and used as a normal object. Thus, the only way to call whatAmI is via Person.prototype.whatAmI
The purpose of the prototype property on functions is that it determines what prototype is assigned to objects created via the new expression when it's used with that function, e.g.:
var p = new Person();
Now, p's underlying prototype is the object that Person.prototype referred to when the new expression was evaluated, so:
p.whoAmI();
works.
In general, replacing the object on the prototype property isn't a great idea and you should only do it when setting up inheritance hierarchies. Instead, just add to the existing object:
function Person(){
this.name = "Dan";
}
Person.prototype.whoAmI = function(){
alert("I am a person")
};
A bit tangential, but:
You do have to replace the object, though, when setting up hierarchies.
// Base
function Person(name) {
this.name = name;
}
Person.prototype.whoAmI = function() {
alert("I am " + this.name);
};
// Derived
function Employee(name, position) {
Person.call(this, name);
this.position = position;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
// Augmenting the derived prototype
Employee.prototype.whatDoIDo = function() {
alert("I hold the position " + this.position);
};
(That's not meant to be the be-all, end-all of hierarchies, just a quick example.)
whatmI is meant to be called on Person instances, e.g.:
var bob = new Person();
bob.whatAmI();
The prototype property of a constructor has properties that are accessible to all constructed instances of that constructor.
The ECMAScript 5 specification has a pleasantly readable explanation of the language's prototype-based inheritance:
Each constructor is a function that has a property named “prototype” that is used to implement prototype-based inheritance and shared properties. Objects are created by using constructors in new expressions; for example, new Date(2009,11) creates a new Date object...
Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s “prototype” property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.
Prototype is actually a built in way in JavaScript for accomplishing inheritance. An object that has already been defined can have methods and properties added to it by accessing it's prototype.
Go right to the authority on the subject and read up. This topic in particular is what makes JavaScript cool.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain
There is no specific reason. It depends on what you want.
If the whatAmI function is needed on instances of the type Person, then you define it on the protoype. If you want it on the type, you can do,
Person.whatAmI = function(){
alert("I am a person")
}
They are both valid uses of the language. What you do depends on your application.

Purpose of this Javascript prototype snippet

Sorry I can't phrase this better. But I ran across some code like the following:
MyObject.prototype = Object.create(MyObject.prototype);
MyObject.prototype.constructor = MyObject;
And I just can't seem to figure out what it does. MyObject is defined above it something like this:
function MyObject(options) {
this.someProp = someDefault;
this.otherProp = process(options.something);
// etc...
}
and it's always called as a constructor. I'm just wondering what benefit those first two lines provide and if it's a known pattern in Javascript.
I just can't seem to figure out what it does
It creates a new object that inherits from [the old] MyObject.prototype via Object.create and then overwrites MyObject.prototype with that. It also explicitly adds a .constructor property which actually should be existing already.
I'm just wondering what benefit those first two lines provide
None, unless before that snippet someone has corrupted the prototype (like MyObject.prototype = Object.prototype) and this is an attempt to fix it.
…and if it's a known pattern in Javascript.
Not like this. Using Object.create to set up the prototype chain for inheritance between constructor-defined "classes" is a known pattern, but then the constructors would be different on each side of the assignment.
The two lines of code provided seem to be an incorrect attempt of the use of prototypal inheritance, but I see where you're going with this and what you're trying to accomplish.
As we know, there are two ways in JavaScript to define objects that have properties and methods as members - the object literal notation and function notation. Using object literal notation, we don't have immediate access to the new keyword (think of this like using abstract classes in Java or C#). With function notation, we have access to the new keyword because the initial declaration of an object as a function serves as our constructor.
In ECMAScript 5, The Object object was given a method called create that provided developers a simple way to create a new object from an existing object declared with the object literal notation. (See documentation here). However, objects created in function notation have problems with this method because they are Function objects. The Object.create method is a great way to use simple inheritance, allowing access to the base properties and methods.
With function notation, once the new keyword is used, the result is not a function, but rather an object. For example, I can test this:
var Obj = function(){};
console.log(typeof Obj) // "function"
console.log(typeof new Object()); // "object"
Because of this, you can only inherit once (meaning the child object cannot be derived from):
var MyObject = new Object();
var anotherObj = new MyObject() // throws exception
To alleviate this problem, you need to follow three steps:
Create your child object in function notation (so you can create new instances of it using the new keyword and inherit from it).
Set the child object's prototype (an object) to the result of a new instance of the base object (which will be an object as well).
Set the constructor of the child object (which happens to be on the object's prototype) back to reference the Function of itself (which is a function prior to instantiation). If you don't do this, the constructor will remain an object, which cannot spawn new instances.
From here, you can create new instances of both the child and parent objects and derive from both, using the pattern. Here's a practical example:
var Vehicle = function(){};
Vehicle.prototype.start = function() {
return this.make + " " + this.model + " " + "started";
}
var Car = function(color, make, model) {
this.color = color;
this.make = make;
this.model = model;
}
Car.prototype = new Vehicle();
Car.prototype.constructor = Car;
var myCar = new Car("red", "chevy", "aveo");
myCar.start(); //"chevy aveo started"
I really don't see any benefit in doing that.
What it's doing is providing the new object with the previous objects methods. But it's coming from the same object...
Here is a good example of JS inheritance:
http://jsfiddle.net/aDCmA/2/
var App = (function(){
var Being = function() {
this.living = true;
this.breathes = function () {
return true;
};
};
var Robert = function() {
this.blogs = true;
this.getsBored = function () {
return "You betcha";
}
};
Robert.prototype = new Being();
return {
Being: Being,
Robert: Robert,
being: function(){ return new Being(); },
robert: function(){ return new Robert(); }
}
}());
Here is another question that is similar: inherit prototype methods from other classes without overriding own prototype methods
Credit to Robert Nyman for originally blogging about it: http://robertnyman.com/2008/10/06/javascript-inheritance-how-and-why/
Let's see line by line:
MyObject.prototype = Object.create(MyObject.prototype);
This redefines MyObject.prototype to an object that inherits from MyObject.prototype. This is unusual, because it makes no sense to inherit from itself.
MyObject.prototype.constructor = MyObject;
Since the previous line overwrote MyObject.prototype, this is just fixing the constructor property that was lost in the process.
I can think of one scenario where tht might be useful: if some code before that messed up with MyObject.prototype, for example assigning the prototype of another constructor to it:
MyObject.prototype = SomethingElse.prototype; // wrong way to do inheritance.
Then the code you posted would be an attempt to fix it.
This is perfectly valid Javascript.
Any javascript function (say Func)can be used as a constructor and the constructor invocation also requires a prototype property (i.e. F.prototype or the prototype associated with the function) . Thus (almost) every function has a prototype property. The value of this property (i.e. Func.prototype).
Now the value of this prototype associated with the function is an object itself that has a single non enumerable property called constructor. And the value of this constructor property is the function object (i.e. F itself).
Lets take an example.
Say I construct a function Func
var Func = function() {
//your definition
};
Now since this can be invoked as a constructor it has to have a prototype property Func.prototype lets call this proto.
proto = Func.prototype;
Now the prototype has a single property (that is non enumerable) called constructor. This constructor has a value that is equal to the function object itself.
Dont believe me check it like this
Func.prototype.constructor === Func // =>true
Will always return true for any function.
Now from the code you explained :
So basically these two lines
MyObject.prototype = Object.create(MyObject.prototype);
MyObject.prototype.constructor = MyObject;
are modifying the value of the prototye to have a constructor property with the value of MyObject that is defined. But that would have happened anyways in the normal course of things. But the reason could be that maybe the prototype of the object has been changed earlier from the class it has been inherited from. In that case would those two lines make sense.
Hope that helps :)

Javascript prototype behavior

I have a method that will let me select the prototype object when creating a new object (copied from "Javascript: The Good Parts" book):
Object.create = function(o) {
var F = function() {};
F.prototype=o;
return new F();
}
Now say, I have an object:
var car = {
model: "Nissan"
};
And I create a new object based on this object, using the "Create" method:
var car1 = Object.create(car);
I can then add a property to car and it will dynamically get added to car1 (dynamic prototyping). So for eg:
car.year=2011; // Gets added to "car"...
alert(car1.year); // ... Is also avaialable to car1
Q1) This behavior indicates that "year" got added to car's prototype, which is why it is available to car1. Is this correct? If not, then where does "year" get added and why is it available to both "car" and "car1"?
Also, per the rule of delegation, if a method cannot be found on an object, it will search its prototype and then check all the prototypes up the chain till it gets to Object.prototype. So now, if I type something like this:
Object.prototype.originCountry = "Japan";
alert(car.originCountry); // Outputs Japan
alert(car1.originCountry); // Outputs Japan
So far so good; however, if I do:
Object.carColor= "White";
alert(car.carColor); // Error!
Q2) When I add a property to "car" (see car.year example above, it gets added to car's prototype. However, when I add a property to Object, it does not get added to Object's prototype? If it does get added to Object's prototype, then why is it not available to "car", per the rule of delegation?
Why is this happening?
When you do this:
Object.carColor = "White";
Then the property carColor does not get added to the Object's prototype. It is now a property of Object. To see what you expect, what you would do is:
Object.prototype.carColor = "White";
Then after that:
alert(({}).carColor); // Will alert "White"
So what happens here is that. any object created including {} (which is nothing but an empty object) is a new instance of Object and hence shares the properties of whatever is set in the prototype of Object.
As for how your Object.create function works. Let us look at it line-by-line:
1. var F = function() {};
You just create a new function, an essentially blank object. The reason you use a function and not something like {} is because a function can be coupled with a new call to create a new instance of that object wherein the function would act as a constructor.
2. F.prototype=o;
You set the prototype of the new blank function to the object you've created. Now, this is purely a reference. It is not a deep-copy. What I mean is that as the object o changes, so will any instances of the objects (actually they won't change, but they would 'seem to' change. More on that later).
3. return new F();
Now you just create a new instance of that function, which has a prototype as the object you passed.
When you do the following:
var car1 = Object.create(car);
You get an object car1 which has the prototype has car. So when you do this:
car.year = 2011
It isn't like car1 changes. It is more like the object that the prototype refers to changes. So when you do something like:
car1.year
A search is made (first in the prototype, then in the object) for a property called year and turns out, that the prototype has it and hence car1.year will return 2011.
So the bottom line is this:
A prototype is shared amongst instances.
Changing the properties of an Object will not manifest into any instances changing.
In your first example, you are adding to the prototype of your car1 because car === F.prototype and car1 instanceof F. So to Q1: yes.
Object is the constructor function of all objects, as F is to your car1. If you add something on Object.prototype, it will be available on all objects - that's the reason why you should not, such non-enumerable properties mess up all for-in-loops. If you set a property of the Object constructor function, nothing changes for the things that inherit from it. Don't forget: Object equals the F function, not the o parameter for prototype setting. new Object() is like Object.create(Object.prototype).
That function doesn't let you select the prototype object it creates a nmew object constructor, the object argument as prototype and then return a new object based on the constructor.
That new object will inherit methods and properties from the object arguments. This is to allow the creation of new objects that inherits from others.
The reason this works (and by the way Object is a core javascript object and should not be extended)
Object.prototype.originCountry = "Japan";
alert(car.originCountry); // Outputs Japan
alert(car1.originCountry);
and this doesn't
Object.carColor= "White";
is because the first extend the prototype object of Object, which means object build with the Object constructor will inherits those methods and properties.
When the later is what we call a static function which does not get passed to object created from the Object constructor.
I would recommend reading more about prototypal inheritance in Javascript. here is few links.
http://www.webreference.com/programming/javascript/prototypal_inheritance/index.html
http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=xEJ2PwtH2Oh
http://unscriptable.com/2007/04/17/inheritance-explained/

Categories

Resources