[javascript] __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
여기에 이미지 설명을 입력하십시오

나는 내가 이것을 처음 만드는 사람이 아니라는 것을 알고 있지만 그것을 발견하는 것이 더 흥미로웠다 :-). 어쨌든, 그 후에 나는 예를 들어 기본적으로 같은 다른 다이어그램을 발견했습니다.

자바 스크립트 객체 레이아웃

나에게 가장 놀라운 것은 대신 을 Object.__proto__가리키는 것을 발견하고 있었지만 그만한 이유가 있다고 확신합니다. 🙂Function.prototypeObject.prototype

누군가 이미지를 테스트하고 싶다면 이미지에 언급 된 코드를 여기에 붙여 넣으십시오. 몇 가지 점프 후의 위치를 ​​쉽게 알 수 있도록 일부 속성이 객체에 추가됩니다.

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);


답변

constructorprototype함수 객체 의 속성으로 가리키는 객체의 사전 정의 된 [[DontEnum]] 속성이며 처음에는 함수 객체 자체를 가리 킵니다.

__proto__ 객체의 내부 [[Prototype]] 속성, 즉 실제 프로토 타입과 같습니다.

new연산자 를 사용하여 객체를 만들면 내부 [[Prototype]] 속성이 생성자 함수의 prototype속성이 가리키는 객체로 설정됩니다 .

이것은 즉, 객체를 생성하는데 사용 된 생성자 함수로 .constructor평가 될 것이며 .__proto__.constructor, 우리가 알게 된 것처럼 protoype이 함수 의 속성은 객체의 [[Prototype]]을 설정하는데 사용되었습니다.

다음과 .constructor.prototype.constructor동일합니다 .constructor(이러한 속성을 덮어 쓰지 않는 한). 자세한 설명 은 여기 를 참조 하십시오 .

__proto__사용 가능한 경우 객체의 실제 프로토 타입 체인을 걸을 수 있습니다. JavaScript는 깊은 상속 계층 구조를 위해 설계되지 않았기 때문에 일반 ECMAScript3에서는이를 수행 할 방법이 없습니다.


답변

JavaScript의 Prototypal Inheritance는 __proto__각 객체가 해당 __proto__속성이 참조하는 객체의 내용을 상속한다는 의미 에서 속성을 기반으로 합니다.

prototype속성은 Function객체에만 적용되며 new연산자를 사용하여 Function생성자 로 호출 할 때만 특별합니다 . 이 경우 생성 된 객체 __proto__는 constructor로 설정됩니다 Function.prototype.

이는에 추가 Function.prototype하면를 __proto__참조하는 모든 객체에 자동으로 반영됩니다 Function.prototype.

생성자 Function.prototype를 다른 객체로 바꾸면 기존 객체의 속성이 업데이트 되지 않습니다__proto__ .

주의 __proto__속성에 직접 액세스 할 수 없습니다해야한다는 Object.getPrototypeOf (개체) 대신에 사용되어야한다.

첫 번째 질문에 답하기 위해 맞춤식 다이어그램 __proto__prototype참조를 만들었습니다. 불행히도 stackoverflow로 인해 “10 평판 미만”의 이미지를 추가 할 수 없습니다. 지금 말고.

[편집] 그림은 ECMAScript 사양이 내부 객체를 참조하는 방식이기 때문에 [[Prototype]]대신 사용 __proto__합니다. 나는 당신이 모든 것을 알아낼 수 있기를 바랍니다.

다음은 그림을 이해하는 데 도움이되는 힌트입니다.

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)

주의 constructor속성이 만든 개체에 존재하지 않지만, 프로토 타입에서 상속됩니다.

여기에 이미지 설명을 입력하십시오


답변

ObjectEve Function는 (는) Adam이며 Adam ( Function)은 자신의 뼈 ( Function.prototype)를 사용하여 Eve ( Object) 를 만듭니다 . 그러면 누가 아담 ( Function) 을 만들었 습니까? -JavaScript 언어의 발명자 :-).

utsaina의 답변에 따르면 더 유용한 정보를 추가하고 싶습니다.

나에게 가장 놀라운 것은 대신 을 Object.__proto__
가리키는 것을 발견하고 있었지만 그만한 이유가 있다고 확신합니다. 🙂Function.prototypeObject.prototype

