Confused on Prototype inheritance Javascript - javascript

I found this picture here
In this case, foo is a constructor function and B and C are objects. I am very confused, first off when you create an object does it always come with the properties and proto? Is that the default? Also in terms of the constructor function for foo. Am I correct to say that every proto of a function defaults to Function.prototype, which uses Object.prototype to create an object? The part that is confusing for me is Foo.prototype, when was this prototype created? Does a constructor function always default to the creation of a prototype which a constructor reference set back to itself and a proto set to object?

No wonder there is confusion. The picture is misleading to the point of being incorrect!
Objects created by calling a constructor function with the new keyword have their inheritance chain set to start with the prototype property of the constructor (correct in the picture).
The prototype property is created every time a function is declared using the function keyword to cover the case of the function being use as a constructor later - so you don't need to specify if a function is a constructor or not. For completeness, functions generated by the class keyword also have a prototype property.)
The function's prototype property's constructor property is set to the function when the prototype property is created (meaning when the function is declared). Again the picture is correct: the value of Foo.prototype.constructor is a reference to Foo.
What is wrong in the picture is objects a and b somehow joining together in a reverse fork and their properties becoming available to instances of Foo.
constructor is always an inherited property. If you replace the original prototype property of a function object with another object, you replace the constructor property inherited by objects constructed with the function. Although you can reset the constructor property of a functions prototype property, it's reasonably unusual and not a part of the story the picture is presenting.
If you do modify the inheritance chain by changing a function's prototype property value, the inheritance chain is still always a single threaded chain back to Object.prototype and then null. The inheritance chain never forks as shown in the picture. If you modified Foo.prototype in the picture to make it a or b, the constructor property of Foo instances would not be Foo.
The picture requires a lot of explanation to be useful.

The properties are assigned in the construction function. Any function can be used with new,thus becoming the "construction function".
var f = function(){};
var fInstance = new f();
console.log(fInstance.constructor); // *f*
If there are no properties assigned in that function (using this.propertyName), then the constructed instance will not have properties. If it does, then it will.
// No properties
var f = function(){};
// Two constructor properties, and one default property
var f = function(prop1, prop2){
this.name = prop1;
this.description = prop2;
this.something = "default";
};
If the prototype of the construction function has properties or methods (basically just glorified properties) attached to its prototype, then each instance will have those.
// No prototype
var f = function(){};
// Prototype with one method
var f = function(){};
f.prototype.test = function(){ console.log("hello"); };
The prototypes and properties must be manually created, and may or may not exist. By default, since using new requires a function, there will always be a constructor function. The process of instantiation using new will also always assign the prototype of the constructor to an object containing the constructing function as a property named constructor as well as all of the properties/methods of the construction function's prototype.

In this case, foo is a constructor function and B and C are objects.
Functions are also objects. Everything are objects. unlike classical inheritance where what defined objects are separate entities. Here an object that is an instance of Function is the constructor that will create an instance of its kind that inherits whatever object is on the constructors prototype attribute.
I am very confused, first off when you create an object does it
always come with the properties and proto? Is that the default?
Only way to get the objects own property y is if the constructor function sets this.y. If a property is not found on the object the system will continue to look at the object that was on the constructors prototype field. Some implementations has this as __proto__ but that is not a requirement. It is implementation specific how it is stored on the instance.
Also in terms of the constructor function for foo. Am I correct to say
that every proto of a function defaults to Function.prototype, which
uses Object.prototype to create an object?
function() {...} makes an instance of the constructor Function. All objects except Object itself inherits Object either indirectly or directly, including Function. Basically you can make a function like this:
var f = new Function('a', 'b', 'return a + b');
f is an instance of Function, as you can see. This is almost the same as:
var f = function(a, b) { return a + b; };
Now the first allows for text to be interpreted as code so its less efficient, but I imagine that in the early days these two would be identical in terms of interpretation. Modern engines prefer the last one since it is more predictable while the first can be seen as a specialized eval.
The part that is confusing for me is Foo.prototype, when was this
prototype created? Does a constructor function always default to the
creation of a prototype which a constructor reference set back to
itself and a proto set to object?
Yes. When the function Foo is created, JS creates by default protoype as new Object(), then it sets constructor to itself. The rest needs to be done in the code itself so we know there is something like this after the actual function code to do the rest of the class:
Foo.prototype.x = 10;
Foo.prototype.calculate = function(...) {...};

