Odd javascript behavior for checking "constructor" key in object - javascript

I am actually not sure if I just stumbled upon an unwanted behavior in javascript or if this is somehow intended behavior.
The following code results in a true statement:
var test= {"test":1}
document.write("constructor" in test);
http://jsfiddle.net/xyatxm2g/2/
If I change it to the following code, it returns false as it should:
var test= {"test":1}
document.write(test.hasOwnProperty("constructor"));
http://jsfiddle.net/fg06ovvc/2/

The hasOwnProperty method, as the name says, look into the object to see if it has the property itself.
But when you use 'propertyName' in test, you're not only looking into the object's own properties, but also the properties that come from inheritance.
In that case, constructor is a property that resides inside the Object's prototype, so all objects have that property, because they all inherit from Object.
Quote from MDN
Every object descended from Object inherits the hasOwnProperty method.
This method can be used to determine whether an object has the
specified property as a direct property of that object; unlike the in
operator, this method does not check down the object's prototype
chain.

From the MDN documentation:
Inherited properties
The in operator returns true for properties in the prototype chain.
"toString" in {}; // returns true
Whereas the hasOwnProperty() method only checks for properties directly on the object, not inherited (i.e. not on the prototype chain).

Following MDN documentation, it is not an enumerable field.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable
You can perform following test:
var obj = {"t": 23};
obj.propertyIsEnumerable("t")
results: true
obj.propertyIsEnumerable("constructor")
results: false
There is a complete example on this document, under section:
Direct versus inherited properties

I think it may be normal behaviour here that the key in object operator is searching through the prototype chain and returning true for Object.prototype.constructor. See this discussion - it goes over a related topic.
How do I check if an object has a property in JavaScript?

Related

Difference between __proto__ and [[prototype]] in Global-Object?

In Browser there are some Global-Objects pre-built (Objects, String, Number, Date, etc). Mother of all such global-objects is "Object". As, this Object is the prototype of nearly all of the data-types present in JS (except only 2 - null and undefined).
Now, we move up after creating any variable of any data-type, we'll use __proto__ to climb up the chain. But, when we react the "Object", the __proto__ points to null and "prototype-chain" has an ending!
Till now I thought prototype and __proto__ are one and the same.
Today, I went and found, that in the Global-Object, while __proto__ points to null,[[prototype]] (inside get proto & set proto) consists of heaps of other values.
Can someone differentiate to me, what exactly is the difference between __proto__ and [[prototype]] and why the values inside both are completely different? While I thought both things are 1 and the same!
I also read this: Difference between __proto__ and [[ Prototype ]] in javascript but got more confused as it says __proto__ === [[prototype]] but then says something of internal-slot? Now, can I get a simple clear answer?
Also, if the __proto__ is null, how then get __proto__ fetch any result? --isn't this absurd? It will fetch result, only if the any value is there, and not null.
In the screenshot you shared, you compare two things that are unrelated.
The first box shows the value you get from accessing __proto__. It is indeed null. But realise that this value is retrieved by calling the getter. __proto__ is not a plain property, it is implemented using a getter and setter. This means that when you write:
var a = x.__proto__;
... a function is called. This is the get __proto__ function. This function is a method that is defined in the prototype chain of x (it is actually defined on Object.prototype).
Similarly if you write:
x.__proto__ = a;
...a function is called. This is the set __proto__ function.
The second box in your screenshot shows the properties of this set __proto__ function object. Remember that functions are objects too. And that object has little to do with the main object of your screenshot.
You can also access the definitions of these getter and setter functions with the following script:
let descriptor = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
console.log(descriptor);
In a comment you've said:
I think now there are 3 items - Array.prototype, Array.__proto__, and [[prototype]]. I thought all 3 were just the same.
([[Prototype]] is usually capitalized.)
That's the fundamental misunderstanding (that and looking at the wrong part of the console output; more below). They aren't. Here's what they are:
[[Prototype]] is the name of the internal field of an object that says what that object's prototype is.
__proto__ is an accessor property defined by Object.prototype that exposes the [[Prototype]] internal field. As I've told you before, it's deprecated. Use Object.getPrototypeOf and (if you can't avoid it) Object.setPrototypeOf.
SomeConstructorFunction.prototype is a property on SomeConstructorFunction that refers to an object. If you create an object via new SomeConstructorFunction (or an equivalent operation), the object that SomeConstructorFunction.prototype refers to is set as the [[Prototype]] of the new object.
See also the answers to this question.
In Browser there are some Global-Objects pre-built (Objects, String, Number, Date, etc). Mother of all such global-objects is "Object". As, this Object is the prototype of nearly all of the data-types present in JS (except only 2 - null and undefined).
No, Object is a function. Object.prototype is the mother of all objects — except the ones it isn't, because it's possible for an object not to inherit from it (or indeed, from anything). Object.create(null) creates an object with no prototype object.
Can someone differentiate to me, what exactly is the difference between __proto__ and [[prototype]] and why the values inside both are completely different?
They aren't (but keep reading). In the picture you've shown, you're looking at [[Prototype]] on a function, the setter of the __proto__ accessor property. You're not looking at [[Prototype]] on the same thing you're looking at __proto__ on.
In your picture you're basically looking at Object.prototype (because you're looking at __proto__ on the result of new Object). Chrome's devtools don't show the [[Prototype]] internal field of Object.prototype (surprisingly), but it they did it would be null per specification.
Let's instead look at a simple object:
> const obj1 = {example: "x"};
<- undefined
> obj1
<- {example: 'x'}
example: "x"
[[Prototype]]: Object
> Object.getPrototypeOf(obj1) === Object.prototype
<- true
> Object.getPrototypeOf(obj1) === obj1.__proto__
<- true
> obj1.prototype
<- undefined
(One part of that which could be confusing is where is says [[Prototype]]: Object. The devtools show the name of the constructor for an object. The [[Prototype]] of the object is the object referenced by Object.prototype, not the Object constructor itself.)