해서는 안됩니다. Object.__proto__를 가리켜서는 안됩니다 Object.prototype. 대신, 인스턴스 Object o, o.__proto__가리켜 야합니다 Object.prototype.

(용어 사용에 대한 용서 classinstance자바 스크립트,하지만 당신은 그것을 알고 🙂

나는 클래스 생각 Object자체의 인스턴스 인 Function이유, Object.__proto__ === Function.prototype. 그러므로 : Object이브이고 Function아담이며, Adam ( Function)은 자신의 뼈 ( Function.prototype)를 사용하여 Eve ( Object) 를 만듭니다 .

또한, 심지어는 클래스 Function자체의 인스턴스 Function입니다 자체가, Function.__proto__ === Function.prototype그 또한 이유,Function === Function.constructor

또한 또한, 일반 클래스 Cat의 인스턴스입니다 Function즉, Cat.__proto__ === Function.prototype.

위의 이유는 JavaScript로 클래스를 만들 때 실제로 함수를 만드는 것입니다.이 함수는의 인스턴스 여야합니다 Function. Object그리고 Function단지 특별하다, 그러나 동시에 그들은 여전히 클래스입니다 Cat일반 클래스입니다.

Chrome Chrome 엔진에서 다음과 같은 요소는 다음과 같습니다.

  • Function.prototype
  • Function.__proto__
  • Object.__proto__
  • Cat.__proto__

그것들은 모두 ===다른 3과 (절대적으로 동일)이며, 그들의 가치는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

확인. 그러면 누가 특별 function Empty() {}( Function.prototype) 을 생성 합니까? 생각 해봐 🙂


답변

나는 왜 사람들이 당신의 이해에서 실제 문제의 위치에 대해 당신을 수정하지 않았는지 모르겠습니다.

이렇게하면 문제를 쉽게 발견 할 수 있습니다

무슨 일이 일어나고 있는지 보자.

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

좋아, 이제 이것을 보자 __proto__

그 전에 다음과 관련된 두 가지 사항을 기억하십시오 __proto__ .

  1. new연산자 를 사용하여 객체를 만들면 원하는 경우 내부 [[Prototype]]/ proto__속성이 “생성자” 의 prototype속성 (1) 으로 설정됩니다 constructor function.

  2. JS 내에서 하드 코딩 된 — : Object.prototype.__proto__입니다 null.

이 두 점을 ” 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

보다 나은?


답변

모든 기능은 프로토 타입을 만듭니다. 그리고 함수 생성자를 사용하여 객체를 만들면 객체의 __proto__ 속성이 해당 함수의 프로토 타입을 가리 키기 시작합니다.


답변

모든 수치가 압도적이라면 속성의 의미를 살펴 보겠습니다.

STH.prototype

새로운 함수를 생성 할 때, 빈 객체가 병렬로 생성되고 [[Prototype]]체인으로 함수에 연결됩니다. 이 객체에 접근하기 prototype위해 함수의 속성을 사용 합니다.

function Gadget() {}
// in background, new object has been created
// we can access it with Gadget.prototype
// it looks somewhat like {constructor: Gadget}

마음에 베어 있다고 prototype속성은 기능에만 사용할 수 있습니다.

STH. 생성자

위에서 언급 한 프로토 타입 객체에는 1을 제외한 속성이 없습니다 constructor. 이 속성은 프로토 타입 객체를 만든 함수를 나타냅니다.

var toy = new Gadget();

만들 때 Gadget기능을, 우리는 같은 객체 생성 {constructor: Gadget}과 같은 아무것도 아니다 – 물론을 Gadget.prototype. 마찬가지로 constructor오브젝트의 프로토 타입을 생성하는 기능을 의미 toy.constructor나타내는 Gadget기능. 우리는 쓰고 다시 toy.constructor.prototype받고 {constructor: Gadget}있습니다.

따라서 악순환 toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype이 있습니다 Gadget.prototype. 사용할 수 있으며 항상 그렇습니다 .

toy
.constructor    // Gadget
.prototype    // {constructor: Gadget}
.constructor    // Gadget
.prototype    // {constructor: Gadget}
// ...

STH .__ proto__

prototype함수에 고유 한 속성 인 반면 에있는 __proto__모든 개체에 사용할 수 있습니다 Object.prototype. 객체를 생성 할 수있는 함수의 프로토 타입을 나타냅니다.

[].__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