>  기사  >  웹 프론트엔드  >  자바스크립트 프로토타입 체인 유지관리 및 상속_자바스크립트 기술에 대한 자세한 설명

자바스크립트 프로토타입 체인 유지관리 및 상속_자바스크립트 기술에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 16:30:271423검색

프로토타입 2개

많은 사람들이 JavaScript가 프로토타입 상속이라는 것을 알고 있습니다. 각 생성자에는 프로토타입 멤버가 있으며 이를 통해 JavaScript의 상속을 아름답게 설명할 수 있습니다.
실제로 이 속성에만 의존해서는 JavaScript 상속을 완료할 수 없습니다.
상속을 완료하기 위해 코드에서 사용하는 프로토타입은 여기서 설명하지 않습니다.
또다른 보이지 않는 프로토타입 멤버.
각 인스턴스에는 프로토타입을 가리키는 프로토타입 속성이 있습니다. 이 속성은 JavaScript 상속을 유지하는 기초이기 때문에 액세스할 수 없으며 물론 수정할 수도 없습니다.

코드 복사 코드는 다음과 같습니다.

//생성자 선언
함수 Guoyansi(){ }
함수 GuoyansiEx(){}
//프로토타입 상속
​​​​​ GuoyansiEx.prototype=new Guoyansi();
//객체 생성
      var g1=new GuoyansiEx();
      var g2=new GuoyansiEx();

위 코드의 객체는 다음 다이어그램으로 설명할 수 있습니다

2. 프로토타입 유지관리

생성자에 의해 생성된 인스턴스의 생성자 속성은 항상 생성자를 가리킵니다. 우리는 일시적으로 이것이 맞다고 생각합니다.

코드 복사 코드는 다음과 같습니다.

함수 Guoyansi(){ }
var obj1=new Guoyansi();
console.log(obj1.constructor===Guoyansi);//true

사실 생성자 자체에는 생성자 속성이 없는데 이 속성은 어디서 오는 걸까요?
대답은 프로토타입에서 나온 것입니다.
따라서 다음과 같은 결론이 도출된다

코드 복사 코드는 다음과 같습니다.
obj1.constructor===Guoyansi.prototype.constructor= ==궈옌시

생성자를 통해 생성자를 찾을 수 있으므로 위 다이어그램을 더욱 개선할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

함수 GuoyansiEx(){}
                              GuoyansiEx.prototype=new Guoyansi();
console.log(GuoyansiEx.constructor===GuoyansiEx)//false

위 사진을 보면 위 결과가 사실이어야 하는데 왜 거짓일까요?

이제 분석해 보겠습니다.
GuoyansiEx의 프로토타입은 Guoyansi 인스턴스로 다시 작성되었으므로 GuoyansiEx 프로토타입의 생성자는 당연히 Guoyansi 인스턴스에서 왔습니다.
Guoyansi 인스턴스의 생성자는 Guoyansi.prototype에서 왔으며 Guoyansi.prototype은 다시 작성되지 않았습니다.
따라서 Guoyansi.prototype의 생성자는 Guoyansi(생성자)를 가리킵니다.

위의 분석을 바탕으로 다음과 같은 결론을 내립니다

코드 복사 코드는 다음과 같습니다.
GuoyansiEx.constructor===Guoyansi.constructor=== 궈옌시;

개발 과정에서 생성자의 방향이 매우 정확하다면 다음과 같이 할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

/**방법 1:**/
함수 Guoyansi(){}
함수 GuoyansiEx(){}
                              GuoyansiEx.prototype=new Guoyansi();
>            GuoyansiEx.prototype.constructor=GuoyansiEx;//생성자 포인터를 재설정합니다.

코드 복사 코드는 다음과 같습니다.

/**
방법 2
            **/
함수 Guoyansi(){}
함수 GuoyansiEx(){
This.constructor=arguments.callee;
            }
​​​​​​ GuoyansiEx.prototype=new Guoyansi();

코드 복사 코드는 다음과 같습니다.

/**
방법 3
            **/
함수 Guoyansi(){}
함수 GuoyansiEx(){
This.constructor=GuoyansiEx;
            }
