I am trying to understand prototypes and dealing with some interference from my understanding of various other constructs.
Can someone explain to me what Object is in Javascript? To clarify, I know what an object(with a lower-case 'o') is, but not what Object (with a capital 'O') is. I understand that any object that is created in JS has a hidden prototype object attached to it. The prototype object is both a property of the parent object, and an object itself, with its own properties that can be accessed using the following command objectName.prototype; additionally, among the properties of the prototype object is a prototype object. Is Object the same as prototype object? If not, what is Object -- the global object? How does it/they relate to the window object or global object?
Thanks in advance for your help. I've scoured the internet for an answer on this, and couldn't find one that was both accessible or understandable. Although I'm not a 10-year old, if you would kindly explain it to me as though I am, I won't be offended, and will greatly appreciate the effort.
I understand that any object that is created in JS has a hidden prototype object attached to it.
Basically yes. Every object has an internal property, denoted as [[Prototype]] in the specification, whose value is simply (a reference to) another object. That other object is the first object's prototype.
A prototype object itself is not hidden though, and you can explicitly set the prototype of an object, via Object.create:
var foo = {x: 42};
var bar = Object.create(foo);
console.log(bar.x); // 42
console.log(Object.getPrototypeOf(bar) === foo); // true
In this example, foo is the prototype of bar.
The prototype object is both a property of the parent object, and an object itself
First of all, there isn't only one prototype object. Any object can act as a prototype and there are many different prototype objects. And when we say "prototype object", we are really referring to an object that has the "role" of a prototype, not to an object of a specific "type". There is no observable difference between an object that is a prototype and one that isn't.
I'm not quite sure what you mean by "property of the parent object" here. An object is a not property, at most it can be the value of a property. In that sense, yes, an object that is a prototype must be the value of the internal [[Prototype]] property of another object.
But that is not much different than every other relationship between two objects (so nothing special). In the following example bar is an object and also assign to a property of foo:
var bar = {};
var foo = {bar: bar};
Is Object the same as prototype object?
No.
Object is (constructor) function for creating objects. var obj = new Object(); is the same as var obj = {};. However, using object literals ({...}) is more convenient which is why you are not seeing new Object used that much.
For every constructor function C, the following holds true:
Object.getPrototypeOf(new C()) === C.prototype
i.e. the value of the C.prototype property becomes the prototype of new instance of C created via new C.
Object.prototype is actually the interesting part of Object and the most important one. You may have heard about the "prototype chain". Because a prototype is just an object, it has itself a prototype, which is an object, etc. This chain has to end somewhere. Object.prototype is the value that sits at the end of basically every prototype chain.
There are many prototype chains because every value that is not a primitive value (Boolean, Number, String, Null, Undefined, Symbol) is an object (which includes functions, regular expressions, arrays, dates, etc).
If not, what is Object -- the global object?
See above. It's not the global object, the global object in browsers is window, and while every JavaScript environment must have a global objects, at least so far there is no standard way in the language to reference it (edit: I guess this in the global environment would one cross-platform way).
How does it/they relate to the window object or global object?
The only relation really is:
Object is a property of the global object, and thus a global variable.
You may think the global object's prototype is also Object.prototype, but that is not necessarily the case
Reading material:
You Don't Know JS: this & Object Prototypes ; all of gettify's books in the series are pretty awesome.
http://felix-kling.de/jsbasics/ ; shameless plug for some very concise slides that I created for a JavaScript class that I'm teaching from time to time. Might not be detailed enough to be useful on it's own (and contains typos ;) )
Related
I need some help for understanding the prototype chain. I don't understand / not quite sure if my assumptions are correct. I want to understand the link to the Object.prototype.
One example
function A(){};
var newObject=new A();
I know the newObject has an internal property [[prototype]] which has a reference to A.prototype.
And this prototype-Object has also an internal property with reference to Object.prototype, right?
But why does it have that reference? Is it because the prototype of A (used as constructor) is an object which can be imagined to be created by A.prototype=new Object() ( which will be done automatically in the background). And now I have a reference to the prototype of Object?
I hope I explained it clearly.
Please let me know your comments.
Many thanks
Yes, your understanding is correct.
In JS, pretty much all the objects have a reference to Object.prototype in their prototype chain.
The [[Prototype]] of an object refers to Object.prototype as the end of a prototype chain. In your example, this means what you described:
[[Prototype]] [[Prototype]]
newObject -----------------> A.prototype -----------------> Object.prototype
That applies to...
objects created by the Object constructor (i.e. new Object(...)),
those created with an object literal (which you can think of as syntax sugar for a new Object() call followed by a bunch of Object.defineProperty calls) and
objects created internally by the JS interpreter (like A.prototype which is created automatically when you define the A function).
There are also exceptions of this "rule" though:
Object.prototype itself.
If it had a reference to... well, itself, it would create and infinite recursion when a nonexistent property is looked up. Hence, it has no prototype, which means that its [[Prototype]] is null (that's how a prototype chain "ends").
Custom objects created using Object.create or modified with Object.setPrototype.
The [[Prototype]] can be set to anything this way, including null or other objects whose prototype chain doesn't end with Object.prototype.
This is indeed what the ECMAScript specification prescribes. When a function is defined with the function keyword, then an object is created from Object.prototype which is assigned to the function's prototype property, and therefor will be used as prototype for any object that is constructed by that function.
This specification can be found at Make Constructor, step 5.a:
5.a. Set prototype to OrdinaryObjectCreate(%Object.prototype%).
When it comes to javascript every value is either an object (arrays, objects, sets, maps...) or a primitive(Numbers, strings, bool ...) objects and primitives are the two data types in javascript a . You have the Number, String , Array and even Object constructors which you can use to create the corresponding value.
And when you create new object using the new operator the following steps happen consecutively:
// 1. New empty object is created
// 2. the constructor function is called, and the this keyword is assigned to the empty object i.e this = {}.
// 3. the empty object is linked to the prototype of the constructor functio i.e {}.proto = constructorFunction.prototype.
// 4. the constructor function automatically return the new object {}.
keep in mind that constructorFunction.prototype is the prototype of the new object that is created from the constructorFunction and not of itself.
I hope this clears things up a little for you!
But why does it have that reference?
To answer in one sentence - because prototype is an object itself and has its own prototype. When you create function in JavaScript it has a property called prototype. When you use that function as a constructor function (with new operator), new object is creating which as you wrote is linked to its constructor function prototype via internal [[prorotype]] property. That prototype object is plain JavaScript object which [[prototype]] property references Object.prototype.
In JavaScript is Object the root of all entities or Function is the root?
For example in the following source objects-functions-and-prototypes-in.html, first the author says "Every entity in Javascript is an object", and later it says "any new object can only be created as an instance of a function (even when you do 'var a = new Object;', Object is a function btw)". The author is basically contradicting himself as far as I can see.
And I see the same chaotic comments in so many other resources on JavaScript. In Java it is easy, you know the first entity in any class Hierarchy is the Object class, but in JavaScript, all I see is chaos.
So, can someone please clarify if Object comes first or Function? What is the root.
I believe the end of the line is Object.prototype, which is an object. This is what makes me think so:
Function.prototype; // the empty function object
Function.prototype.__proto__; // the default Object prototype
Object.prototype; // the default Object prototype
Object.prototype.__proto__; // null
The ECMAScript 5.1 specification states it like this:
In 15.3.4 Properties of the Function Prototype Object:
The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object
And in 15.2.4 Properties of the Object Prototype Object
The value of the [[Prototype]] internal property of the Object prototype object is null
Here's what the MDN docs for Object.prototype have to say:
all objects inherit methods and properties from Object.prototype, although they may be overridden (except an Object with a null prototype, i.e. Object.create(null)).
In other words, Object.prototype is the root of almost all objects. Both Object and Function are children of Function.prototype, which is itself a child of Object.prototype.
I find inheritance in Javascript to be far easier to understand when I ignore the constructor functions, and instead focus on prototype chains. Doing this, for me, makes both the questions as well as the answers simpler; questions like:
what is the prototype chain of an object?
given two objects x and y, is x in y's prototype chain? (or: does y inherit from x?)
You can easily investigate prototype chains yourself with this little snippet (helpful docs here):
function getPrototypes(obj) {
var protos = [],
parent = obj;
while ( true ) {
parent = Object.getPrototypeOf(parent);
if ( parent === null ) {
break;
}
protos.push(parent);
}
return protos;
}
According to this function, primitives don't have prototypes:
> getPrototypes(3)
TypeError: Object.getPrototypeOf called on non-object
So let's leave primitives out of the picture.
For objects, the hierarchy looks like this (where the children are indented to the right of their parent). As far as I know, true multiple inheritance is impossible in Javascript, and so every object has a single parent, with the exception of Object.prototype, which has no parent:
Object.create(null)
Object.prototype
arguments
Object.create(Object.prototype)
{}
Object.create({}) -- assuming {} is the object from the previous line, not a separate new object
JSON
Math
Array.prototype
[]
new Array()
Function.prototype
Array
Object
Function
Number
Boolean
String
RegExp
function MyFunction() {}
Object.keys
Object.prototype.toString
Object.prototype.toString.call
getPrototypes
MyFunction.prototype
new MyFunction()
String.prototype
new String('abc')
Object.create(new String('abc'))
Number.prototype
new Number(41)
Boolean.prototype
new Boolean()
new Object(false)
RegExp.prototype
/a/
This is very confusing! Notice that for most cases, X.prototype is not a prototype of X! If we had some better terminology, the situation would probably be improved; however ... we don't :( As you can see, constructors such as Number and Boolean are in a separate sub-hieararchy from the objects they produce. Also, Object itself inherits from Function.prototype inherits from Object.prototype.
If you try these examples out, you will also find that using the constructor property is a poor way to inspect an object's prototypes, for a couple of reasons. Given var str1 = new String('abc'); var str2 = Object.create(str1);, here's why:
an object can be an instance of multiple constructors: str1 instanceof String and str1 instanceof Object are both true. This isn't reflected in the constructor property: str1.contructor === String
sometimes, we can't find a constructor function for each object in an object's prototype chain: Object.getPrototypeOf(str2).constructor === String. This is because the constructor property is inherited from String.prototype: both str1.hasOwnProperty('constructor') and str2.hasOwnProperty('constructor') are false, while Object.getPrototypeOf(str1).hasOwnProperty('constructor') is true. Fortunately, you can use the Object.prototype.isPrototypeOf method for this instead: str1.isPrototypeOf(str2) is true.
You're misunderstanding it.
Everything in Javascript (including all functions) is an object.
However, every object is an instance of a function. (as specified by the object's constructor property)
function Gadget(name, color)
{
this.name = name;
this.color = color;
}
Gadget.prototype.rating = 3
var newtoy = new Gadget("webcam", "black")
newtoy.constructor.prototype.constructor.prototype.constructor.prototype
It always returns the object with rating = 3.
But if I do the following:
newtoy.__proto__.__proto__.__proto__
The chain ends up returning null.
Also in Internet Explorer how would I check the null if there is not a __proto__ property?
I've been trying to wrap my head around this recently and finally came up with this "map" that I think sheds full light over the matter
http://i.stack.imgur.com/KFzI3.png
I know I'm not the first one making this up but it was more interesting figuring it out that finding it :-). Anyway, after that I found e.g. this another diagram that I think says basicly the same:
Javascript object layout
The most surprising thing for me was discovering that Object.__proto__ points to Function.prototype, instead of Object.prototype, but I'm sure there's a good reason for that :-)
I paste the code mentioned in the image here as well for if anyone wants to test it. Note that some properties are added to the objects for making easy to know where we are after some jumps:
Object.O1='';
Object.prototype.Op1='';
Function.F1 = '';
Function.prototype.Fp1 = '';
Cat = function(){};
Cat.C1 = '';
Cat.prototype.Cp1 = '';
mycat = new Cat();
o = {};
// EDITED: using console.dir now instead of console.log
console.dir(mycat);
console.dir(o);
constructor is a pre-defined [[DontEnum]] property of the object pointed to by the prototype property of a function object and will initially point to the function object itself.
__proto__ is equivalent to the internal [[Prototype]] property of an object, ie its actual prototype.
When you create an object with the new operator, its internal [[Prototype]] property will be set to the object pointed to by the constructor function's prototype property.
This means that .constructor will evaluate to .__proto__.constructor, ie the constructor function used to create the object, and as we have learned, the protoype property of this function was used to set the object's [[Prototype]].
It follows that .constructor.prototype.constructor is identical to .constructor (as long as these properties haven't been overwritten); see here for a more detailed explanation.
If __proto__ is available, you can walk the actual prototype chain of the object. There's no way to do this in plain ECMAScript3 because JavaScript wasn't designed for deep inheritance hierarchies.
The Prototypal Inheritance in JavaScript is based on __proto__ property in a sense that each object is inheriting the contents of the object referenced by its __proto__ property.
The prototype property is special only for Function objects and only when using new operator to call a Function as constructor. In this case, the created object's __proto__ will be set to constructor's Function.prototype.
This means that adding to Function.prototype will automatically reflect on all objects whose __proto__ is referencing the Function.prototype.
Replacing constructor's Function.prototype with another object will not update __proto__ property for any of the already existing objects.
Note that __proto__ property should not be accessed directly, Object.getPrototypeOf(object) should be used instead.
To answer the first question, I've created a bespoke diagram of __proto__ and prototype references, unfortunately stackoverflow does not allow me to add the image with "less than 10 reputation". Maybe some other time.
[Edit]
The figure uses [[Prototype]] instead of __proto__ because that is how ECMAScript specification refers to internal objects. I hope you can figure everything out.
Here are some hints to help you understand the figure:
red = JavaScript Function constructor and its prototype
violet = JavaScript Object constructor and its prototype
green = user-created objects
(first created using Object constructor or object literal {},
second using user-defined constructor function)
blue = user-defined function and its prototype
(when you create a function, two objects are created in memory:
the function and its prototype)
Note that constructor property does not exist in created objects, but is inherited from the prototype.
Object is Eve, and Function is Adam, Adam (Function) uses his bone (Function.prototype) to create Eve (Object). Then who created Adam (Function)? -- The Inventor of the JavaScript language :-).
According to utsaina's answer, I want to add more useful info.
The most surprising thing for me was discovering that Object.__proto__
points to Function.prototype, instead of Object.prototype, but I'm
sure there's a good reason for that :-)
It should NOT be. Object.__proto__ should NOT point to Object.prototype. Instead, the instance of Object o, o.__proto__ should point to Object.prototype.
(Forgive me for using the terms class and instance in JavaScript, but you know it :-)
I think the class Object itself is an instance of Function, that's why Object.__proto__ === Function.prototype. Therefore: Object is Eve, and Function is Adam, Adam (Function) uses his bone (Function.prototype) to create Eve (Object).
Furthermore, even the class Function itself is an instance of Function itself, that is Function.__proto__ === Function.prototype, that's also why Function === Function.constructor
Further furthermore, the regular class Cat is an instance of Function, that is Cat.__proto__ === Function.prototype.
The reason for the above is, when we create a class in JavaScript, actually, we are just creating a function, which should be an instance of Function. Object and Function are just special, but they are still classes, while Cat is a regular class.
As a matter of factor, in Google Chrome JavaScript engine, the following 4:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
They are all === (absolutely equal) to the other 3, and their value is function Empty() {}
> Function.prototype
function Empty() {}
> Function.__proto__
function Empty() {}
> Object.__proto__
function Empty() {}
> Cat.__proto__
function Empty() {}
> Function.prototype === Function.__proto__
true
> Function.__proto__ === Object.__proto__
true
> Object.__proto__ === Cat.__proto__
true
OK. Then who creates the special function Empty() {} (Function.prototype)? Think about it :-)
I really don't know why people didn't correct you about where the actual problem in your understanding.
This would make a lot easier for you to spot the problem
So let's see what's going on :
var newtoy = new Gadget("webcam", "black")
newtoy
.constructor //newtoy's constructor function is newtoy ( the function itself)
.prototype // the function has a prototype property.( all functions has)
.constructor // constructor here is a **property** (why ? becuase you just did `prototype.constructor`... see the dot ? ) ! it is not(!) the constructor function !!! this is where your mess begins. it points back to the constructor function itself ( newtoy function)
.prototype // so again we are at line 3 of this code snippet
.constructor //same as line 4 ...
.prototype
rating = 3
Great , so now let's look at this __proto__
Before that , please remember 2 things regarding __proto__ :
When you create an object with the new operator, its internal [[Prototype]]/proto__ property will be set to the prototype property(1) of its constructor function or "creator" if you like .
Hard coded within JS — : Object.prototype.__proto__ is null.
Let's refer to these 2 points as "bill"
newtoy
.__proto__ // When `newtoy` was created , Js put __proto__'s value equal to the value of the cunstructor's prototype value. which is `Gadget.prototype`.
.__proto__ // Ok so now our starting point is `Gadget.prototype`. so regarding "bill" who is the constructor function now? watch out !! it's a simple object ! a regular object ! prototype is a regular object!! so who is the constructor function of that object ? Right , it's the `function Object(){...}`. Ok .( continuing "bill" ) does it has a `prototype` property ? sure. all function has. it's `Object.prototype`. just remember that when Gadget.prototype was created , it's internal `__proto__` was refered to `Object.prototype` becuase as "bill" says :"..will be set to the `prototype` property of its `constructor function`"
.__proto__ // Ok so now our satrting point is `Object.prototype`. STOP. read bullet 2.Object.prototype.__proto__ is null by definition. when Object.prototype ( as an object) was created , they SET THE __PROTO__ AS NULL HARDCODED
Better?
Every functions creates it's prototype.
And when we create an object using that function constructor then the __proto__ property of my object will start pointing to the prototype of that function.
If all those figures were overwhelming, let's take a look what the properties mean.
STH.prototype
When creating a new function, there is an empty object being created in parallel and linked to the function with [[Prototype]] chain. To access this object, we use prototype property of the function.
function Gadget() {}
// in background, new object has been created
// we can access it with Gadget.prototype
// it looks somewhat like {constructor: Gadget}
Bear in mind that prototype property is only available for functions.
STH.constructor
The prototype object mentioned above has no properties except for one - constructor. This property represents a function that created the prototype object.
var toy = new Gadget();
When creating Gadget function, we created an object like {constructor: Gadget} as well - that is nothing like Gadget.prototype. As constructor refers to a function that created an object prototype, toy.constructor represents Gadget function. We write toy.constructor.prototype and we are getting {constructor: Gadget} again.
Therefore, there's a vicious circle: you can use toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype and it always will be Gadget.prototype.
toy
.constructor // Gadget
.prototype // {constructor: Gadget}
.constructor // Gadget
.prototype // {constructor: Gadget}
// ...
STH.__proto__
While prototypeis a property specific for functions, __proto__ is available for all objects as it lays in Object.prototype. It refers to prototype of a function that can create an object.
[].__proto__ === Array.prototype
// true
({}).__proto === Object.prototype
// true
Here, toy.__proto__ is Gadget.prototype. As Gadget.prototype is an object ({}) and objects are created with Object function (see the example above), we get Object.prototype. This is the higher object in JavaScript and its __proto__ can only indicate null.
toy
.__proto__ // Gadget.prototype (object looking like {constructor: Gadget})
.__proto__ // Object.prototype (topmost object in JS)
.__proto__ // null - Object.prototype is the end of any chain
Short answer: __proto__ is a reference to the prototype property of the constructor that created the object.
Objects in JavaScript
A JavaScript object is a built-in type for a collection of zero or more properties. Properties are containers that hold other objects, primitive values, or functions.
Constructors in JavaScript
Functions are regular objects (which implement [[Call]] in ECMA-262 terms) with the additional capability of being callable but play another role in JavaScript: they become constructors (factories for objects) if invoked via the new operator. Constructors are thus a rough analog to classes in other languages.
Every JavaScript function is actually an instance of the Function built-in function object that has a special property named prototype used to implement prototype-based inheritance and shared properties. Every object created by a constructor function has an implicit reference (called the prototype or __proto__) to the value of its constructor prototype.
The constructor prototype is a sort of blueprint for building objects since every object created by the constructor inherits a reference to its prototype.
The prototype chain
An object specifies its prototype via the internal property [[Prototype]] or __proto__. The prototype relationship between two objects is about inheritance: every object can have another object as its prototype. The prototype may be the null value.
The chain of objects connected by the __proto__ property is called the prototype chain. When a reference is made to a property in an object, that reference is to the property encountered in the first object in the prototype chain that contains a property of that name. The prototype chain behaves as if it were a single object.
Whenever you try to access a property in an object, JavaScript starts the search for it in that object and continues with its prototype, the prototype's prototype and so on until the property is encountered or if __proto__ holds the value null.
This type of inheritance using the prototype chain is often called delegation to avoid confusion with other languages using the class chain.
Almost all objects are instances of Object, because Object.prototype is last in their prototype chain. But Object.prototype is not an instance of Object because Object.prototype.__proto__ holds the value null.
You can also create an object with a null prototype like this:
var dict = Object.create(null);
Such an object is a better map (dictionary) than a literal object, which is why this pattern is sometimes called the dict pattern (dict for dictionary).
Note: literal objects created using {} are instances of Object since ({}).__proto__ is a reference to Object.prototype.
Prototypes in JavaScript are confusing for Everyone
A constructor on any type (Object, String, Array, etc) is initially connected with the Function Object that creates them. Once the object types value/objects are created, only then are they assigned their own prototypes, which is a unique property and object the Functions constructor creates when each value is created. But the prototyopes of all objects/types (Object, String, Array, etc) in JavaScript starting out are all Function.prototype. They all derive from functions and their constructors needed to create instances of objects and primitive values in memory! It is not till their values get created by their function constructors that they get assigned their own unique prototypes, both the "prototyoe" property and the Object prototype they inherit from.
This is what 99% of online web pages on the Internet do not tell you!
For example, the Number (or String Array, Boolean, etc.) type always has a constructor, or Number.constructor, which derives from the Function Object assigned to the "Number" type. This is why "Number" is called an "Constructor". So, its prototype is Function.prototype when you check. Once its function or constructor has built a true Number primitive or type, its assigned its own unique prototype of Number.prototype. Let's prove that below!
Here is a simpler explanation. Below is how most objects in JavaScript inherit starting with null down to the object type:
String < Function < Object < null
Array < Function < Object < null
Object < Function < Object < null
Function < Function < Object < null
Here is proof!
Below I am just asking for the prototype found for each object. Note: Object.prototype.toString.call() just tells us the string name of the prototype:
Object.prototype.toString.call(String);// [object Function]
Object.prototype.toString.call(Array);// [object Function]
Object.prototype.toString.call(Object);// [object Function]
Object.prototype.toString.call(Function);// [object Function]
Object.prototype.toString.call(String.__proto__);// [object Function]
Object.prototype.toString.call(Array.__proto__);// [object Function]
Object.prototype.toString.call(Object.__proto__);// [object Function]
Object.prototype.toString.call(Function.__proto__);// [object Function]
Object.prototype.toString.call(String.__proto__.__proto__);// [object Object]
Object.prototype.toString.call(Array.__proto__.__proto__);// [object Object]
Object.prototype.toString.call(Object.__proto__.__proto__);// [object Object]
Object.prototype.toString.call(Function.__proto__.__proto__);// [object Object]
Object.prototype.toString.call(String.__proto__.__proto__.__proto__);// [object Null]
Object.prototype.toString.call(Array.__proto__.__proto__.__proto__);// [object Null]
Object.prototype.toString.call(Object.__proto__.__proto__.__proto__);// [object Null]
Object.prototype.toString.call(Function.__proto__.__proto__.__proto__);// [object Null]
Please note that the string "[object Function]" is saying that the "prototype" or parent object for the type was "Function.prototype". So it a representation of the underlying prototype parent objects assigned at each level. Now let's explain this in more depth...
A prototype in JavaScript is a word that means the following:
All Objects in JavaScript ultimately inherit from a series of prototypes or "base classes" that assign their various properties and features through inheritance. This cascades down a tree to the child at the bottom. In JavaScript ALL OBJECTS ultimately inherit from the Object.prototype which is close to the top of that inheritance tree.
The term "prototype" means a special object with properties and methods inherited by child objects
"prototype" is also a special property given to all Objects in JavaScript that assigns a given object as the parent prototype to a child but also grants access to changing the prototype. It controls the actual prototype assigned to a child object, but also acts like a true Class Property in that you can use it to manipulate the prototype of a child object. I do not recommend you do this, but you can modify the original Object.prototype inherited by all object by adding new properties using a simple property addition or adding properties via a Object Literal containing properties:
Object.prototype.myproperty = "Hello World";
Object.prototype.myobjectproperties = {text1: "Hello", text2: "World"};
"prototype" the property is expressed in combination with the Child Object name as "MyObjectType.prototype". This new name is now both a identifier for the parent prototype and also a tool to change it. But it is NOT a reference to the actual prototype object! (That is done below using __proto__). It is assigned to all new objects when created of that type. It is first assigned to the function constructor that built the object, then passed to the object the function constructor creates.
"__proto__" is a reference to the actual prototype object assigned to the child. Its also a property but its a reference. So its used to go up the tree of prototypes objects inherited by a child object and access them and their properties. This example below goes up the tree from an object literal created and ends at the top with "null":
alert({}.__proto__.__proto__);// null
Weirdness in Prototype
So, in JavaScript inheritance, everything starts with a Function type! Why is that? Its because you cannot create any of the object "types" (Object, Array, Function, String, etc.) without a Function. And when you do, they still get constructed from a "constructor" called somewhere in a function. A Function and its constructor is what not only creates new objects from types, but also assigns the "prototype" property, the "__proto__" property, and the actual tree of inherited prototypes or objects the child object will use.
There are two states of objects in JavaScript, the "types" and the actual instantiated Objects. That is why "Object" is not the same as a created Object as "const x = {}". And that is why the "type" starts out with a different inheritance or prototypes from its final one.
Check this out!
// The Array type has a prototype of "Function.prototype"
alert(Object.prototype.toString.call(Array));// [object Function]
// But an instance of an Array object has a NEW prototype of "Array.prototype" that the function prototype's constructor created for the object!
const myarray = [];
alert(Object.prototype.toString.call(myarray));// [object Array]
So what happened?
It turns out the FUNCTION CONSTRUCTOR creates and assigns the final prototype when the object is created. But that custom prototype can be modified both before and after the array object is created with many more properties, objects, etc. So the final assigned prototype is set by the constructor of the Function object which as shown above was the Array types initial prototype.
So realize, the Function.prototype is the primary prototype of all Object types in JavaScript! It lies underneath all objects, but is a tool to creating the final instantiated object that is assigned its own prototype when created. Note that the "Array.prototype" has a parent prototype of Object.prototype who has a parent of "null". So the Object.prototype remains the top parent inherited by all these objects. But in the creation of them the constructor changes the immediate parent of all child objects when new objects get created.
Note that the Function.prototype gets many of its features from its own Object.prototype it too inherits. The prototype it builds for your created objects are also made from this parent prototype. So in the end. the Object.prototype provides the goodies needed for Function types and all types to get created and manage the prototype assigned to them. Just remember Function like Object is a special pre-built type with special tools and features needed to create all types of objects!
Last test....lets see how prototype works for CUSTOM OBJECTS we create. The example below proves that the function constructor (part of the Function.prototype) assigns the "prototype" property to the created objects BUT can be customized with various properties and methods before or after being assigned to the objects prototype of MyCustomObject.prototype. This shows that the final prototype of your object need not be a static copy of the Object.prototype's inherited properties, but can be something you create that is entirely new!
let newPet;
function Pet() {
this.fourlegs = true;
}
var Cat = {
type : "cat"
}
var Dog = {
type : "dog"
}
// We can see the prototype our constructor created for us
// and modify it as we like! Here we assigned it to an object
// which only means the prototype will merge "Cat" object's
// properties into the Pet.prototype.
Pet.prototype = Cat;
newPet = new Pet();
alert(newPet.type);// cat - inherited the Cat Object's properties in the prototype
Pet.prototype = Dog;
newPet = new Pet();
alert(newPet.type);// dog - inherited the Dog Object's properties in the prototype
alert(newPet.fourlegs);// true - this shows, even though you replace prototype, it ADDs the new types but does NOT erase the existing object properties! This must mean "prototype" is dynamically additive and rebuilt until the final "Pet" prototype is complete.
// Now change the "Pet.prototype" so all new objects have a new property.
Pet.prototype.furcolor = "white";
newPet = new Pet();
alert(newPet.furcolor);// "white"
// So you can see the "Pet.prototype" is dynamic, something you can tell the function constructor to modify!
I've been reading about the prototype chain in JavaScript and came to two slightly different definitions. It is said that every object in JavaScript has a prototype and that prototype in turn has another prototype.
The top prototype (Grand) may also have prototype and the chain can continue. Now the chain will stop at one last object. JavaScript: The Good Parts says the chain terminates at Object.prototype and MDN says null is the final link where the chain terminates.
Javascript: The Good Parts
Every object is linked to a prototype object from which it can inherit properties. All objects created from object literals are linked to Object.prototype, an object that comes standard with JavaScript.
MDN
Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. null, by definition, has no prototype, and acts as the final link in this prototype chain.
What is the end of prototype chain in JavaScript -- null or Object.prototype? Or are null and Object.prototype one and the same thing?
Are objects, which are not created from object literals, not linked to Object.prototype?
Say I have an object var x = { len: 4, breadth: 5}. Would JavaScript automatically create its prototype x.prototype? And how long would the prototype chain be? Would x.prototype have only one prototype, Object.prototype, making a 3 point chain?
How does JavaScript internally create automatic prototypes?
It is like, if New York has an envelope and inside, it says Colorado, and Colorado has an envelope, and inside, it says San Francisco, and San Francisco has an envelope, and inside, it says "none". So is San Francisco end of the chain, or is "none" the end of chain? It may depend on how you look at it. But one thing is for sure: it points up and up the chain, for inheritance purpose (prototypal inheritance), until it reaches null, which means can't go further up. And make sure you know that, to go up and up the chain, it is __proto__. It is not prototype.
Object.prototype, Animal.prototype are different from x.__proto__. The former are function objects (Object, Animal) having a prototype property pointing to a prototype object. And x.__proto__ is how the prototype chain is followed upward. To go up and up, it is x.__proto__.__proto__ and so on. See JavaScript's Pseudo Classical Inheritance diagram to understand it more.
Object.prototype refers to a prototype object. Quoted from MDN, null "represents the intentional absence of any object value. It is one of JavaScript's primitive values." So Object.prototype and null are not the same thing.
All JavaScript objects will have obj.__proto__ referring ultimately to what Object.prototype refers to. If it is not obj.__proto__, then it is obj.__proto__.__proto__. If not, just go up, and up, and it will reach the prototype object which Object.prototype refers to. And at this point, when you go up one level (by adding a .__proto__, then you get null. You can try it in Google Chrome's developer's tool:
x = { a : 1 }
> Object {a: 1}
x.__proto__ === Object.prototype
> true
x.__proto__.__proto__
> null
Object.prototype.__proto__
> null
What is the end of prototype chain in JavaScript ...?
Null. The only authority on the language is ECMA-262.
Are objects, which are not created from object literals, not linked to Object.prototype?
They may or many not be, e.g.
var x = Object.create(null)
has a [[Prototype]] of null, whereas:
var y = {};
has a [[Prototype]] of Object.prototype.
Say I have an object var x = { len: 4, breadth: 5}. Would JavaScript automatically create its prototype x.prototype?
No. Function objects have default prototype objects. Plain objects have a default [[Prototype]] (i.e. internal prototype property) that is Object.prototype (unless constructed as above).
And how long would the prototype chain be? Would x.prototype have only one prototype, Object.prototype, making a 3 point chain?
Two values: Object.prototype and null.
How does JavaScript internally create automatic prototypes?
However it likes, the language specification does not define implementation, only behaviour.
What is the end of prototype chain in javascript -- null or Object.prototype? Or are null and Object.prototype one and the same thing?
null. Consider this code in a normal JavaScript environment:
var o = {};
console.log(o.i_am_a_property_that_does_not_exist);
That property accessor operation (o.i_am_a_property_that_does_not_exist) ends up going to the OrdinaryGet abstract operation defined by the specification with O set to the o object above and P set to "i_am_a_property_that_does_not_exist". That operation starts like this:
Assert: IsPropertyKey(P) is true.
Let desc be ? O.[GetOwnProperty].
If desc is undefined, then
a. Let parent be ? O.[GetPrototypeOf].
b. If parent is null, return undefined.
c. Return ? parent.[[Get]](P, Receiver).
...
For my example above, that [[Get]] operation in 3.c. ends up calling OrdinaryGet recursively until we run out of prototypes. As we can see, the chain ends when we reach null.
Moreover, it's entirely possible to have an object with a prototype chain that doesn't include Object.prototype at all (we'll see some in a moment). So clearly Object.prototype can't be the end of the prototype chain.
Are objects, which are not created from object literals, not linked to Object.prototype?
The vast majority will be linked to Object.prototype directly or indirectly. Consider:
function Thing() {
}
var t = new Thing();
t's prototype is the object referenced by Thing.prototype. Thing.prototype's prototype is Object.prototype. So t is linked to Object.prototype (indirectly).
But it's entirely possible for an object not to be linked to Object.prototype. Here's one way:
var o = Object.create(null);
Object.create lets us create an object with the prototype we specify in the first argument (null in the above). So o above has no prototype, its [[Prototype]] internal slot (where objects remember their prototypes) is null.
Here's another:
function Thing() {
}
Thing.prototype = Object.create(null);
var t = new Thing();
In that case, although t has a prototype, its prototype's prototype is null; t isn't linked to Object.prototype at all.
Say I have an object var x = { len: 4, breadth: 5}. Would JavaScript automatically create it's prototype x.prototype.
An object's prototype is not a property called prototype, so no, the JavaScript engine wouldn't create x.prototype. An object's prototype is linked via its [[Prototype]] internal slot, which is not directly observable but can be retrieved via Object.getPrototypeOf. (There's also the legacy __proto__ property, but it's best not to use it, not least because A) It's an optional part of the specification, and B) Not all objects inherit from Object.prototype, which is where __proto__ is defined.)
The prototype property is just used on functions to determine what object to use as the [[Prototype]] of new objects created via new with that function. Non-function objects don't have it, and if they did, it wouldn't be any more special than a property called foo or bazinga.
And how long would the prototype chain be? Would x.prototype have only one prototype Object.prototype making a 3 point chain?
You're close, but again, the prototype property is not the prototype of the object, and non-function objects typically won't have a prototype property. For var x = { len: 4, breadth: 5}, the inheritance chain would be:
x
x's [[Prototype]] (which is Object.prototype)
Object.prototype's [[Prototype]], which is null
So quite short; 1, 2, or 3 depending on whether you want to count x and whether you want to count null.
How does JavaScript internally creates automatic prototypes?
It doesn't, other than the ones defined by the spec (e.g., Object.prototype and such). The closest it comes is that for all function functions, the JavaScript engine automatically creates an object and assigns that object to the function's prototype property just in case that function is used as a constructor (via new). (It doesn't do this with arrow functions or generators.)
In the browser's console, try creating an object literal:
const myObject =
{
city: 'Madrid',
greet()
{
console.log(`Greetings from ${this.city}`);
}
}
myObject.greet(); // Greetings from Madrid
This is an object with one data property, city, and one method, greet().
If you type the object's name followed by a period into the console, like myObject., then the console will pop up a list of all the properties available to this object.
You'll see that as well as city and greet, there are lots of other properties!
__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
__proto__
city
constructor
greet
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString
toString
toValueOf
Try accessing one of them:
myObject.toString(); // "[object Object]"
Copy to Clipboard
It works (even if it's not obvious what toString() does).
consider a piece of code
function F(){
this.p=10;
}
F.prototype.newProp='some value';
var f1=new F(), f2=new F();
alert(f1.__proto__==f2.__proto__); //returns true. implies f1 and f2 share same instance of prototype object
f1.newProp='new value'; //changing the value of inherited property
alert(f2.newProp); //returns 'some value'
Ok now the question is if f1 and f2 both share the same [[prototype]] object instance
and if
property retrieval in javascript works by walking along the prototype chain
So if I change value of a property (newProp, in this case) of a shared [[prototype]] object,
how come its not reflected in f2 as well ,
since f1.proto==f2.proto (which means its the SAME object)
then why changing the newProp of f1 doesn't change newProp of f2 (both inherit from same prototype object, no ?)
Surprisingly,changing f1.proto.newProp reflects the change when retrieving "f1.newProp"
So , are f1.newProp and f1.proto.newProp different properties ?
I thought the property look up in javascript worked by successively looking higher in the prototype chain.
I am sorry if my question sounds naive, but I couldn't get my head around :
If 1) f1.proto==f2.proto //true! implies both objects f1 and f2 refer same [[prototype]] object from which they inherit
and if
2) property not found in object is searched in its prototype .
then why changing f1.newProp doesn't reflect in f2.newProp too ? as both have common [[prototype]] property as shown in point (1)
Is it that properties from prototype object are being copied individually into f1 and f2. ?
but then thats in violation of point (2) [looking up the properties of prototype chain when not not found in the object]
Please explain the contradiction here. thank u very much :)
==================EDIT================
thank you #jfriend00 for the reply.
but lets say I have this code
function Person(name, age){
this.name=name;
this.age=age;
alert("obj created:"+name);
}
function Employee(name,age,eid){
this.base=Person;
this.base(name,age);
this.eid=eid;
}
Employee.prototype=new Person;
var ob1=new Employee('name1',23,100);
var ob2=new Employee('name2',24,101);
here too, obviously ob1.proto==ob2.proto
but if I am not mistaken there's 2 objects here for each instance of employee
1 is the employee object itself with only 1 property eid (and other one base func)
2nd is the Person object which is referenced by the [[prototype]] property of employee object. This object has name and age property..
So , employee obj actually stores and retrieves name and age from its [[prototype]] Person object.
Am I right ?
If so , and since ob1.proto==ob2.proto, then how are we able to store unique name and age of both objects ?
I mean, here it almost seems there's a prototype object for each employee.
if u could explain this, thank u very much :)
and one more query is :
how come the above code will work even if comment out the
Employee.prototype=new Person;
in the above line and thereby breaking the link between 2 objs. Inheritance still works just because I have declared Person function as a property of Employee and called Person from it .
how is this working
thank you :)
Once you set f1.newProp = 'new value', it no longer is setting newProp on the prototype, but on the f1 object itself. Try this, you will see:
var f1=new F(), f2=new F();
console.log(f1.hasOwnProperty('newProp')); // returns false, because it is from prototype
f1.newProp = 'new value';
console.log(f1.hasOwnProperty('newProp')); // returns true
The prototype object is shared among all objects (as you have shown).
But, when you assign to a property an the object, it doesn't change the prototype, the property goes on the object itself and because of the lookup order for resolving a property reference, the newly assigned property on the object itself is found before the one on the prototype so it becomes the active property.
When you reference a property on an object, there is a search order. First it looks for properties directly on the object. If no match is found, then it searches the prototype chain.
When you write to a property on the object, it never writes to the prototype unless you explicitly reference the prototype object, instead it puts a property directly on the object and that property then becomes the active one (essentially overriding what's on the prototype).
You can tell whether a property is on the object itself or on the prototype by using .hasOwnProperty(). That will return true only when the property is directly on the object.
So, in your code:
f1.newProp='new value'; //changing the value of inherited property
This adds a new property directly to the object (not on the prototype) and it essentially overrides what is on the prototype.
In general, data properties are usually set in the constructor to avoid any confusion about the two possible locations the property can reside and, if you're writing to them, there's really no advantage to having initially specified them on the prototype. Function properties (e.g. methods) are often set in the prototype because they generally aren't written to so it's more efficient to just have one shared prototype object that contains them that can be read from.