>  기사  >  웹 프론트엔드  >  자바스크립트 프로토타입 체인 면접 질문 분석(상세)

자바스크립트 프로토타입 체인 면접 질문 분석(상세)

不言
不言원래의
2018-09-19 17:12:065602검색

본 글의 내용은 자바스크립트 프로토타입 체인에 대한 인터뷰 질문에 대한 분석(상세)입니다. 참고할만한 가치가 있으니 도움이 필요한 분들에게 도움이 되었으면 좋겠습니다.

기본 앞에서는 모든 실력이 헛된 것입니다.

질문은 이렇습니다

콘솔의 출력을 작성해야 합니다.

function Parent() {
            this.a = 1;
            this.b = [1, 2, this.a];
            this.c = { demo: 5 };
            this.show = function () {
                console.log(this.a , this.b , this.c.demo );
            }
        }
function Child() {
    this.a = 2;
    this.change = function () {
        this.b.push(this.a);
        this.a = this.b.length;
        this.c.demo = this.a++;
    }
}
        Child.prototype = new Parent(); 
        var parent = new Parent();
        var child1 = new Child();
        var child2 = new Child();
        child1.a = 11;
        child2.a = 12;
        parent.show();
        child1.show();
        child2.show();
        child1.change();
        child2.change();
        parent.show();
        child1.show();
        child2.show();

질문에 관련된 지식 포인트

  • 이것은

  • 프로토타입 기계 프로토타입 체인

  • 클래스 상속

    을 가리킵니다.
  • 원시 유형과 참조 유형의 차이점
    모든 지식 포인트는 별도의 특수 연구를 위해 추출될 수 있습니다.

문제 해결에 필요한 지식 포인트의 세부 사항

1. 생성자는 생성자의 프로토타입 객체를 가리키는 프로토타입 속성을 가지며, 인스턴스는 동일한 프로토타입 객체를 공유합니다.

2. 새로운 힙 메모리가 메모리에 생성되고, 인스턴스에 대한 일반 작업은 힙 메모리에서 서로 다른 공간을 차지하고 서로 영향을 주지 않기 때문에 다른 인스턴스에 영향을 주지 않습니다.

3. 암시적 프로토타입 __proto__가 생성자의 프로토타입 객체를 가리킵니다.

4. 이 포인팅 문제의 일반적인 상황은 다음과 같습니다.

4.1 객체 메서드로 사용되는 경우 이를 호출하는 사람은 누구를 가리킵니다(이 질문은 주로 이 글과 관련이 있습니다)

4.2 함수로 호출될 때 전역 최상위 변수인 window를 가리킬 때

4.3 생성자로 호출될 때, 즉 new 연산자가 인스턴스를 생성할 때 생성자 내에서 인스턴스를 가리킵니다

4.4 호출 및 적용 메소드에서 지정된 this의 바인딩이 지정된 컨텍스트로 표시됩니다

5. 리터럴 방식(리터럴을 직접 수량으로 변환하는 정보도 있는데 개인적으로 후자라고 생각합니다) 실제로 번역이 더 직관적이고 생생합니다) 객체와 배열을 할당할 때(배열의 본질도 객체입니다) 모두 참조입니다. 즉, 힙 메모리에서 리소스를 생성하고, 스택 메모리에서 변수를 생성한 다음 변수를 리소스의 주소를 가리킵니다.

6 프로토타입 체인의 검색 규칙은 최단 경로 원칙을 따릅니다. 즉, 먼저 인스턴스 속성을 검색한 다음 프로토타입 끝에 Object.prototype이 있고 null이 될 때까지 프로토타입 체인을 따라 지정된 속성을 검색합니다. chain.인스턴스 자체와 프로토타입 체인 전체가 존재하지 않는 경우, undefine이 반환됩니다

7. 기본 값 할당과 참조 유형 할당에 대한 할당문의 세부 차이점

질문 분석 시작

1.parent.show()

기본적으로 설명할 내용은 없습니다.
값을 직접 취하면 답을 얻을 수 있습니다1 [1,2,1] 51 [1,2,1] 5;

2.child1.show()

Child的构造函数原本是指向Child
자바스크립트 프로토타입 체인 면접 질문 분석(상세)
题目中显式将Child类的原型对象指向了Parent类的一个实例,这是javascript面向对象编程中常见的继承方式之一。此处需要注意Child.prototype指向的是Parent的实例parent,而不是指向Parent这个类
자바스크립트 프로토타입 체인 면접 질문 분석(상세)
直接在控制台操作输出答案可得11 [1,2,1] 5
자바스크립트 프로토타입 체인 면접 질문 분석(상세)

