Difficulty in manual operation. Prototype chain.

I wanted to try manually going through the prototype chain of several objects to see what I find along the way. However, I was stuck on the first thing I tried. Here is the code:

function MyObject() { } var x = new MyObject(); console.log('--------------------------------------------'); console.log('x.constructor.name: ' + x.constructor.name); console.log('x.constructor.prototype.constructor.name: ' + x.constructor.prototype.constructor.name); console.log(x.constructor.prototype === Function.prototype ? 'Good guess.' : 'No, you are wrong.'); console.log(x.constructor === MyObject ? 'Good guess.' : 'No, you are wrong.'); console.log('--------------------------------------------'); 

The above code displays the following result in the Google Chrome Developer Console:

 -------------------------------------------- x.constructor.name: MyObject x.constructor.prototype.constructor.name: MyObject No, you are wrong. Good guess. -------------------------------------------- 

It makes sense that the constructor x is a function of MyObject, since x was created using the new keyword in MyObject (this follows from the constructor definition). Because of this, I understand the first line of output (note: I started counting output lines from zero up). However, the second line confuses me. I would like to know what a prototype of MyObject is. Apparently, this is not an object of type Function, as indicated by the third line of output, which tells me that I'm wrong. The fourth line of output only enhances the output of the first line.

In a more general note, I suggested that the correct way to run the prototype of an object chain is to go from the object in question to its constructor, and then from the constructor to the prototype constructor, assuming this last link is not null. I suggested that this two-step process (consisting of going to the constructor, and then to the prototype of the constructor) should be repeated until a zero reference from the constructor to the prototype is reached, which means the end of the prototype chain. This does not seem to work, since applying this algorithm to the above scenario only results in circular references.

In conclusion, I have two questions:

  • Why x.constructor === x.constructor.prototype.constructor (or, in other words, why circular links), and which particular object is x.constructor.prototype, in any case (or, in another word, how did it happen / where did it come from)?
  • How can the above algorithm be eliminated in order to correctly go through the prototype chain for object x?

Edit

I came across a similar question in StackOverflow here , but does not explain how to properly go through the prototype chain. It points to circular links, though ...

+6
source share
2 answers

In Javascript terminology, a "prototype" refers to the object from which a inherits properties. The standard way to access this is with Object.getPrototypeOf :

 var protoOfA = Object.getPrototypeOf(a); 

There is also an old way, non-standard, but supported by some browsers:

 var protoOfA = a.__proto__; 

But if you have an F function, F.prototype does NOT refer to the object from which F inherits anything. Rather, this refers to the object from which the instances created by F inherit are:

 function F() {}; a = new F(); console.log(Object.getPrototypeOf(a) === F.prototype); // true 

When you define a function, an object is created that serves as the prototype of the instances created by this function, and this new object is stored in the prototype function property.

-

Functions behave like objects in different ways (for example, they can have properties), but they are not quite like other objects:

 console.log(typeof a); // "object" console.log(typeof F); // "function" 

Their "prototypes" are poorly defined (the example runs in Chrome) (this is apparently the behavior typical of Chrome )

 console.log(Object.getPrototypeOf(F)); // "function Empty() {}" console.log(Empty); // ReferenceError: Empty is not defined 

-

The constructor property is strange. The translator does not care about this . MDN says vaguely :

Returns a reference to the Object function that created the instance prototype.

In addition, you can change the constructor value to an object, but this does not affect what the object is or how it behaves - it is simply descriptive.

-

So, to answer your questions:

Why x.constructor === x.constructor.prototype.constructor

There is no good reason. These are arbitrary behavior browsers converge.

which object is x.constructor.prototype, anyway

In this example, the t x prototype is similar to Object.getPrototypeOf(x) . But in general, you cannot rely on x.constructor or anything derived from it, because it is arbitrary.

How can the above algorithm be eliminated in order to correctly go through the prototype chain for object x?

 for (var p = x ; p != null ; p = Object.getPrototypeOf(p)) { // do something with p } 
+3
source

Yes, it can be a little difficult to understand at first. I can do no better than provide you some links. They always help me when I'm in trouble.

http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

http://mckoss.com/jscript/object.htm

http://zeekat.nl/articles/constructors-considered-mildly-confusing.html

Q1: “why,” see the links above. x.constructor.prototype is x.__proto__ , that is, the internal "real" prototype of x, at least in your case, when the prototype and constructor properties were not overwritten. It is created the moment you define the MyObject function.

Q2: Unfortunately, you cannot do this. You can use the __proto__ property, where it is supported, but see

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

+1
source

Source: https://habr.com/ru/post/986323/


All Articles