Programing

__proto__ VS.

lottogame 2020. 9. 30. 08:35
반응형

__proto__ VS. JavaScript의 프로토 타입


이 그림은 모든 객체에 프로토 타입이 있음을 다시 보여줍니다. 생성자 함수 Foo에는 자체적 __proto__으로 Function.prototype이 있으며 이는 __proto__다시 해당 속성을 통해 Object.prototype을 다시 참조 합니다. 따라서 반복하십시오. Foo.prototype은 b 및 c 객체의 프로토 타입을 참조하는 Foo의 명시 적 속성 일뿐입니다.

var b = new Foo(20);
var c = new Foo(30);

의 차이점은 무엇입니까 __proto__와는 prototype?

여기에 이미지 설명 입력

수치는 dmitrysoshnikov.com 에서 가져온 것 입니다.


__proto__메서드 등을 해결하기 위해 조회 체인에서 사용되는 실제 개체입니다. 다음을 사용 prototype하여 개체를 만들 __proto__빌드하는 데 사용 되는 개체입니다 new.

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

prototypeFunction 객체의 속성입니다. 그것은 그 함수에 의해 구성된 객체의 프로토 타입입니다.

__proto__프로토 타입을 가리키는 객체의 내부 속성입니다. 현재 표준은 동일한 Object.getPrototypeOf(O)방법을 제공 하지만 사실상 표준 __proto__이 더 빠릅니다.

instanceof함수 prototype__proto__체인을 객체의 체인과 비교하여 관계를 찾을 수 있으며을 변경하여 이러한 관계를 끊을 수 있습니다 prototype.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

다음 Point은 생성자 함수이며, 절차 적으로 객체 (데이터 구조)를 빌드합니다. myPoint에 의해 생성 된 객체 Point()이므로 그 당시에 Point.prototype저장됩니다 myPoint.__proto__.


Prototype 속성은 함수가 선언 될 때 생성됩니다.

예를 들면 :

 function Person(dob){
    this.dob = dob
 }; 

Person.prototype 속성은 위의 함수를 선언하면 내부적으로 생성됩니다. new Person ()을 사용하여 생성 된 Person 인스턴스가 공유하는 Person.prototype에 많은 속성을 추가 할 수 있습니다.

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

기본적으로 리터럴 이라는 점 Person.prototype주목할 가치가 Object있습니다 (필요에 따라 변경할 수 있음).

사용하여 만든 모든 인스턴스는 new Person()__proto__받는 지적 재산을 Person.prototype. 이것은 특정 개체의 속성을 찾기 위해 횡단하는 데 사용되는 체인입니다.

var person1 = new Person(somedate);
var person2 = new Person(somedate);

2 개 인스턴스를 생성 Person,이 2 개의 객체는 호출 할 수있는 age방법 Person.prototype등을 person1.age, person2.age.

귀하의 질문에서 위의 그림에서, 당신은 볼 수 FooA는 Function Object따라서 그것은이 __proto__받는 링크 Function.prototype차례의 인스턴스 Object와이 __proto__링크를 Object.prototype. proto 링크는 여기 __proto__에서를 Object.prototype가리키는로 끝납니다 null.

모든 객체는에 의해 연결된 프로토 체인의 모든 속성에 액세스 할 수 __proto__있으므로 프로토 타입 상속의 기반을 형성합니다.

__proto__프로토 타입 체인에 액세스하는 표준 방법은 아니지만 표준이지만 유사한 접근 방식은 Object.getPrototypeOf(obj).

instanceof연산자에 대한 아래 코드 는 더 나은 이해를 제공합니다.

객체 instanceof클래스 연산자는 객체가 클래스 true의 인스턴스 일 때 반환합니다 .보다 구체적 Class.prototype으로 해당 객체의 프로토 체인에서가 발견되면 객체는 해당 클래스의 인스턴스입니다.

function instanceOf(Func){
  var obj = this;
  while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
      return true;
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}      

위의 메서드는 다음과 같이 호출 할 수 있습니다 instanceOf.call(object, Class). 객체가 Class의 인스턴스이면 true를 반환합니다.


그것을 생각하는 좋은 방법은 ...