此处令人迷惑的是this.b指向的数组最后一列为什么是1而不是11;


2.child1.show()자바스크립트 프로토타입 체인 면접 질문 분석(상세)

Child 생성자는 원래 Child

자바스크립트 프로토타입 체인 면접 질문 분석(상세)

Title을 가리켰습니다. Child 클래스의 프로토타입 개체가 Parent 클래스의 인스턴스를 명시적으로 가리킵니다. 이는 JavaScript 개체의 일반적인 상속 방법 중 하나입니다. 프로그래밍 지향. 여기서 Child.prototypeParent 클래스가 아니라 Parent의 인스턴스 parent를 가리킨다는 점에 유의해야 합니다.

자바스크립트 프로토타입 체인 면접 질문 분석(상세)
답변을 콘솔에 직접 출력할 수 있습니다11 [ 1 ,2,1] 5
자바스크립트 프로토타입 체인 면접 질문 분석(상세)

여기에서 주문하세요 사람들을 혼란스럽게 만드는 것은 this.b가 가리키는 배열의 마지막 열이 11가 아닌 1인 이유입니다.
  1. 먼저 child1이 어떻게 보이는지 살펴보겠습니다. like:

    자바스크립트 프로토타입 체인 면접 질문 분석(상세)child1 .show() 메서드를 실행할 때 Child의 인스턴스인 child1은 a 속성을 가지므로 show() 메서드의 this.a는 이 속성의 값을 직접 가리킵니다. 11이고 프로토타입을 따라 계속되지 않습니다. 체인은 __proto__가 가리키는 객체에 대한 a 속성을 얻습니다.

    그런 다음 child1에는 b 속성이 없으므로 b 속성을 얻습니다. 프로토타입 체인을 따라 부모이고 그 값은 배열입니다. 배열의 마지막 항목은 참조이고 여기 포인터는 동적 포인터가 아닙니다. new Parent() 단계에서 이미 한 번 실행되었으며 parent.a가 가리키는 리소스는 값 1인 child1.__proto__의 a 속성이 가리키는 리소스입니다.


    확장된 사고

다음 사항에 유의해야 합니다.


코드 관점에서 child1.__proto__.b 배열의 세 번째 항목은 child1.__proto__.a를 가리킨 다음 child1.__proto__를 수정합니다. 이때 a의 값이 child1.show()의 결과에 영향을 미치나요?


  • 답은 '아니요'입니다. 동일한 주소를 가리키는 속성이 다른 값을 갖는 이유는 무엇입니까? 상위 인스턴스가 생성될 때 this.a는 기본 값 2를 가리키므로 this.b의 세 번째 항목은 실제로 기본 값이 할당되므로 언뜻 참조 유형 할당처럼 보이지만 그렇지 않습니다. . 기본 값 할당은 새로운 저장 공간을 열어 this.a와 this.b[2]의 값을 동일하게 만들지만 힙 메모리의 다른 주소를 가리킵니다. 자세한 설명은 [확장 읽기]에서 추천하는 블로그 포스트를 참고해주세요. 자바스크립트 프로토타입 체인 면접 질문 분석(상세)
    자바스크립트 프로토타입 체인 면접 질문 분석(상세)

  • 2. child1.__proto__.b 배열의 세 번째 항목도 11을 출력하도록 하려면 어떻게 해야 하나요?
인스턴스화 후 수정하세요Parent 클래스 정의에서 b 속성 배열의 세 번째 항목은 다음을 가리킵니다. a 속성의 값은 Parent가 인스턴스화되기 전에 이 참조가 동적으로 지정된다는 것을 의미하므로, Parent가 인스턴스화되기 전에 클래스 정의의 this.a 값이 변경되는 한 원하는 효과를 얻을 수 있습니다. 부모가 인스턴스화되었으면 *.b[2] 속성의 값을 명시적으로 수정할 수만 있습니다.
get/set 메소드 동기화

또 다른 방법은 a 속성에 대한 get/set 메소드를 설정하는 것입니다. 예, a 속성 값이 변경될 때마다 b[2] 값이 동기적으로 수정됩니다. 표시:

3.child2.show()


위의 설명을 이해했다면 여기서도 동일한 논리로 답을 얻을 수 있습니다. 12 [1, 2,1] 5
🎜🎜🎜🎜다음 코드가 실행됩니다. child1.change(); child2.change();🎜🎜🎜🎜4.parent.show()🎜🎜🎜🎜parent는 Parent의 인스턴스입니다. 클래스 및 Child.prorotype은 Parent 클래스의 또 다른 인스턴스입니다. 이들은 힙 메모리에 있는 두 리소스이며 서로 영향을 주지 않습니다. 따라서 위 작업은 상위 인스턴스에 영향을 주지 않습니다. 1 [1,2,1] 5;🎜 🎜
5.child1.show(),child2.show()

