본 글의 내용은 자바스크립트 프로토타입 체인에 대한 인터뷰 질문에 대한 분석(상세)입니다. 참고할만한 가치가 있으니 도움이 필요한 분들에게 도움이 되었으면 좋겠습니다.
기본 앞에서는 모든 실력이 헛된 것입니다.
콘솔의 출력을 작성해야 합니다.
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 [1,2,1] 5
1 [1,2,1] 5
;
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.prototype
는 Parent
클래스가 아니라 Parent
의 인스턴스 parent
를 가리킨다는 점에 유의해야 합니다.
11 [ 1 ,2,1] 5
11
가 아닌 1
인 이유입니다.child1 .show() 메서드를 실행할 때 Child의 인스턴스인 child1은 a 속성을 가지므로 show() 메서드의 this.a는 이 속성의 값을 직접 가리킵니다. 11이고 프로토타입을 따라 계속되지 않습니다. 체인은 __proto__가 가리키는 객체에 대한 a 속성을 얻습니다.
다음 사항에 유의해야 합니다.
답은 '아니요'입니다. 동일한 주소를 가리키는 속성이 다른 값을 갖는 이유는 무엇입니까? 상위 인스턴스가 생성될 때 this.a는 기본 값 2를 가리키므로 this.b의 세 번째 항목은 실제로 기본 값이 할당되므로 언뜻 참조 유형 할당처럼 보이지만 그렇지 않습니다. . 기본 값 할당은 새로운 저장 공간을 열어 this.a와 this.b[2]의 값을 동일하게 만들지만 힙 메모리의 다른 주소를 가리킵니다. 자세한 설명은 [확장 읽기]에서 추천하는 블로그 포스트를 참고해주세요.
또 다른 방법은 a 속성에 대한 get/set 메소드를 설정하는 것입니다. 예, a 속성 값이 변경될 때마다 b[2] 값이 동기적으로 수정됩니다. 표시:
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!