This question already has answers here:
Is there a good use case for the constructor property in Javascript?
(3 answers)
Closed 9 years ago.
In JavaScript, every function's prototype object has a non-enumerable property constructor which points to the function (EcmaScript §13.2). It is not used in any native functionality (e.g. instanceof checks only the prototype chain), however we are encouraged to adjust it when overwriting the prototype property of a function for inheritance:
SubClass.prototype = Object.create(SuperClass.prototype, {
constructor: {value:SubClass, writable:true, configurable:true}
});
But, do we (including me) do that only for clarity and neatness? Are there any real-world use cases that rely on the constructor property?
I can't really see why the constructor property is what it is in JS. I occasionally find myself using it to get to the prototypes of objects (like the Event object) in IE < 9. However I do think it's there to allow some ppl to mimic classical OO programming constructs:
function Foo()
{
this.name = 'Foo';
}
function Bar()
{
this.name = 'Bar';
}
function Foobar(){};
Foo.prototype = new Foobar;
Foo.prototype.constructor = Foo;
Bar.prototype = new Foobar;
Bar.prototype.constructor = Bar;
var foo = new Foo();
var bar = new Bar();
//so far the set-up
function pseudoOverload(obj)
{
if (!(obj instanceof Foobar))
{
throw new Error 'I only take subclasses of Foobar';
}
if (obj.constructor.name === 'Foo')
{
return new obj.constructor;//reference to constructor is quite handy
}
//do stuff with Bar instance
}
So AFAIK, the "advantages" of the constructor property are:
instantiating new objects from instance easily
being able to group your objects as being subclasses of a certain class, but still being able to check what particular type of subclass you're dealing with.
As you say: being tidy.
Whats my understanding constructor property is used to see whether a particular object is created or constructed by which functional constructor.
This is a great example for the same:
http://www.klauskomenda.com/code/javascript-inheritance-by-example/
Related
This question already has answers here:
Is there a good use case for the constructor property in Javascript?
(3 answers)
Closed 3 years ago.
As we know JavaScript has Prototypal inheritance instead of Classical one, which means every object
has a [[Prototype]] property which can be used for inheritance through prototype chain.
However one part of this prototypal inheritance model that i'm not able to understand is the logic behind default prototype property that a function (or a class) object gets initially. i.e.
//For classes
class Dog {}
Dog.prototype // {constructor: Dog}
//For functions
function Cat() {}
Cat.prototype // {constructor: Cat};
What's the possible use of having this property contain a constructor property pointing to function itself? I understand one usage that any object created will get the constructor property and can be used to created further objects if the definition is somehow lost (like this):
function Dog(name) {
this.name = name;
alert(name);
}
let dog = new Dog("White Dog");
let dog2 = new dog.constructor("Black Dog");
But this doesn't justify such setting which is quite complicated to be honest(because functions/classes are the only objects with such a circular reference to itself). Is there any other reasoning behind this decision?
(Updated to answer the actual question, see old answer below)
Is there any other reasoning behind this decision?
I can only guess, but it probably comes from the design of the languages that influenced javascript. In pure prototype-based programming, there are no constructors at all. There's only the prototype object itself to define a "class", and it would have an init method to be called on instances derived from it. A pseudo-language example:
dog = object create()
dog init = (name) {
this name = name
}
mydog = dog create()
mydog init("whitey")
Notice how mydog inherits from dog which inherits from object. The dog object has an init method, this is the natural link. A helper method new might bundle create and init together, to be called as mydog = dog new("blackey").
Now in JavaScript everything was made an object, even the functions/methods themselves. And to look more like Java (which was hip at the time), new was made an operator not an inherited method. For some reason, it was decided not to apply it to the prototype object, but to the constructor function instead - which was given a .prototype property for this. Maybe so that classes could be declared with a simple function? Or to enable inheritance by overwriting .prototype with a custom object? I do not know.
In any case, .constructor is the more natural one of the two circular properties. We could easily live without a .prototype:
// assuming builtins:
const object = Object.create(null)
object.create = function() { return Object.create(this) }
object.new = function() { const o = this.create(); o.constructor(); return o }
// we would use them as (assuming the object literal to inherit from `object`)
var Dog = {
constructor(name) { this.name = name },
woof() { alert(this.name + "makes: Woof!") }
}
var myDog = Dog.new("Whitey")
myDog.woof()
The power comes from the object being used as the [[prototype]] of all the instances being created with the new operator:
const mydog = new Dog("White Dog");
console.assert(Object.getPrototypeOf(mydog) === Dog.prototype)
This is the central object of your class, where all the shared methods live. The .constructor property among them is just a helpful (if rarely used) default. But you'd write
Dog.prototype.woof = function() {
alert(this.name + "makes: Woof!");
};
and the method would be available through inheritance as
dog.woof();
Using class syntax to define the methods leads to just the same Dog.prototype object.
I'm from Java/C# background, the traditional OOP language. it is really hard for me understand javascript world. Below is an example and my questions:
var o = new Object(123);
Q1- is the Object in new Object() actually a function like
function Object() {
...
}
Q2- if the answer to question 1 is yes then I'm confused with Object.prototype, that means prototype is a property for object function, so how can a function has its property? so how can we add a new property in a function like
function Object() {
...
prototype: ... //obviously this is not the right syntax
}
can any body provides me a skeleton code for this?
Q3- what I check console.log(typeof Object), the output is "function", since an function is also an object, so why the output is not "object"
Yes Object is a function in new Object(123).
Older version like ES5 class is written like this pattern
function MyClass () {
// .....
}
But in ES6 the original class keyword can be used like Java/C#
class MyClass
{
constructor() {
// ...
}
}
In JavaScript the prototype is used to inherit the class properties and this concept for the older version of ES6
According to MDN documentation the Object.Prototype is
Nearly all objects in JavaScript are instances of Object; a typical object inherits properties (including methods) from Object.prototype, although these properties may be shadowed (a.k.a. overridden). However, an Object may be deliberately created for which this is not true (e.g. by Object.create(null)), or it may be altered so that this is no longer true (e.g. with Object.setPrototypeOf).
Changes to the Object prototype object are seen by all objects through prototype chaining, unless the properties and methods subject to those changes are overridden further along the prototype chain. This provides a very powerful although potentially dangerous mechanism to override or extend object behavior.
Prototype Example:
Consider the following Employee class
function Employee()
{
this.organization = 'xyz';
}
If you want to add a function details property to that Employee class, then you can use prototype. Example:
Employee.prototype.details = function()
{
this.age = 26;
this.designation = 'Software Engineer';
// ....
}
Now, create the object of that Employee class
var emp = new Employee();
console.log(emp.organization, emp.age, emp.designation);
Notice that you can access age and designation what you are inherited using prototype.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm getting stuck because of less understanding of prototypal inheritance. I want to know what is prototypal inheritance exactly and how it is implemented.
Could you please show one ease example?
Any help is appreciated.
At its core
Imagine you have an object and you want to look up a property. Now imagine the property doesn't exist. What if you could make it automatically continue the search for that property on a different object? That's basically what prototypal inheritance is.
How do we do it?
So then the only question is how to create this relationship between objects. Well, that's the weird part.
I'll start with the main, historical way of doing it. That is using functions.
First thing to note is that a function in JavaScript is itself an object. It can have its own properties, and it uses prototypal inheritance to gain access to other properties.
So let's start by creating a function.
function Foo() {
// our function
}
So now we have a function named Foo. Our new function automatically gets a property named prototype when it's created. That property references an (almost) empty object.
console.log(typeof Foo.prototype); // object
Why does that property and object exist? Well, they exist to support the weird way that JavaScript has formed that relationship between objects that I described above.
Basically, the Foo.prototype object is what we're going to use as the "backup" object when looking for new properties on our objects. But we still haven't formed any special relationship between the object we want to use, and the Foo.prototype object.
Putting it to work
To do that, we actually invoke the function using the new operator.
var my_object = new Foo();
And there we go. So now my_object is a new, empty object. But it has in its "prototype chain" that object that is dangling from our Foo function off of its .prototype property. In other words, when we look for a property on my_object, if the property doesn't exist, it'll continue the search on the Foo.prototype object.
See it in action
Trouble is that we haven't added anything that we might find useful to Foo.prototype. But there actually is one property on that object. That property was also automatically created when we made our Foo function, and it's the .constructor property.
What does that property reference? It has a reference back to the Foo function. In other words:
Foo.prototype.constructor === Foo; // true
Alright, so if our my_object is empty, and if when looking for a property on my_object that doesn't exist, it continues the search on the Foo.prototype object, then that should mean that we should be able to automatically get to the Foo.prototype.constructor property from my_object.
my_object.constructor === Foo; // true
And it works. Since my_object didn't have a property named constructor, it continued its search on the object from which it inherits, which is Foo.prototype, which as we know, has a .constructor property that refers to the Foo function.
Customizing for our code
Super. But how do we set up other properties that are more useful to us in our code? We just add them to Foo.prototype. That will let our my_object find those properties if the object doesn't own them directly.
// give a custom property to `Foo.prototype`
Foo.prototype.bar = "foobar";
// see if we can access that property on your object
my_object.bar === "foobar"; // true
Sure enough, it worked. So let's see if we can create a new object from Foo that also has access to that .bar property.
var another_object = new Foo();
another_object.bar === "foobar"; // true
Again, it works. This is because all objects created by invoking Foo using the new keyword will have in their prototype chain the Foo.prototype object. In other words, Foo.prototype is shared among all instances created from Foo.
So if we now modify the Foo.prototype.bar property, it will be reflected in both objects we created.
Foo.prototype.bar = "raboof";
my_object.bar === "raboof"; // true
another_object.bar === "raboof"; // true
So we can see that both of our objects are simply looking for properties that they don't have by passing the search on to the next object in their "prototype chain", which is that weird object dangling off the Foo function... Foo.prototype.
There's more to learn
There are newer ways to set up this object relationship, but this is the original way, and in spite of its weirdness, should probably be understood first.
This is how I understand it:
This could be considered a constructor
var Thing = function(){
this.method1 = function(){
alert( "method 1" );
}
}
This is an instance of it
var a_thing = new Thing();
a_thing.method1();
Now, if you add something to the prototype of the constructor, it is automatically available to the already instantiated object.
Thing.prototype.method2 = function(){
alert( "method2" );
}
a_thing.method2();
Hope this helps.
This is the simplest example I can think of,
pizza class inherits from circle by using this line:
pizza.prototype = new circle();
Full example:
<html>
<head>
<script>
// base class
function circle(radius){
this.radius = radius;
this.getArea = function ()
{
return (this.radius * this.radius) * Math.PI;
};
this.foo = function ()
{
return "circle foo";
};
return true;
}
// child class
function pizza(flavour, radius){
circle.call(this, radius);
this.flavour = flavour;
this.foo = function ()
{
return "pizza foo";
};
return true;
}
// Inheritance
pizza.prototype = new circle();
function Go(){
// Instancing new object
var myCircle = new circle(8);
var myPizza = new pizza("Onion", 5);
// Calling property
var pizza_area = myPizza.getArea();
// Calling override foo function
var foo = myPizza.foo();
// Calling foo base class
var base = pizza.prototype.foo.call(myPizza);
//Line.prototype.someFunction.call(myLine);
var isBase = myCircle instanceof pizza;
isBase = myPizza instanceof pizza;
}
</script>
</head>
<body onload="Go();">
</body>
</html>
Is there any way whatsoever to enable an object to inherit from a prototype (1) without using new, and
(2) without using Object.create. (I had a suspicion that new is present inside the Object.create method, but after the Firebug console told me it's native code, well, I have a suspicion it goes native.) When I say "inherit from a prototype" I mean real JavaScript prototypical inheritance (i.e, not just an imitation of it). I know real inheritance when I see it (i.e., the __proto__ property is present, there is a circular reference between the constructor and the prototype, there is an inheritance hierarchy).
My question boils down to: even though 'we barely new ya', are the only two mechanisms for inheritance new and Object.create?
[...] are the only two mechanisms for inheritance new and Object.create?
Yes, they are. At least those are the only ones you should use.
You could directly assign to __proto__, but it is not a standard property yet. More info: MDN - __proto__.
As you might know new and Object.create do a hidden action than we can call setPrototype.
Object.create = function(proto, properties) {
var obj = {};
setPrototype(obj, proto);
Object.defineProperties(obj, properties);
return obj;
}
function fakeNew(Constructor) {
var obj = {};
setPrototype(obj, Constructor.prototype);
Constructor.call(obj);
return obj;
}
It's not than "new is inside Object.create" or "Object.create is inside new". Both does the prototype assignation and other actions.
Actually there is a way to implement setPrototype but surely you know it's not standard.
function setPrototype(obj, proto) {
obj.__proto__ = proto;
}
In order to avoid using the new operator, but still instantiate an object that inherits from a prototype (the prototype of SomeClass), a simple solution is to build a facade constructor function (which uses the new operator behind the scenes):
function SomeClassFacade() {
return new SomeClass();
}
SomeClass.prototype = {
/* ... */
};
Since ES6 you can also use Reflect.construct, which basically behaves like the new operator:
function Constructor() {}
var instance = Reflect.construct(Constructor, []);
Object.getPrototypeOf(instance); // Constructor.prototype
If you want something closer to Object.create, ES6 extending classes can also create inheritance, but only from constructors or null:
var obj = (class extends null{}).prototype;
delete obj.constructor;
Object.getPrototypeOf(obj); // null
function Constructor() {}
var obj = (class extends Constructor{}).prototype;
delete obj.constructor;
Object.getPrototypeOf(obj); // Constructor.prototype
I am unable to understand this loop behavior of the javascript.
Can someone tell me why was it designed in this way?
Is there any real use case of this behavior?
why this loop? {
Newly created instance inherits properties from the prototype property of the constructor function object.
prototype property of the constructor function is an object that keeps constructor property.
constructor property is equal to the constructor function object.
Again constructor function object keeps prototype property.
}
instance1---inhertis(keeps)-->Prototype property of func()-->keep constructor property-->function object func-->keep prototype property.
var func = function(){};
var construct = func.prototype.constructor;
console.log(construct === func); //true
var instance1 = new func();
Updated: Even if in between i assigned something else, instanceof always returns true.
var func1 = function(){};
func1.prototype.constructor = 1;
var instance1 = new func1();
console.log(instance1 instanceof func1); //true
var func2 = function(){};
func2.prototype.constructor = 0;
var instance2 = new func2();
console.log(instance2 instanceof func2); //true
Sorry to ask 2 question in 1 but both may be related.
Of course it retains the instance. Why wouldn't it? If you're making a duck, it's a duck - its DNA says that it's a duck, no matter if you paint it black or teach it to be a goose.
Also, in your case, setting the constructor has no effect. When you do new func (or new func(), which are identical), you go and grab an internal property of the function (the [[Construct]] property), and not func.prototype.constructor.
obj.constructor is defined on every single object, since it's defined on every "constructor": That is, Object Number Function Date Boolean String and so on. Each have a constructor property in their prototype:
Object.prototype.constructor === Object;
String.prototype.constructor === String;
//etc
Each one has its prototype.constructor pointing to itself.
Since functions can also behave like constructors, their .prototype.constructor property points to themselves as well. AFAIK, that's unused in the language itself.
The terse, technical answer? http://es5.github.com/#x11.8.6
//foo instanceof bar
Return the result of calling the [[HasInstance]] internal method of bar with argument foo.
(slightly paraphrased)
Basically, you're asking mother-duck: "Excuse me ma'am, is this your child?" The child has little say in the matter.
Edit: As mentioned in the comments, changing the prototype does indeed affect the instanceof results. Like above, there's the intuitive answer and the technical answer.
Intuitive answer is simple: The prototype defines the object. Therefore, changing the prototype changes the DNA - you make the duck a goose, not by teaching it to be a goose, but by going to its DNA and changing it to a goose DNA.
The technicality is seeing what [[HasInstance]] does. (the other [[HasIntsance]] calls this one) The spec is really dry and terse, so here's the algorithm written in pseudo-javascript:
//assume Func is the function we're talking about
function HasInstance ( value ) {
if ( IsntAnObject(value) ) {
return false;
}
var proto = Func.prototype;
if ( Type(proto) !== "Object" ) {
return false;
}
while ( value !== null ) {
value = value.prototype;
if ( value === proto ) {
return true;
}
}
return false;
}
As can be seen, by changing the prototype, we're changing the behavior - value will be different values.
Very nice question!
Since prototypes are Object instances (as everything in JavaScript is), they have to share Object's prototype. Which happens to have the constructor property.
Instances share all properties of their constructor prototypes, including the constructor property.
The constructor property of a function's prototype is specified to reflect the function itself. For example:
Object.prototype.constructor === Object
Function.prototype.constructor === Function
/* the same with every other function */
When you overwrite a constructor function's prototype, like this:
Func.prototype = 1
The prototype itself and all instances of Func have a different constructor property, in the case above – Number.
As for the instanceof, it has nothing to do with the constructor property per se. It has to do with the prototype.
function Func() {}
Func.prototype = { a: 1 } // assign a prototype
var fn = new Func() // create an instance
fn instanceof Func // true (reflects connexion to the original prototype)
Func.prototype = { b: 2 } // assign a completely different prototype
fn instanceof Func // false (the connexion is broken)
Below little code might clear up your confusion. As you can see the new instance actually does not have its own property called "constructor". So when you are asking for instance.constructor, you are actually getting instance.prototype.constructor value due to prototype chaining. To be consistent you want to see instance.constructor set to same value as the function that created it. This is why JS interpreter sets prototype.constructor to the value of the function itself.
function Rabbit() { }
var rabbit = new Rabbit()
alert( rabbit.hasOwnProperty('constructor') ) // false
alert( Rabbit.prototype.hasOwnProperty('constructor') ) // true
This works same for non-function objects. They don't have their own .constructor property and so the call ultimately ends up in Object.prototype.constructor and hence you get same answer for all non-function objects.
A question to ask at this point is why JS designer made this choice for function objects instead of explicitly setting constructor property of instance to function itself. I don't know the answer but I can guess that it adds more "dynamism" in the language. The instance.constructor can be used to create a new instance in generic way even if you don't have the original function that created the instance.
function makeUnicorn(animal) {
var unicorn = new animal.constructor();
unicorn.HornOnNose = true;
return unicorn;
}
var unicornRabbit = makeUnicorn(rabbit);
Notice that above runs without error for any object, even ones that are not an instance of function. You can conceivably use this JavaScript feature to customize behavior of above "generic" function which you otherwise couldn't if constructor was an own property of the instance.
Horse.prototype.constructor = function() {
var newHorse = new Horse();
newHorse.Color = "White";
return newHorse;
}