Function _Proto_ vs Prototype - javascript

The picture below shows that a function has a proto and a prototype, I understand that a proto is an object that is used to look up the chain. Does a prototype contain the actual prototype? Is that the distinction? Also the object A and B in this picture don't have a prototype property but I assume that if you create a prototype property it would show up on the object?

Related

Who is parentmost entity in JS (Object or Function)?

According to image (Image is taken from Kyle simpson book this and Object prototypes)
Every function prototype has a prototype that is linked (or inheritin using Prototypical inheritance) to Object.prototype.
Object.prototype has a property i.e constructor that points Object.
Object even has a prototype property (that means it is also inheriting from Function’s prototype).
Function prototype has a constructor property that points to Function.
I don’t understand who is parent most Object or Function.
According to image Function is parentmost.
When you say "parentmost" I'm going to assume you're asking: What's the topmost thing in this image? The thing that everything else derives from? E.g., a "root" object.
The closest thing to a root object in that image is the object that Object.prototype points to, in the upper right-hand corner. That's the root object of the inheritance hierarchy shown in that image.
That object is the prototype of Function.prototype, which is the function object that is used as the prototype of all other functions by default, including the Function function, the Object function, etc. (It's possible to have functions with other prototypes — derived class constructors are one example — or even no prototype, but by default a function has Function.prototype as its prototype.)
Addressing your list:
Every function prototype has a prototype that is linked (or inheritin using Prototypical inheritance) to Object.prototype.
By "Every function prototype" I think you mean "the object on the prototype property of every function." That's true by default for functions that have a prototype property (not all do; arrow functions don't, for instance), but prototype is just a property, it can be changed.
Object.prototype has a property i.e constructor that points Object.
That's true, but it's not really relevant. (More below.)
Object even has a prototype property (that means it is also inheriting from Function’s prototype).
The fact Object has a prototype property doesn't have anything to do with it inheriting from Function's prototype. It has to do with the way the Object function is defined in the specification, which says that it has a prototype property that refers to the root object prototype.
Function prototype has a constructor property that points to Function.
That's true but also not really relevant.
The constructor property on the objects referred to by the prototype property of functions is very rarely used by JavaScript itself. (It wasn't used at all until ES2015.) It's not involved in the workings of inheritance, for instance. Since ES2015 it's been used in a few places to create new objects of the same subclass as other objects, for instance when Array.prototype.slice creates a new array, it uses the constructor property of the source array to create the new array.

JavaScript OOP concepts - Properties

On MDN they state the following:
Properties are variables contained in the class; every instance of the
object has those properties. Properties should be set in the prototype
property of the class (function) so that inheritance works correctly.
Looking at the sections I've set to bold I assumed this meant:
myClass.prototype.newProperty = ...
However their example shows the following:
function Person(firstName) {
this.firstName = firstName;
console.log('Person instantiated');
}
var person1 = new Person('Alice');
var person2 = new Person('Bob');
// Show the firstName properties of the objects
console.log('person1 is ' + person1.firstName); // logs "person1 is Alice"
console.log('person2 is ' + person2.firstName); // logs "person2 is Bob"
In their example they're adding the property 'firstName' directly to the class/function using 'this'.
Does this mean:
a) That the function declaration is the prototype? I.e. myClass is the prototype which also has a property prototype which by default is set to Object?
b) That using 'this.' in the function declaration does actually add the property to the myClass.prototype
Edit: Updated title
JavaScript doesn't have classes, stop thinking in classes, because that doesn't work with JavaScript (yes, even with the ES6 class syntax, it's just sugar, there aren't actual classes in JavaScript).
By adding the property to the object's prototype, you ensure that it and any other objects with the same prototype will share this property, this means that they'll all have it, but it also mean that if you change it on one, it will change with all of them. Oops.
The creation of a new object with the new keyword is fairly straightforward:
Create an empty object
Make that object prototype the same prototype as the constructor's
Call the constructor with this as the newly created object.
So adding a property to the prototype of an object will have it shared among all instances of the same constructor, while adding it to this in the constructor will have it only on this specific instance. Because it's set in the constructor, it's safe to assume that all instances will have that variable in them, although it won't be shared with all other instances.
When you call a JavaScript property, the engine will look for it in the following fasion:
Look for the property on the object itself (that's this inside of methods of that object)
If not found, look for the property on the object's prototype
If not found, go up the prototype chain and look for it there
So in your Person example, the lookup chain will look like:
this > Person.prototype > Object.prototype
The constructor's will look like this:
this > Person.prototype > Function.prototype > Object.prototype
Person is a function, so its prototype is inherited from Function.prototype, similarly any function is an Object.
So to your specific questions:
The function declaration is not the prototype. See the object creation process above.
No, this applies the property on this instance, while prototype is shared among all instances.

Why can't I define properties or functions on prototype via Object.defineProperties()?

I want to set multiple properties on the prototype of my object at once, since Object.defineProperties() takes an object(and prototype is an object) and descriptors, and my object obj has already a prototype as it comes with every object,i am trying to modify the prototype of my object as follows
var obj = document.createElement(tn);
obj.prototype = Object.defineProperties(obj.prototype,{
getName:{
value:function(){
alert("I have the tag"+this.tagName);
},
configurable:true
}
});
but I am getting an error:
Object.defineProperties called on non-object
why?
This is because, obj.prototype is undefined.
You point it to some other object, properties will be added to it.
JS has a prototype based inheritance model where an object inherits from another object, if it doesn't have a property or a method, it looks to its prototype object which is just another object with property and methods which again might have its own prototype object.
You are getting the error Object.defineProperties called on non-object simply because obj.prototype is not an object and is undefined.
set it to window or an empty {}, it should work for you.

Function Object Internal Prototype

It is said every javascipt object have internal prototype property,then predefined Function object also have the internal prototype property.So which object prototype does its internal prototype called proto points to?
function Object(){}
alert(Object.constructor)//function Function(){[native code]}
so i m referring to the internal prototype of the function Function(){} object not its prototype property . like Function object instance have their internal prototype pointing to Function object.prototype likewise Function object internal prototype point to what?not taking about the prototype property that gets added to it.I know what will the internal prototype of the prototype object points to.
All objects inherit from Object.prototype, but they may inherit from other prototypes as well depending on the type of object. Functions inherit from Function.prototype (which inherits from Object.prototype).
In Javascript, functions are just a specific type of object. Thus a function's prototype is the same thing as an object's prototype. For more reading on functions as objects, check out this link.

Confused about JavaScript prototypal inheritance

In the book "JavaScript the definitive guide 5 edition", section 9.2 Prototypes and Inheritance, I find the following words:
In the previous section, I showed that
the new operator creates a new, empty
object and then invokes a constructor
function as a method of that object.
This is not the complete story,
however. After creating the empty
object, new sets the prototype of that
object. The prototype of an object is
the value of the prototype property of
its constructor function. All
functions have a prototype property
that is automatically created and
initialized when the function is
defined. The initial value of the
prototype property is an object with a
single property. This property is
named constructor and refers back to
the constructor function with which
the prototype is associated. (You
may recall the constructor property
from Chapter 7 ; this is why every
object has a constructor property.)
Any properties you add to this
prototype object will appear to be
properties of objects initialized by
the constructor.
Now, if that is true, how could prototypal inheritance exists? I mean, let's say the prototype object of a constructor function has a constructor property initially. Because the prototype object itself is an object, to determine its constructor we often use prototype_object.constructor. But now the prototype_object already has a constructor property itself, and it points to the constructor function with which the prototype is associated. In this situation how can inheritance exists?
The .constructor property honestly doesn't matter very much, and has very little to do with inheriting from other objects in JavaScript. It's just a convenient handle to an object's constructor.
For example, if you have an instance of something, and you'd like to create another instance of that thing, but you don't have a direct handle on its constructor, you could do something like this:
const myCar = new Racecar();
console.log(myCar.constructor); // [Function: Racecar]
const car2 = new myCar.constructor();
console.log(car2.constructor); // [Function: Racecar]
It's important to understand that the .constructor property and the class of an object are not synonymous. As you may have already guessed, the .constructor property is dynamic, just like most other things in JavaScript, so it should not be used for anything like type checking.
It's also important to understand that the .constructor property does not mean that something is a subclass of something else. In fact, there is no reliable way to find out if something is a subclass of something else in JavaScript. Because it's a dynamic language, and because there are so many ways to inherit properties from other objects (including copying properties from other objects after instantiation), type-safe subclasses don't exist in JavaScript like they exist in other languages.
The best way to know if something is a compatible type is to feature-test properties. In other words, duck type.
The instanceof operator ignores the .constructor property. Instead, it checks whether or not the constructor's .prototype exists (with an identity check) in the prototype chain of the object.
With manual constructor functions, inheritance can confuse the .constructor property connection (making it refer to the wrong constructor). You can fix it by manually wiring up the connection. For example, the canonical way to do so in ES5 is this:
function Car () {}
console.log(Car.prototype.constructor); // Car
function Racecar () {}
Racecar.prototype = Object.create(Car.prototype);
// To preserve the same relationship we have with the Car
// constructor, we'll need to reassign the .prototype.constructor:
Racecar.prototype.constructor = Racecar;
var myCar = new Racecar();
console.log(myCar.constructor); // [Function: Racecar]
ES6 classes do this for you automatically:
// ES6
class Car {}
class Racecar extends Car {}
const myCar = new Racecar();
console.log(myCar.constructor); // [Function: Racecar]
That said, I'm not a big fan of either constructor functions or ES6 classes, and I generally have little use for the .constructor property. Why? Because factory functions are far more flexible, far more powerful, and they don't have the pitfalls related to constructor functions and class inheritance. See "Factory Functions vs Constructor Functions vs Classes".
Let say, Dog is a Mammal.
function Mammal() {
this.milk = true;
};
function Dog() {
this.bark = true;
}
Dog.prototype = new Mammal;
So prototype of Dog points to an object of Mammal. This Mammal object has a reference to its constructor so when Dog is new, JavaScript see that Dog prototype is a Mammal so Mammal's constructor is called to produce a valid Mammal object (another one) then make it a Dog object using Dog constructor.
From this, the constructor of Dog.prototype is a Mammal (a Mammal Object that has extra fields and functions added) BUT constructor of Dog is Dog. The inheritance exist because the an instance of Dog has a Mammal as a prototype; hence, Dog is a Mammal. When a method is called and JS cannot find it from Dog.prototype, JS look in Mammal.prototype (which is an Object that has extra fields and functions added).
Hope this helps.
Don't worry about the constructor property - it is irrelevant.
Skip those sentences and you might follow it better.
If you are still unsure of your understanding, google for __proto__ - the internal prototype reference on JS objects. It is even exposed to scripts on Firefox and Safari.
A good reference is https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/The_Employee_Example/Object_Properties/Inheriting_Properties
If you have an object obj, it's prototype is obj.prototype and constructor property referring to obj's constructor is obj.prototype.constructor.
For the object obj.prototype the situation is the same. Let's say proto = obj.prototype, then the reference to the constructor of proto would be found at proto.prototype.constructor.
This is the same as obj.prototype.prototype.constructor, so there is no conflict with obj.prototype.constructor.

Categories

Resources