Why does __proto__ not update when prototype is set to null [duplicate]

Why is it that setting the prototype property of a constructor function to null does not prevent objects created from that function from calling through to methods on Object.prototype, in the same way that setting the prototype to Object.create(null) does?
That is, why is this the case:
function Foo(){}
Foo.prototype = null;
console.log(new Foo().toString); //outputs function toString() { [native code] } (or whatever)
function Foo(){}
Foo.prototype = Object.create(null);
console.log(new Foo().toString); //output undefined
In short
Yes, your observation is correct - a function constructed with the new operator will always have an object prototype in this case Object.prototype and this is indeed unlike a function created with Object.create.
On why
One can see this behavior completely specified in the ES5 language specification on which JavaScript is based on. Let's see this.
In new:
Quoting the specification of the [[Construct]] method of functions that indicates how object creation using the new operator is performed we can see that the following is specified:
If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.
In Object.create:
On the other hand, if we check out The spec for Object.create we can see that Object.create(o) specifies:
Set the [[Prototype]] internal property of obj to O.
Which means we can set it, it also explicitly checks that it is null or Object in that algorithm (please do follow the link to the spec and read it :))
So the prototype of the objects called with new Foo is Object.prototype and not null. It is impossible to create objects with no prototype without Object.create using standard methods only.

why typeof(Function.prototype) is function