prototypeconstructor()함수에서 사용됩니다 . 그것이 "prototypeToInstall"바로 그것이 기 때문에 그것은 정말로, 같은 것과 같이 불렸어야 했습니다.

__proto__오브젝트 해당 "설치된 원형"이다 (그 생성 /로부터 상기 대상물에 설치된 constructor()기능)


설명하기 위해 함수를 생성하겠습니다.

 function a (name) {
  this.name = name;
 }

JavaScript는이 코드를 실행할 때 prototype속성을에 추가 a하고 prototype속성은 두 가지 속성이있는 객체입니다.

  1. constructor
  2. __proto__

그래서 우리가 할 때

a.prototype 그것은 반환

     constructor: a  // function definition
    __proto__: Object

이제 보시 constructor다시피 함수 a자체 가 JavaScript __proto__의 루트 수준 Object가리 킵니다 .

키워드 a와 함께 기능을 사용할 때 어떤 일이 발생하는지 살펴 보겠습니다 new.

var b = new a ('JavaScript');

JavaScript가이 코드를 실행하면 4 가지 작업을 수행합니다.

  1. 새로운 객체, 빈 객체를 생성합니다. // {}
  2. 그것은 생성 __proto__b그것을 가리 수 a.prototype있도록b.__proto__ === a.prototype
  3. 새로 생성 된 객체 (1 단계에서 생성됨)를 컨텍스트 (this)로 사용하여 ( a.prototype.constructor함수 정의 인 a) 실행 하므로 name'JavaScript'(에 추가됨 this) 로 전달 속성 이 새로 생성 된 객체에 추가됩니다.
  4. (# 1 단계에서 생성 된) 새로 생성 된 객체를 반환하므로 var b가 새로 생성 된 객체에 할당됩니다.

이제를 추가 a.prototype.car = "BMW"하고하면 b.car"BMW"출력이 나타납니다.

이는 JavaScript가이 코드를 실행했을 때에서 car속성을 검색했을 때 b사용 된 JavaScript b.__proto__(# 2 단계에서 'a.prototype'을 가리 키도록 만들어 짐)를 찾지 못하고 car속성을 찾아 "BMW"를 반환하기 때문입니다.


프로토 타입 VS. __proto__ VS. [[원기]]

함수를 생성 할 때 prototype 이라는 속성 객체 가 자동으로 생성되고 (사용자가 직접 생성하지 않음) 함수 객체 ( constructor)에 연결됩니다.
참고 :이 새로운 프로토 타입 객체는 네이티브 JavaScript 객체를 가리 키거나 내부 비공개 링크를 가지고 있습니다.

예:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

키워드 Foo사용하여 새 객체를 생성하는 경우 new, 기본적으로 앞서 논의한 함수의 프로토 타입에 대한 내부 또는 비공개 링크 가있는 새 객체를 생성합니다 Foo.

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


개인 이 함수의 객체에 연결 더블 브라켓은 프로토 타입 또는 방금 전화 [[Prototype]]. 많은 브라우저가 우리에게 공개 링크를 제공하고 있습니다 __proto__.

좀 더 구체적으로 말하자면, __proto__실제로 는 네이티브 자바 스크립트 객체에 속하는 getter 함수 입니다. this바인딩이 무엇이든간에 내부 프라이빗 프로토 타입 연결을 반환합니다 ( [[Prototype]]of 반환 b).

b.__proto__ === Foo.prototype // true

로 시작 ECMAScript5하면 getPrototypeOf 메서드를 사용 하여 내부 개인 연결을 가져올 수도 있습니다 .

Object.getPrototypeOf(b) === b.__proto__ // true


참고 : 이 답변은 새로운 개체 또는 새 생성자를 작성의 전 과정을 포함하려고하지만, 도움이 더 나은 무엇인지 이해하지 못하는 __proto__, prototype그리고 [[Prototype]]어떻게 작동하는지.


위의 훌륭한 답변 외에도 약간 명확하게하려면 다음을 수행하십시오.

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

인스턴스 에는 __proto__가 있고 클래스 에는 프로토 타입이 있습니다.


JavaScript에서는 함수를 생성자로 사용할 수 있습니다. 즉, new 키워드를 사용하여 개체를 만들 수 있습니다. 모든 생성자 함수는 그들과 연결된 내장 객체와 함께 제공됩니다. 이 내장 객체를 프로토 타입이라고합니다.Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

프로토 타입 다이어그램

  1. 먼저 생성자를 만들었습니다 : function Foo(){}. 분명히 말하면 Foo는 또 다른 기능입니다. 그러나 새로운 키워드를 사용하여 객체를 만들 수 있습니다. 그래서 우리는 그것을 생성자 함수라고 부릅니다.

  2. 모든 함수에는 프로토 타입 속성이라고하는 고유 한 속성이 있습니다. 따라서 Constructor 함수 Foo에는 프로토 타입을 가리키는 프로토 타입 속성이 있습니다 Foo.prototype(이미지 참조).

  3. 생성자 함수는 그 자체로 [[Function]] 생성자라고하는 시스템 생성자의 인스턴스 인 함수입니다. 그래서 우리는 function Foo[[Function]] 생성자에 의해 생성 된다고 말할 수 있습니다 . 그래서 __proto__우리 Foo function는 생성자의 프로토 타입 인 Function.prototype.

  4. Function.prototype라는 다른 시스템 생성자에서 생성 된 객체 일뿐 [[Object]]입니다. 따라서, [[Object]]의 생성자입니다 Function.prototype. 그래서 우리가 말할 수 Function.prototype의 인스턴스입니다 [[Object]]. 그래서 __proto__Function.prototype포인트 Object.prototype.

  5. Object.prototype프로토 타입 체인에서 마지막으로 서있는 사람입니다. 건설되지 않았 음을 의미합니다. 이미 시스템에 있습니다. 그래서 그 __proto__포인트는 null.

  6. 이제 우리는 Foo. 를 사용하여 인스턴스를 만들면의 인스턴스 인 new Foo()새 개체를 만듭니다 Foo. Foo, 이러한 인스턴스의 생성자입니다. 여기에서 두 개의 인스턴스 (x 및 y)를 만들었습니다. __proto__따라서 x와 y의 Foo.prototype.


저는 You Do n't Know JS : this & Object Prototypes 에서 프로토 타입을 배우고 있습니다 .이 책은 밑에있는 디자인을 이해하고 많은 오해를 명확히하는 훌륭한 책 instanceof입니다.

하지만 사람들이 여기에서 물었던 것과 같은 질문이 있습니다. 몇 가지 답변이 정말 도움이되고 계몽 적입니다. 또한 제 이해를 공유하고 싶습니다.


프로토 타입이란?

JavaScript의 객체에는 사양에서로 표시되는 내부 속성 [[Prototype]]이 있으며 이는 단순히 다른 객체에 대한 참조입니다. 거의 모든 객체는 null생성 시점에이 속성에 대한 값이 아닙니다.

개체의 프로토 타입을 얻는 방법은 무엇입니까?

__proto__또는 통해Object.getPrototypeOf

var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true

function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype

무엇입니까 prototype?

prototype함수 의 특수 속성으로 자동 생성되는 객체로 , 위임 (상속) 체인, 일명 프로토 타입 체인을 설정하는 데 사용됩니다.

우리는 함수를 만들 때 a, prototype자동으로 특별한 속성으로 생성 a하고, 등의 기능 코드를 저장 constructorprototype.

function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true

이 속성을 함수 개체의 속성 (메서드 포함)을 저장하는 장소로 간주하고 싶습니다. 그것은 또한 JS에서 유틸리티 기능은 다음과 같이 정의되는 이유입니다 Array.prototype.forEach(), Function.prototype.bind(),Object.prototype.toString().

함수 의 속성을 강조하는 이유는 무엇 입니까?

{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}

// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();

그래서, Arary, Function, Object모든 기능은 다음과 같습니다. 나는 이것이 JS에 대한 나의 인상을 새롭게한다는 것을 인정해야한다. 나는 함수가 JS에서 일류 시민이라는 것을 알고 있지만 함수를 기반으로 한 것 같습니다.

__proto__의 차이점은 무엇입니까 prototype?

__proto__참조 속성 을 참조하기 위해 모든 개체 에서 작동 [[Prototype]]합니다.

prototype함수 의 특수 속성으로 자동 생성되는 객체 로, 함수 객체의 속성 (메서드 포함)을 저장하는 데 사용됩니다.

이 두 가지를 통해 우리는 프로토 타입 체인을 정신적으로 매핑 할 수 있습니다. 이 그림은 다음을 보여줍니다.

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true

요약:

__proto__객체 속성은 객체 prototype의 생성자 함수에 매핑되는 속성입니다 . 다시 말해:

instance.__proto__ === constructor.prototype // true

이것은 prototype개체 체인 을 형성하는 데 사용됩니다 . prototype체인 오브젝트의 속성에 대한 룩업 메커니즘이다. 객체의 속성에 액세스하면 JavaScript는 먼저 객체 자체를 봅니다. 거기에서 부동산이 발견되지 않으면 발견 protochain될 때까지 (또는 발견되지 않을 때까지) 올라갈 것입니다.

예:

function Person (name, city) {
  this.name = name;
}

Person.prototype.age = 25;

const willem = new Person('Willem');

console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor

console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function 

에 대한 첫 번째 로그 결과 true는 언급했듯이 __proto__생성자가 생성 한 인스턴스의 prototype속성이 생성자 속성을 참조하기 때문 입니다. JavaScript에서 함수는 객체이기도합니다. 객체는 속성을 가질 수 있으며 모든 함수의 기본 속성은 prototype이라는 하나의 속성입니다.

그런 다음이 함수를 생성자 함수로 사용하면이 함수에서 인스턴스화 된 객체가라는 속성을받습니다 __proto__. 그리고이 __proto__속성은 prototype생성자 함수 속성 (기본적으로 모든 함수에 있음)을 나타냅니다.

이것이 왜 유용합니까?

JavaScript에는 'prototypal inheritance'Objects 라는 속성을 찾을 때 기본적으로 수행되는 작업이 있습니다.

  • 먼저 속성이 Object 자체에 있는지 확인합니다. 그렇다면이 속성이 반환됩니다.
  • 속성이 객체 자체에 위치하지 않으면 '프로토 체인 위로 올라갑니다'. 기본적으로 __proto__속성이 참조하는 객체를 봅니다 . 거기에서에서 참조하는 객체에서 속성을 사용할 수 있는지 확인합니다 __proto__.
  • 속성이 __proto__개체 에 없으면 개체까지 __proto__체인 을 따라 올라갑니다 Object.
  • 객체와 prototype체인 에서 속성을 찾을 수 없으면 을 반환 undefined합니다.

예를 들면 :

function Person (name) {
  this.name = name;
}

let mySelf = new Person('Willem');

console.log(mySelf.__proto__ === Person.prototype);

console.log(mySelf.__proto__.__proto__ === Object.prototype);


그것을 이해하는 또 다른 좋은 방법 :

var foo = {}

/* 
foo.constructor is Object, so foo.constructor.prototype is actually 
Object.prototype; Object.prototype in return is what foo.__proto__ links to. 
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);

IE11 __proto__이 지원 된 후에 만 가능합니다 . IE9와 같은 해당 버전 이전에는 constructor사용 하여 __proto__.


원기

프로토 타입은 함수의 속성입니다. 그 (생성자) 함수를 new 키워드와 함께 사용하여 객체를 생성하기위한 청사진입니다.

__proto__메서드, 속성을 확인하기 위해 조회 체인에서 사용됩니다. 객체가 생성 될 때 (새 키워드와 함께 생성자 함수 사용), __proto__(생성자) Function.prototype으로 설정됩니다.

function Robot(name) {
    this.name = name;
}
var robot = new Robot();

// the following are true   
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype

혼란을 없애기위한 내 (가상) 설명은 다음과 같습니다.

함수와 관련된 가상 클래스 (청사진 / 쿠키 커터)가 있다고 상상해보십시오. 가상 클래스는 객체를 인스턴스화하는 데 사용됩니다. prototype가상 클래스에 항목을 추가하는 확장 메커니즘 (C #의 확장 메서드 또는 Swift Extension)입니다.

function Robot(name) {
    this.name = name;
}

위는 다음과 같이 상상할 수 있습니다.

// imaginary class
class Robot extends Object{

    static prototype = Robot.class  
    // Robot.prototype is the way to add things to Robot class
    // since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype

    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

} 

그래서,

var robot = new Robot();

robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype

이제 prototype로봇에 메서드를 추가합니다 .

Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)

위의 내용은 Robot 클래스의 확장으로 상상할 수 있습니다.

// Swift way of extention
extension Robot{
    function move(x, y){    
        Robot.position.x = x; Robot.position.y = y
    }
}

차례로

// imaginary class
class Robot{

    static prototype = Robot.class // Robot.prototype way to extend Robot class
    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

    // added by prototype (as like C# extension method)
    function move(x, y){ 
        Robot.position.x = x; Robot.position.y = y
    };
}

간단히 말하면 :

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

이를 통해 X 유형의 객체가 인스턴스화 된 후 X.prototype에 속성을 연결할 수 있으며 Javascript-engine이 프로토 타입 체인을 걸어 가기 위해 사용하는 __proto__ 참조를 통해 새 속성에 계속 액세스 할 수 있습니다.


 자바 스크립트 프로토 타입 vs __prototype__

'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true

JavaScript에서 모든 객체 (함수도 객체입니다!)에는 __proto__속성이 있으며 속성은 프로토 타입에 대한 참조입니다.

우리가 사용하면 new새로운 객체를 생성하는 생성자와 연산자를 새 개체의 __proto__속성은 생성자의 설정 될 것 prototype"이"새로운 객체에 대한 참조가 될 것입니다 후 생성자는 그 과정에서 새로운 객체에 의해 호출 될 것입니다, 재산 생성자 범위에서 마지막으로 새 개체를 반환합니다.

생성자의 프로토 타입은 __proto__속성이고 생성자의 prototype속성은 new연산자 와 함께 작동합니다.

생성자는 함수 여야하지만 함수에 prototype속성 이 있어도 항상 생성자는 아닙니다 .

프로토 타입 체인은 실제로 프로토 타입 __proto__을 참조하는 객체의 속성이고, 프로토 __proto__타입의 프로토 타입을 참조하는 프로토 타입의 __proto__속성은 null 을 참조하는 Object의 프로토 타입 속성 을 참조 할 때까지 계속됩니다 .

예를 들면 :

console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A

[[Prototype]]그리고 __proto__재산은 실제로 같은 것입니다.

Object의 getPrototypeOf 메소드를 사용하여 무언가의 프로토 타입을 얻을 수 있습니다.

console.log(Object.getPrototypeOf(a) === a.__proto__); // true

우리가 작성한 모든 함수는 new연산자 를 사용하여 객체를 만드는 데 사용할 수 있으므로 이러한 함수는 모두 생성자가 될 수 있습니다.


Prototype 또는 Object.prototype 은 개체 리터럴의 속성입니다. 프로토 타입 체인을 따라 더 많은 속성이나 메서드를 추가하기 위해 재정의 할 수 있는 Object 프로토 타입 객체를 나타냅니다 .

__proto__ 는 액세스되는 객체의 내부 프로토 타입을 노출하는 접근 자 속성 (get 및 set 함수)입니다.

참조 :

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  2. http://www.w3schools.com/js/js_object_prototypes.asp

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


나는 늦었지만 그것을 단순화하도록 노력하겠습니다.

함수가 있다고합시다

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

Foo 함수에는 프로토 타입 개체가 연결됩니다. 따라서 JavaScript에서 함수를 만들 때마다 항상 프로토 타입 객체가 연결됩니다.

이제 Foo 함수를 사용하여 두 개의 객체를 생성하겠습니다.

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);
  1. 이제 객체 a와 객체 b라는 두 개의 객체가 있습니다. 둘 다 생성자 Foo를 사용하여 생성됩니다. 생성자는 여기에있는 단어 일뿐입니다.
  2. 객체 a와 b는 모두 메시지 속성의 복사본을 가지고 있습니다.
  3. 이 두 객체 a와 b는 생성자 Foo의 프로토 타입 객체에 연결됩니다.
  4. 객체 a와 b에서는 모든 브라우저에서 proto 속성을 사용하여 Foo 프로토 타입에 액세스 할 수 있으며 IE에서는 Object.getPrototypeOf (a) 또는 Object.getPrototypeOf (b)를 사용할 수 있습니다.

이제 Foo.prototype, a. proto 및 b. proto all은 동일한 객체를 나타냅니다.

    b.__proto__ === Object.getPrototypeOf(a);
    a.__proto__ ===  Foo.prototype;
    a.constructor.prototype  === a.__proto__;

위의 모든 것이 true를 반환합니다.

아시다시피 JavaScript 속성은 동적으로 추가 될 수 있습니다. 객체에 속성을 추가 할 수 있습니다.

    Foo.prototype.Greet = function(){

         console.log(this.message);
    }
    a.Greet();//a
    b.Greet();//b
    a.constructor.prototype.Greet();//undefined 

보시다시피 Foo.prototype에 Greet () 메서드를 추가했지만 a와 b 또는 Foo를 사용하여 구성된 다른 객체에서 액세스 할 수 있습니다.

a.Greet ()을 실행하는 동안 JavaScript는 먼저 속성 목록에서 객체 a에서 Greet을 검색합니다. 을 찾지 못하면 a의 프로토 체인으로 올라갑니다 . 이후. proto 와 Foo.prototype은 동일한 객체이며 JavaScript는 Greet () 메서드를 찾아 실행합니다.

이제 프로토 타입과 프로토 타입 이 약간 단순화 되었으면 합니다.


정의

(괄호 () 안의 숫자는 아래에 작성된 코드에 대한 '링크'입니다.)

prototype-다음으로 구성된 객체 :
=>이 특정 ConstructorFunction.prototype(5 )의 함수 (3) 가이 생성자 함수를 통해 생성되거나 생성 될 각 객체 (4)에 의해 액세스 가능 (1)
=> 생성자 함수 자체 (1 )
=> __proto__이 특정 개체 (프로토 타입 개체)

__proto__(dandor proto?)-특정 생성자 함수 (1)를 통해 생성 된 모든 객체 (2)와 생성 된 각 객체 (2)가 프로토 타입의 함수에 액세스 할 수 있도록하는 해당 생성자의 프로토 타입 객체 속성 (5) 간의 링크 및 메소드 (4) ( __proto__기본적으로 JS의 모든 단일 객체에 포함됨)

코드 설명

1.

    function Person (name, age) {
        this.name = name;
        this.age = age;  

    } 

2.

    var John = new Person(‘John’, 37);
    // John is an object

삼.

    Person.prototype.getOlder = function() {
        this.age++;
    }
    // getOlder is a key that has a value of the function

4.

    John.getOlder();

5.

    Person.prototype;

설명 예 :

function Dog(){}
Dog.prototype.bark = "woof"

let myPuppie = new Dog()

이제 myPupppie에는 __proto__Dog.prototype을 가리키는 속성이 있습니다.

> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}

그러나 myPuppie에는 프로토 타입 속성이 없습니다.

> myPuppie.prototype
>> undefined

따라서 __proto__mypuppie는 이 개체를 인스턴스화하는 데 사용 된 생성자 함수의 .prototype 속성에 대한 참조입니다 (현재 myPuppie 개체에는이 개체에 대한 "대리자"관계가 있음 __proto__). 반면 myPuppie의 .prototype 속성은 우리는 그것을 설정하지 않았습니다).

MPJ의 좋은 설명 : proto vs prototype-JavaScript에서 객체 생성


4 학년 설명을 해보겠습니다.

상황은 매우 간단합니다. A prototype는 무언가를 어떻게 만들어야 하는지를 보여주는 예입니다. 그래서:

  • 나는 function이고 나는 나의prototype

  • 나는 object나의 __proto__예를 사용하여 지어졌습니다.

증거 :

function Foo() { }

var bar = new Foo()

// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true

// bar is an instance - it does not know how to create objects
bar.prototype // => undefined

생성하는 모든 함수에는라는 속성이 prototype있으며 빈 객체로 수명이 시작됩니다. 이 속성은이 함수를 생성자 함수, 즉 'new'키워드와 함께 사용할 때까지 사용되지 않습니다.

이것은 종종 __proto__객체 속성 과 혼동됩니다 . 일부는 혼란 스러울 수 prototype있으며 객체 속성이 객체의 프로토 타입을 얻을 수 있다는 점을 제외하고는 . 그러나 이것은 사실이 아닙니다. 함수 생성자에서 생성 된 객체 prototype를 가져 오는 데 사용됩니다 __proto__.

위의 예에서 :

function Person(name){
    this.name = name
}; 

var eve = new Person("Eve");

console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__

이해가 되길 바랍니다.


__proto__정적 메서드 를 사용 하는 것은 어떻습니까?

function Foo(name){
  this.name = name
  Foo.__proto__.collection.push(this)
  Foo.__proto__.count++

}

Foo.__proto__.count=0
Foo.__proto__.collection=[]

var bar = new Foo('bar')
var baz = new Foo('baz')

Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined

(function(){ 
      let a = function(){console.log(this.b)};
      a.prototype.b = 1;
      a.__proto__.b = 2;
      let q = new a();
      console.log(a.b);
      console.log(q.b) 
    })()

이해하려면이 코드를 사용해보십시오.


__proto__는 생성 할 기본 prototype이며 생성자 함수입니다. 예 : 생성자 함수 의 새 인스턴스에서 공유되는 function human(){}has prototype입니다 __proto__. 여기에서 더 자세한 내용을 읽으 십시오.


으로 바르게 진술

__proto__메소드 등을 해결하기 위해 조회 체인에서 사용되는 실제 객체입니다. prototype은 __proto__new로 객체를 만들 때 빌드하는 데 사용 되는 객체입니다.

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

우리는 더주의 할 __proto__메모리 위치로 향해 지적으로 객체의 속성이 기능 생성자 포인트를 사용하여 만든 프로토 타입 이 각각의 생성자의 재산입니다.

생성자 함수 프로토 타입메모리 위치를 변경하면 __proto__파생 된 객체의 원래 주소 공간을 계속 가리 킵니다. 따라서 상속 체인에서 공통 속성을 사용할 수 있도록하려면 속성을 다시 초기화 (메모리 주소 변경)하는 대신 항상 생성자 함수 prototype에 속성을 추가합니다 .

다음 예를 고려하십시오.

function Human(){
    this.speed = 25;
}

var himansh = new Human();

Human.prototype.showSpeed = function(){
    return this.speed;
}

himansh.__proto__ === Human.prototype;  //true
himansh.showSpeed();    //25

//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}

//himansh.__proto__ will still continue to point towards the same original memory location. 

himansh.__proto__ === Human.prototype;  //false
himansh.showSpeed();    //25

protypal chaining에 사용되는 개체는 하나뿐입니다. :이 개체는 분명 이름과 값을 가지고 __proto__그 이름이며, prototype그 값입니다. 그게 다야.

이해를 더 쉽게하기 위해이 게시물의 상단에있는 다이어그램 (dmitry soshnikov의 다이어그램)을 보면 그 가치 __proto__이외의 다른 것에 대한 포인트를 찾을 수 없습니다 prototype.

요점은 이것입니다 : __proto__프로토 타입 객체를 참조하는 이름이며 prototype실제 프로토 타입 객체입니다.

다음과 같이 말합니다.

var x = {name: 'john'};

x개체 이름 (포인터)이고 {name: 'john'}실제 개체 (데이터 값)입니다.

참고 : 이것은 상위 수준에서 어떻게 관련되는지에 대한 매우 단순화 된 힌트입니다.


내 이해는 : __proto__ 및 프로토 타입은 모두 프로토 타입 체인 기술을 위해 제공됩니다. 차이점은 밑줄로 명명 된 함수 (예 : __proto__)는 명시 적으로 호출 된 개발자를위한 것이 아닙니다. 즉, 상속과 같은 일부 메커니즘을위한 것입니다. '백엔드'입니다. 그러나 밑줄이없는 이름의 함수는 명시 적으로 호출되도록 설계되었으며 '프론트 엔드'입니다.


!!! 이것은 세계 최고의 설명입니다 !!!!!

var q = {}
var prototype = {prop: 11}

q.prop // undefined
q.__proto__ = prototype
q.prop // 11

함수 생성자에서 자바 스크립트 엔진은 q.__proto__ = prototype우리가 작성할 때 이것을 자동으로 호출 new Class하고 __proto__소품 세트에Class.prototype

function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new

var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999

즐겨 %)

참고 URL : https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript

반응형