​​​​​​ GuoyansiEx.prototype=new Guoyansi();

3. 보이지 않는 프로토타입의 용도는 무엇인가요?

보이는 프로토타입 체인을 작동하여 상속을 완료할 수 있지만 이 보이지 않는 프로토타입 체인을 볼 수도 없고 작동할 수도 없습니다.
객체 지향의 상속에는 유사성이라는 특성이 있습니다. 따라서 하위 클래스에서는 상위 클래스에서 상속된 멤버를 삭제하는 데 사용할 수 없습니다.
이 기능을 유지하기 위해 JavaScript는 우리가 볼 수 없고 사용자가 액세스하는 것을 허용하지 않는 객체 내부에 프로토타입 속성을 생성합니다. 이러한 방식으로 사용자는 어떤 목적으로든 생성자를 수정할 수 있습니다.
하위 클래스가 가지고 있는 상위 클래스의 특성을 파괴하지 않습니다.
간단히 말해서, JavaScript의 프로토타입 상속 메커니즘에는 내부 프로토타입이 필요하고, 상속을 구현하려면 사용자에게 외부 프로토타입이 필요합니다.

4. Firefox 엔진 SpiderMonkey의 __proto__

여전히 이 코드입니다.

코드 복사 코드는 다음과 같습니다.

함수 Guoyansi(){}
                 Guoyansi.prototype.age=24;
함수 GuoyansiEx(){}
            var obj1=new Guoyansi();
                          GuoyansiEx.prototype=obj1;
​​​​​​ GuoyansiEx.prototype.constructor=GuoyansiEx;//생성자 포인터 재설정.
            var obj2=new GuoyansiEx();

이제 obj부터 상위 클래스 Guoyansi의 프로토타입 속성 나이에 액세스하고 싶습니다.
아이디어는 이렇습니다.
1단계: obj2====>obj2.constructor.prototype
2부: obj2.constructor.prototype===>GuoyansiEx.prototype;
3부: GuoyansiEx.prototype===>obj1;
4부: obj1.constructor====>Guoyansi
5부: Guoyansi.prototype.age

다음과 같이 작성하세요: console.log(obj2.constructor.prototype.constructor.prototype.age)//24;
최종 결과는 24입니다.
최종 결과는 24입니다. 정상적으로 실행이 가능하지만, 생성자를 수정한 후 상위 클래스의 프로토타입을 찾을 수 없다고 하는 책이 많습니다.

Firefox._proto_에 더욱 간결한 속성을 도입했습니다.
SpiderMonkey는 기본적으로 생성된 모든 객체에 _proto_라는 속성을 추가하며, 이는 생성자가 사용하는 프로토타입을 가리킵니다.
사실 위에서 언급한 보이지 않는 프로토타입 체인인데 여기서는 위장해서 공개한 것 뿐입니다
나이
이렇게 접근할 수 있습니다 console.log(obj2.__proto__.__proto__.age);//24
이는 실제로 상위 클래스의 프로토타입 속성에 성공적으로 액세스하지만 이 속성은 Firefox에만 적용 가능하며 다른 브라우저에서는 오류가 발생합니다.
E5에서는 Object.getPrototypeOf()가 Object로 확장되었으며 모든 상위 클래스의 프로토타입에 액세스할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

함수 Guoyansi(){}
                 Guoyansi.prototype.age=24;
함수 GuoyansiEx(){}
            var obj1=new Guoyansi();
                          GuoyansiEx.prototype=obj1;
​​​​​​ GuoyansiEx.prototype.constructor=GuoyansiEx;//생성자 포인터 재설정.
            var obj2=new GuoyansiEx();
          var proto=Object.getPrototypeOf(obj2);
             동안(프로토){
console.log(proto.constructor);
                   proto=Object.getPrototypeOf(proto);
            }
console.log("객체 프로토타입" proto);

결과는: GuoyansiEx
궈옌시
객체
객체의 프로토타입이 null입니다

개인적으로는 이것이 객체지향 JavaScript의 핵심 중 하나로 간주되어야 한다고 생각합니다. 친구들이 직접 참고하고 필요에 따라 자신의 프로젝트에 사용하시기 바랍니다

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.