Related

Why can't I set the 'prototype' of a function created using 'bind'?

Consider this code:
function foo(something) {
this.a = something;
}
var obj1 = {};
var bar = foo.bind(obj1);
Now the following statement doesn't execute:
bar.prototype.newprop = "new"; // Cannot execute this
As I understood, every function has a prototype object. Then why can't we execute the above statement?
And bar is indeed a function as we can call it:
bar(2);
console.log(obj1.a); // 2
As I understood, every function has a prototype object.
Well, there are exceptions to every rule :-) You found one: bound functions don't have a .prototype property because they don't need it. When you call a bound function with new, it calls the original function as a constructor, using the original's .prototype object as the prototype of the new instance.
In fact, since ECMAScript 6 many functions don't have a .prototype property with an object, because they are not constructors - they cannot be called with new so they don't need it. Among those are
arrow functions (() => {…})
methods (method() { … } in object literals and classes)
builtin non-constructor functions (like Math.sin)
See the specification:
Function.prototype.bind ( thisArg , ...args)
[...]
NOTE 1 Function objects created using Function.prototype.bind are exotic objects. They also do not have a prototype property.
The returned function from .bind() has no prototype object. You can give it one:
bar.prototype = { newprop: "new" };
It is not true that "every function has a prototype object". Every function can have a prototype object, but the value of the "prototype" property can be anything, including null or undefined.
Additionally, there are "special" functions that may not behave like ordinary functions in all cases.
Adding properties to the prototype means you want to create an object by using the function as a constructor.
When you create an object like by calling new on a function, the this value is the new object being created. So it makes no sense to bind this to another value.

Why the prototype of instance is not the same like the prototype of its constructor if to use the `Object.getPrototypeOf()` function?

Why the prototype of instance is not the same like the prototype of its constructor if to use the Object.getPrototypeOf() function?
function A(n){this.n=n;};
let a = new A(1);
console.log('Object.getPrototypeOf(a) == Object.getPrototypeOf(A); // ',
Object.getPrototypeOf(a) == Object.getPrototypeOf(A));
console.log('Object.getPrototypeOf(a) == A.prototype; // ',
Object.getPrototypeOf(a) == A.prototype);
Object.getPrototypeOf() returns the value of the internal [[Prototype]] property, which is not the same as the prototype property. When you create a function (or a class), it gets a prototype property, and when you create an instance of it, the created object has the internal [[Prototype]] property set to the prototype property of the class.
Your first example evaluates to false, because [[Prototype]] of a is A.prototype, but [[Prototype]] of A is Function.prototype, because every function is an instance of the Function class.
You are seeing this because A's prototype (the prototype object from which A is derived) is Function.prototype, not A.prototype:
function A(n){this.n=n;};
console.log('Object.getPrototypeOf(A) === Function.prototype');
console.log(Object.getPrototypeOf(A) === Function.prototype);
let a = new A(1);
console.log('Object.getPrototypeOf(a) === A.prototype');
console.log(Object.getPrototypeOf(a) === A.prototype);
Object.getPrototypeOf(x) is not just a convoluted way of writing x.prototype.
Object.getPrototypeOf(x) returns the prototype from which x is derived.
x.prototype is the prototype of objects created using x as a constructor.
Although it seems simple at a glance but the answer will become more clear if you know how protoypal inheritance works in JS.
Still I would try to explain it in short, how prototype works.
In JS, everything is an object. Although primitive values such as numbers, strings, boolean do not look like objects but are treated like objects internally.
For a quick reference see below. Everything is an object.
Now lets come to the case mentioned in question. Whenever you create anything in JS, it uses some existing prototype. It depends on what kind of item you are creating.
The below line is basically doing a lot of things in background. It is creating a function with name as 'A'. While doing so the JS engine uses an already existing special object in the browser called Function.prototype. This contains the basic characteristics of any function that you are creating. Then it creates a brand new object that has only two properties by default: constructor and a link to the default object prototype(referenced by proto). And then assign the new function definition that you have written to this newly created function.
function A(n){this.n=n;};
Hence we have two prototypes to understand here:
Function.prototype
A.prototype
Function.prototype would give that existing object we discussed above which is provided by the engine to create new functions.
A.prototype is the new object that gets created when A is declared. Note that we haven't yet used our new function A to create objects.
While running the below code, JS engine creates a new object which would inherit properties from A.prototype, runs the function definition which is stored in A(this.n = n etc..) and returns the newly created object.
let a = new A(1);
To summarize
a is an object that inherits from A.prototype
A is a function(a special object) that inherits from Function.prototype
I think now it should be clear what the below code means.
Object.getPrototypeOf(a) === A.prototype // true
Object.getPrototypeOf(A) === Function.prototype //true