I am aware of the fact that Prototypes are object literal. So methods and properties can be defined on them. Function.prototype has some method like apply, call, bind, toString etc. So I thought a function's prototype should be a object literal. But I ran following code and encountered that Function.prototype is of type function !
console.log(typeof(Function.prototype)); // function
How come it is not a object literal itself ?
From the specification:
The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.
NOTE
The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.
(my emphasis)
If we go to the ES5 spec, it says:
The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
...without offering any explanation for why that would be the case. That language is essentially unchanged in ES1, ES2, ES3, and ES5. I think the original idea was basically that that was what gave it its function-ness, although typeof (even in ES1) didn't look at the internal [[Class]], it looked at whether the thing implemented [[Call]] (as it still does). When something goes back all the way to ES1, one frequently has to just invoke the "because Eich did the first JavaScript in 10 days and yeah, weird stuff happens when you do that" argument. :-)
Side note: By "object literal" I take it you mean "plain object." (An "object literal" — what the specifiation calls an object initializer — is just a way to write an object in source code. There are other ways to create plain objects.)
An object literal is some JavaScript syntax for creating objects. It isn't a data type.
Functions are just a specific type of object in JavaScript. Anywhere you can have an object, you can have a function.
Let's say you have declared an array,
let arr = [ 1 , 2 ];
So, internally it will be created as
let arr = new Array ( 1, 2 );
This is the function constructor.
Have you ever thought about how the array got all functions like concate, map, filter, reduce etc.?
Internally when we create an instance from a function constructor, the prototype property of a function will be set to the prototype property of that newly created instance. Hense, this concate, map, filter, reduce get automatically associated with that function constructor. So that's how we can use that array properties by arr.map, arr.concate.
Actually the prototype property of a function is visible but the prototype property of an instance which is created by a function constructor is hidden. If you want to check then you can check it by obj_name.proto. It's a pointer towards that prototype property.
Now, you can see that the array "arr" is not the array internally. It's an instance of a function constructor. That's why if you check the type of the array, you will get the answer as object and also if you check the typeof(Array), you will get the answer as Function.
If you find it useful then please like it on
https://www.linkedin.com/posts/sh-jay_javascript-array-prototype-activity-6951547190049677312-Dqbn?utm_source=linkedin_share&utm_medium=member_desktop_web
Well, I don't think you mean object literal, as alluded to by other answers and comments.
alert(Function.prototype instanceof Object) // true
alert(Function.prototype instanceof Function) // true
alert(typeof Function.prototype) // function
It is an object. It's also a function. Also, all functions are objects. They're all following the rules just fine.
alert((function(){}) instanceof Object) // true
alert((function(){}) instanceof Function) // true
alert(typeof (function(){})) // function
One big happy we-all-derive-from-Object family. Why should the prototype of Function not be a function?
Now if you wanna get weird... let's get weird.
var notAFn = Object.create(Function.prototype);
alert(notAFn instanceof Function); // true
alert(typeof notAFn); // object
And no, you can't call notAFn(). Not until they add a call Symbol for that. :)
Oh hey, feel free to tell me why this isn't a good answer. I'll try to improve it.

Confusion regarding javascript prototype explanation defined in Mozilla developer network

I have read about javascript prototype and read some stackoverflow question as well like how-does-javascript-prototype-work and I was finally understanding prototype properly but then as I was going through documentation on Mozilla Developer Netork (MDN) regarding prototype under this
Details_of_the_Object_Model MDN
Under that there is a note
Note: Directly assigning to FunctionName.prototype removes its original prototype's "constructor" property. As a result, (new WorkerBee).constructor yields "Employee" (instead of expected "WorkerBee"). Care must be taken to preserve the original prototype's constructor. For instance, assign the parent to FunctionName.prototype.__proto__ instead. For example, WorkerBee.prototype.__proto__ = new Employee; This way, (new WorkerBee).constructor yields expected "WorkerBee".
I can't seem to understand what this statement mean
Directly assigning to FunctionName.prototype removes its original prototype's "constructor" property.
Does it mean that Manager.prototype = new Employee will replace Manager.__proto__ = Function.prototype to Employee.prototype?
As a result, (new WorkerBee).constructor yields "Employee" (instead of expected "WorkerBee")
What does it mean that it will yield Employee? I know we should not directly use __proto__ but the above statement specify to use FunctionName.prototype.__proto__. In which case this is true?
Can someone explain with example what does it try to convey?
Prototype on functions are used as proto for objects generated by these functions.
A functions proto points to Function.prototype since a function is also an object instance by itself. Setting it's proto does not affect it's prototype but re setting it's prototype does affect the prototype. constructor
You should not set Child.prototype to an instance of Parent, use Object.create instead.
What prototype.constructor is and more is explained here: Prototypical inheritance - writing up

How does __proto__ differ from constructor.prototype?

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!

Categories

Resources