child1이change() 메서드를 실행한 후 어떤 변화가 발생했나요?

this.b.push(this.a)
이 동적 포인팅 기능으로 인해 this.b는 Child.prototype의 b 배열을 가리키고, this.a는 child1의 a 속성을 가리키므로 Child.prototype.b는 [1,2,1,11];

this .a = this.b.length
이 명령문에서 this.a 및 this.b의 방향은 이전 문장과 일치하므로 결과는 child1.a가 4;

this.c.demo = this 가 됩니다. a++
child1의 자체 속성에는 c 속성이 없으므로 여기서 this.c는 Child.prototype.c를 가리킵니다. this.a의 값은 4이므로 기본 유형으로 값이 할당됩니다. Child.prototype.c.demo의 결과는 4이고, this.a는 5(4 + 1 = 5)로 증가합니다.

그런 다음 child2는change() 메서드를 실행합니다. , child2와 child1은 모두 Child 클래스의 인스턴스이므로 해당 프로토타입 체인은 동일한 상위 인스턴스인 동일한 프로토타입 개체 Child.prototype을 가리키므로 그래서 최종 출력 결과는 child2.change()中所有影响到原型对象的语句都会影响child1

this.b입니다. push(this.a)

이것의 동적 포인팅 특성으로 인해 this.b는 Child.prototype의 b 배열을 가리키고 this.a는 child2의 a 속성을 가리키므로 Child.prototype이 됩니다. b는

[1,2,1,11, 12];

this.a = this.b.length
이 명령문에서 this.a 및 this.b의 방향은 이전 문장과 일치합니다. 따라서 결과는 child2.a가 5가 됩니다.

this.c.demo = this.a++
child2의 자체 속성에는 c 속성이 없으므로 여기의 this.c는 Child.prototype.c를 가리킵니다. 실행 결과 Child.prototype.c.demo의 값은 child2가 됩니다. .a의 값은 5이고, child2.a는 결국 6(5 + 1 = 6)으로 증가합니다.

다음으로 출력 명령을 실행하고, 최종 결과는 다음과 같이 출력됩니다:
child1.show():5 [1,2, 1,11,12] 5
child2.show():6 [1,2,1,11,12] 5

확장된 사고
문제를 풀다보니 this.c.demo = this. 여기서 참조가 전달될 줄 알았는데, 실제로는 값이 전달되었습니다. this.a가 원래 값을 가리키기 때문에 이는 개체 속성에 원래 값을 할당하는 것과 동일하므로 할당 후에는 child.c의 값이 child.a의 변경에 의해 더 이상 영향을 받지 않습니다. child.a가 참조 유형인 경우 결과는 어떻게 되나요?
소스 코드를 일부 수정하고 child.a가 객체(예: 참조 유형)를 가리키도록 합니다. 자바스크립트 프로토타입 체인 면접 질문 분석(상세)
그런 다음 실행한 후 Child.prototype.c의 값이 child1의 변경에 따라 변경되는 것을 확인할 수 있습니다. a, 왜냐하면 child1.a의 값이 참조 유형일 때 할당 프로세스는 Child.prototype.c와 child1.a가 동일한 리소스의 메모리 공간 주소를 가리키도록 만들기 때문입니다. 원본 유형과 참조 유형에 대한 자세한 설명은 이 기사 끝에 있는 확장 읽기의 블로그를 참조할 수 있습니다.

수확과 성찰

1. 기본 지식은 본질적으로 세부 사항이 분산되어 있어 끝까지 끈기 있게 학습해야 합니다.

2. 기본 지식은 가장 지루하고, 사람 사이의 격차를 실제로 넓히는 요소이기도 합니다. 중요하지만 급하지는 않습니다. 우리도 초보자입니다. 어떤 사람들은 3~5년 후에 프런트엔드 설계자가 될 것입니다. 어떤 사람들은 3~5년 후에 이벤트를 버튼에 바인딩하기 위해 계속해서 새로운 프레임워크를 사용할 것입니다. 넣다. , 대부분의 경우 아무런 문제가 없습니다. 기초가 정말 중요해요! 매우 중요합니다! 매우 중요합니다!

위 내용은 자바스크립트 프로토타입 체인 면접 질문 분석(상세)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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