What's the difference between these 2 implementations of prototypal inheritance?

What's the difference between these 2 implementations of prototypal inheritance, and considering that we're working with 2 different "prototypes" (the prototype property that's only on functions, and the internal prototype), and how do these implementations differ in their prototype chain lookup? Also, does the first implementation (using the prototype property) rely on our use of the new operator?
Assigning to a functions's prototype property and using the new operator:
function foo() {}
foo.prototype.output = function(){
console.log('inherits from Function.prototype property');
};
bar = new foo();
bar.output();
Storing a function in an object literal and using the Object.create() method:
var foo = {
output: function(){
console.log('inherits from the internal prototype');
}
};
var bar = Object.create(foo);
bar.output();
The main difference is in the way it is used, and the dangers associated.
The first one forces you to use new when you want to create a new object. The syntax is fairly ugly (SomeConstructor.prototype.method), and it bears one major flaw: calling a constructor which adds properties (this.name = nameParam...) without new will apply the construction to the global object. The behaviour of the constructor is weird (create new object which delegates to SomeConstructor.prototype, then apply the constructor to the new object, then if the constructor returns something replace the object by the something). Plus, in your example, foo itself is not usable, you have to create a new object in order to access its functionalities.
The second one, Object.create, doesn't force you to use any syntoxic quirk. You don't have the global pollution risk. The object foo has functionalities that can already be used without creating a new object, and bar will simply borrow these functionalities. This kind of pattern can also make it easier to implement factories (without news to replace everywhere) and object pools if needed.
Eric Eliott talks about it very well, and Kyle Simpson wrote a whole book about prototype delegation!
Now, here's how the lookup happens:
With the constructor, the lookup is done on Constructor.prototype (not the actual internal prototype of the constructor, but its prototypeproperty. If you find it confusing, congratulations, you are human). Additional properties are set in the constructor function. foo itself is not used for the lookup, foo.prototype (again, not the same as foo.__proto__ which points to Function) is the one used for it.
With Object.create the lookup is done on the object itself (foo). There's no prototype non-prototype property on the object.
There's very funny diagrams on this page of Kyle Simpson's book which explain the thing further.
More on new in this question: Is JavaScript's "new" keyword considered harmful?
OK, first of all, in case you didn't know, Object.create is based upon the following pattern proposed by Douglas Crockford (read more here):
function create (proto) {
function f () {}
f.prototype = proto;
return new f();
}
Now, you must be aware that the above code does not yield the same result in case you pass null as parameter.
The ECMAScript algorithm for creating new objects (read more here) states that if the prototype of a function is set to null (or any non object), when you're trying to use new f() syntax, the newly created object will inherit from Object.prototype.
If you use Object.create(null), the newly created object will have its [[Prototype]] internal member set to null, which means the prototype chain will stop there (your object doesn't get hasOwnProperty and other stuff from Object.prototype as normal object would).
var o1 = create(null);
var o2 = Object.create(null);
Object.getPrototypeOf(o1) === Object.prototype // true
Object.getPrototypeOf(o2) === Object.prototype // false
Object.getPrototypeOf(o2) === null // true
The first example - foo, is a function.
The second example - foo is an object.
in the second example, bar becomes an new instance without a constructor.
See - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create, to add the constructor.
As a side note, it common best practice that constructors should begin with a capital letter.

When is the `.constructor` property of an object actually used

I've been using code like this for inheriting from another object:
// define base object constructor
function SuperType(){
// constructor code
}
// define base object methods on the prototype
SuperType.prototype.foo = function() {};
// ---------------------------------------------------------------------------
// define object that wants to inherit from the SuperType object
function SubType() {
// call base object constructor with all arguments that might have been passed
SuperType.apply(this, arguments);
// other constructor code
}
// set prototype for this object to point to base object
// so we inherit any items set on the base object's prototype
SubType.prototype = new SuperType();
// reset constructor to point to this object not to SuperType
SubType.prototype.constructor = SubType;
// define any methods of this object by adding them to the prototype
SubType.prototype.myMethod = function() {};
My question is why do you have to set the SubType.constructor = SubType? When is the .constructor property actually used? If you create a SubType object like this:
var s = new SubType();
That's going to call the SubType() constructor regardless of what SubType.prototype.constructor is actually set to, so I'm trying to understand when the .constructor property is ever actually used?
As you can see in this jsFiddle demo with the assignment to .constructor commented out, the proper constructor is still called. So, it appears that the .constructor property is not used in normal construction with the new operator. I'm wondering when it is used?
According to the The ECMAScript Language Specification,
The initial value of Object.prototype.constructor is the standard built-in Object constructor.
In other words, it's just a pointer to the Object's actual, native constructor-- The one that is called via new Object(). Thus, you can override it without changing anything about how new Object() works.
So why does it exist? Because constructor functions are effectively classes in JavaScript, it lets you do certain things with class instances without needing to their class name. To borrow from Axel Rauschmayer's blog, the constructor property allows:
Comparing between classes, i.e. a.constructor === b.constructor
Creating a new instance from an existing instance, i.e. new a.constructor()
Invoking another (super)class's constructor
All without any hardcoded references to class names. Again, it's not really meant to be overridden. To echo the above comments, I've never really seen someone override it in the wild.

Prototype or inline, what is the difference?

I am just learning Javascript and I was wondering, is using the prototype declaration, like this:
function TSomeObj()
{
this.name="my object";
}
TSomeObj.prototype.showname = function() {
alert(this.name);
}
Basically the same as doing it like this:
function TSomeObj()
{
this.name="my object";
this.showname = function() {
alert(this.name);
}
}
When I dump the object's properties I get the same result:
TSomeObj (inline version) =
{
'name': 'my object',
'test': function
}
TSomeObj (prototype declaration) =
{
'name': 'my object',
'test': function
}
What exactly is the benefit of using prototype declarations? Except less cluttering and more orderly sourcecode perhaps.
Update: I should perhaps have made it more clear that it was the final result i was curious about. The end result is ofcourse the same (i.e both register a new function in the object prototype) - but the way they do it is wildly different. Thank you for all replies and info!
Note: This answer is accurate but does not fully reflect the new way to create classes in JavaScript using the ES6 class Thing {} syntax. Everything here does in fact apply to ES6 classes, but might take some translation.
I initially answered the wrong question. Here is the answer to your actually-asked question. I'll leave my other notes in just in case they're helpful to someone.
Adding properties to an object in the constructor function through this.prop is different from doing so outside through Object.prototype.prop.
The most important difference is that when you add a property to the prototype of a function and instantiate a new object from it, that property is accessed in the new object by stepping up the inheritance chain rather than it being directly on the object.
var baseobj = {};
function ObjType1() {
this.prop = 2;
}
function ObjType2() {}
ObjType1.prototype = baseobj;
ObjType2.prototype = baseobj; // these now have the *same* prototype object.
ObjType1.prototype.prop = 1;
// identical to `baseobj.prop = 1` -- we're modifying the prototype
var a = new ObjType1(),
b = new ObjType2();
//a.hasOwnProperty('prop') : true
//b.hasOwnProperty('prop') : false -- it has no local property "prop"
//a: { prop = 2 }, b : { prop = 1 } -- b's "prop" comes from the inheritance chain
baseobj.prop = 3;
//b's value changed because we changed the prototype
//a: { prop = 2 }, b : { prop = 3 }
delete a.prop;
//a is now reflecting the prototype's "prop" instead of its own:
//a: { prop = 3 }, b : { prop = 3 }
A second difference is that adding properties to a prototype occurs once when that code executes, but adding properties to the object inside the constructor occurs each time a new object is created. This means using the prototype performs better and uses less memory, because no new storage is required until you set that same property on the leaf/proximate object.
Another difference is that internally-added functions have access to private variables and functions (those declared in the constructor with var, const, or let), and prototype-based or externally-added functions do not, simply because they have the wrong scope:
function Obj(initialx, initialy) {
var x = initialx,
y = initialy;
this.getX = function() {
return x;
}
var twoX = function() { // mostly identical to `function twoX() { ... }`
return x * 2;
}
this.getTwoX = function() {
return twoX();
}
}
Obj.prototype.getY = function() {
return y; // fails, even if you try `this.y`
}
Obj.prototype.twoY = function() {
return y * 2; // fails
}
Obj.prototype.getTwoY = function() {
return twoY(); // fails
}
var obj = new Obj();
// obj.y : fails, you can't access "y", it is internal
// obj.twoX() : fails, you can't access "twoX", it is internal
// obj.getTwoX() : works, it is "public" but has access to the twoX function
General notes about JavaScript objects, functions, and inheritance
All non-string and non-scalar variables in JavaScript are objects. (And some primitive types undergo boxing when a method is used on them such as true.toString() or 1.2.valueOf()). They all act somewhat like a hash/dictionary in that they have an unlimited(?) number of key/value pairs that can be assigned to them. The current list of primitives in JavaScript is: string, number, bigint, boolean, undefined, symbol, null.
Each object has an inheritance chain of "prototypes" that go all the way up to the base object. When you access a property of an object, if that property doesn't exist on the object itself, then the secret prototype of that object is checked, and if not present then that object's prototype, so on and so forth all the way up. Some browsers expose this prototype through the property __proto__. The more modern way to get the prototype of an object is Object.getPrototypeOf(obj). Regular objects don't have a prototype property because this property is for functions, to store the object that will be the prototype of any new objects created using that function as their constructor.
A JavaScript function is a special case of an object, that in addition to having the key/value pairs of an object also has parameters and a series of statements that are executed in order.
Every time a function object is invoked it is paired with another object that is accessed from within the function by the keyword this. Usually, the this object is the one that the function is a property of. For example, ''.replace() boxes the string literal to a String, then inside the replace function, this refers to that object. another example is when a function is attached to a DOM element (perhaps an onclick function on a button), then this refers to the DOM element. You can manually choose the paired this object dynamically using apply or call.
When a JavaScript function is invoked with the new keyword as in var obj = new Obj(), this causes a special thing to happen. If you don't specifically return anything, then instead of obj now containing the return value of the Obj function, it contains the this object that was paired with the function at invocation time, which will be a new empty object with the first parent in its inheritance chain set to Obj.prototype. The invoked Obj() function, while running, can modify the properties of the new object. Then that object is returned.
You don't have to worry much about the keyword constructor, just suffice it to say that obj.constructor points to the Obj function (so you can find the thing that created it), but you'll probably not need to use this for most things.
Back to your question. To understand the difference between modifying the properties of an object from within the constructor and modifying its prototype, try this:
var baseobj = {prop1: 'x'};
function TSomeObj() {
this.prop2 = 'y';
};
TSomeObj.prototype = baseobj;
var a = new TSomeObj();
//now dump the properties of `a`
a.prop1 = 'z';
baseobj.prop1 = 'w';
baseobj.prop2 = 'q';
//dump properties of `a` again
delete a.prop1;
//dump properties of `a` again
You'll see that setting a.prop1 is actually creating a new property of the proximate object, but it doesn't overwrite the base object's prop1. When you remove prop1 from a then you get the inherited prop1 that we changed. Also, even though we added prop2 after a was created, a still has that property. This is because javascript uses prototype inheritance rather than classic inheritance. When you modify the prototype of TSomeObj you also modify all its previously-instantiated objects because they are actively inheriting from it.
When you instantiate a class in any programing language, the new object takes on the properties of its "constructor" class (which we usually think of as synonymous with the object). And in most programming languages, you can't change the properties or methods of the class or the instantiated object, except by stopping your program and changing the class declaration.
Javascript, though, lets you modify the properties of objects and "classes" at run-time, and all instantiated objects of that type class are also modified unless they have their own properties that override the modification. Objects can beget objects which can beget objects, so this works in a chain all the way up to the base Object class. I put "classes" in quotes because there really isn't such a thing as a class in JavaScript (even in ES6, it's mostly syntactic sugar), except that the new keyword lets you make new objects with the inheritance chain hooked up for you, so we call them classes even though they're just the result of constructor functions being called with the new keyword.
Some other notes: functions have a Function constructor, objects have an Object constructor. The prototype of the Function constructor is (surprise, surprise) Object.
Inheriting from an object without the constructor function running
In some cases, it's useful to be able to create a new "instance of an object" without the constructor function running. You can inherit from a class without running the class's constructor function like so (almost like manually doing child.__proto__ = parent):
function inheritFrom(Class) {
function F() {};
F.prototype = Class.prototype;
return new F();
}
A better way to do this now is Object.setPrototypeOf().
The accepted answer missed the most important distinctions between prototypes and methods bound to a specific object, so I'm going to clarify
Prototype'd functions are only ever declared once. Functions attached using
this.method = function(){}
are redeclared again and again whenever you create an instance of the class. Prototypes are, thus, generally the preferred way to attach functions to a class since they use less memory since every instance of that class uses the same functions. As Erik pointed out, however, functions attached using prototypes vs attached to a specific object have a different scope, so prototypes don't have access to "private" variables defined in a function constructor.
As for what a prototype actually is, since it's an odd concept coming from traditional OO languages:
Whenever you create a new instance of a function:
var obj = new Foo();
the following logic is run (not literally this code, but something similar):
var inheritsFrom = Foo,
objectInstance = {};
objectInstance.__proto__ = inheritsFrom.prototype;
inheritsFrom.apply( objectInstance, arguments );
return objectInstance;
so:
A new object is created, {}, to represent the new instance of the function
The prototype of the function is copied to __proto__ of the new object. Note that this is a copy-by-reference, so Foo.prototype and objectInstance.__proto__ now refer to the same object and changes made in one can be seen in the other immediately.
The function is called with this new object being set as this in the function
and whenever you try to access a function or property, e.g.: obj.bar(), the following logic gets run:
if( obj.hasOwnProperty('bar') ) {
// use obj.bar
} else if( obj.__proto__ ){
var proto = obj.__proto__;
while(proto){
if( proto.hasOwnProperty('bar') ){
// use proto.bar;
}
proto = proto.__proto__;
}
}
in other words, the following are checked:
obj.bar
obj.__proto__.bar
obj.__proto__.__proto__.bar
obj.__proto__.__proto__.__proto__.bar
... etc
until __proto__ eventually equals null because you've reached the end of the prototype chain.
Many browsers actually expose __proto__ now, so you can inspect it in Firebug or the Console in Chrome/Safari. IE doesn't expose it (and may very well have a different name for the same thing internally).

Categories