__proto__는 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
항상 등급이 3 인 객체를 반환합니다.
그러나 내가 다음을 수행하면 :
newtoy.__proto__.__proto__.__proto__
체인이 돌아갑니다 null
.
또한 Internet Explorer에서 __proto__
속성 이 없으면 null을 어떻게 확인 합니까?
최근에이 문제를 해결하기 위해 노력해 왔으며 마침내이 "지도"를 생각해 냈습니다.
http://i.stack.imgur.com/KFzI3.png
나는 내가 이것을 처음 만드는 사람이 아니라는 것을 알고 있지만 그것을 발견하는 것이 더 흥미로웠다 :-). 어쨌든, 그 후에 나는 예를 들어 기본적으로 같은 다른 다이어그램을 발견했습니다.
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 toFunction.prototype
, instead ofObject.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 theprototype
property(1) of itsconstructor function
or "creator" if you like .Hard coded within JS — :
Object.prototype.__proto__
isnull
.
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 prototype
is 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
여기는 toy.__proto__
입니다 Gadget.prototype
. Gadget.prototype
객체 ( {}
)와 마찬가지로 객체는 Object
함수 로 생성됩니다 (위 예 참조) Object.prototype
. 이것은 JavaScript에서 더 높은 객체이며 __proto__
표시 할 수 있습니다 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
참고 URL : https://stackoverflow.com/questions/650764/how-does-proto-differ-from-constructor-prototype
'Programing' 카테고리의 다른 글
Windows에서 여러 Python 버전을 실행하는 방법 (0) | 2020.06.07 |
---|---|
Swift에서 "포장 해제 된 값"은 무엇입니까? (0) | 2020.06.07 |
표준 :: 기능 대 템플릿 (0) | 2020.06.07 |
ArrayAdapter의 getViewTypeCount 및 getItemViewType 메소드 (0) | 2020.06.07 |
HTML 인쇄시 페이지를 강제로 끊을 수 있습니까? (0) | 2020.06.07 |