>  기사  >  웹 프론트엔드  >  JavaScript_Basic 지식을 통해 __proto__와 프로토타입의 관계에 대한 심층적인 이해

JavaScript_Basic 지식을 통해 __proto__와 프로토타입의 관계에 대한 심층적인 이해

WBOY
WBOY원래의
2016-05-16 17:47:26891검색

여기서는 객체의 내부 프로토타입(__proto__)과 생성자의 프로토타입(prototype) 사이의 관계에 대해 논의합니다.
1. 모든 생성자/함수의 __proto__는 빈 함수(빈 함수)인 Function.prototype을 가리킵니다.

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

Number.__proto__ === Function.prototype // true
Boolean.__proto__ === Function.prototype // true
String. __proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
Array.__proto__ === 함수 . 프로토타입 // true
RegExp.__proto__ === Function.prototype // true
Error.__proto__ === Function.prototype // true
Date.__proto__ === Function.prototype // true

JavaScript에는 총 12개의 내장 생성자/객체가 있습니다(JSON은 ES5에 새로 추가되었습니다). 나머지 Global 등은 직접 접근이 불가능하고, Arguments는 함수 호출 시 JS 엔진에 의해서만 생성되며, Math와 JSON은 객체 형태로 존재하므로 new가 필요하지 않습니다. 그들의 __proto__는 Object.prototype입니다. 다음과 같습니다
코드 복사 코드는 다음과 같습니다.

Math.__proto__ === Object .prototype // true
JSON.__proto__ === Object.prototype // true

위에 언급된 "모든 생성자/함수"에는 확실히 사용자 지정 항목이 포함됩니다. 다음과 같습니다
코드 복사 코드는 다음과 같습니다.

// 함수선언
function Person() {}
// 함수 표현식
var Man = function() {}
console.log(Person.__proto__ === Function.prototype) // true
console.log (Man. __proto__ === Function.prototype) // true

무슨 뜻인가요?
모든 생성자는 Function.prototype에서 나오며 루트 생성자 Object와 Function 자체도 마찬가지입니다. 모든 생성자는 Function.prototype의 속성과 메서드를 상속합니다. 길이, 호출, 적용, 바인딩(ES5) 등이 있습니다.
Function.prototype은 XXX.prototype 유형이 "function"인 유일한 프로토타입이기도 합니다. 다른 생성자의 프로토타입은 객체입니다. 다음과 같습니다
코드 복사 코드는 다음과 같습니다.

console.log(typeof Function. 프로토타입) // 함수
console.log(typeof Object.prototype) // 객체
console.log(typeof Number.prototype) // 객체
console.log(typeof Boolean.prototype) // 객체
console .log(typeof String.prototype) // 객체
console.log(typeof Array.prototype) // 객체
console.log(typeof RegExp.prototype) // 객체
console. log(typeof Error .prototype) // 객체
console.log(typeof Date.prototype) // 객체
console.log(typeof Object.prototype) // 객체

아 , 위에서도 언급한 바 있습니다. 이는 빈 함수임이 밝혀졌습니다. Alert(Function.prototype)를 살펴보세요.
우리는 모든 생성자(내장 및 사용자 정의 포함)의 __proto__가 Function.prototype이라는 것을 알고 있는데, Function.prototype의 __proto__는 누구입니까?
JavaScript의 함수도 일급 시민이라는 말을 들어보셨을 텐데요, 이를 어디서 보여줄 수 있나요? 다음과 같습니다
코드를 복사합니다 코드는 다음과 같습니다.

console.log(Function. 프로토타입.__proto__ == = Object.prototype) // true

이는 모든 생성자도 일반 JS 객체이며 생성자에 속성을 추가/제거할 수 있음을 보여줍니다. 동시에 Object.prototype의 모든 메소드(toString, valueOf, hasOwnProperty 등)도 상속합니다.
Object.prototype의 __proto__는 누구인가요?
코드 복사 코드는 다음과 같습니다.

Object.prototype.__proto__ === null // true

이 최상위에 도달했으며 null입니다.
2. 모든 객체의 __proto__는 생성자의 프로토타입을 가리킵니다.
모든 내장 생성자와 사용자 정의 생성자의 __proto__는 위에서 테스트되었습니다. 생성자. _proto__는 누구를 가리킵니까?
자바스크립트 엔진에 내장된 생성자를 먼저 살펴보겠습니다
코드 복사 코드는 다음과 같습니다. :

var obj = {name: 'jack'}
var arr = [1,2,3]
var reg = /hello/g
var date = 새 날짜
var err = new Error('Exception')
console.log(obj.__proto__ === Object.prototype) // true
console.log(arr.__proto__ === Array.prototype) // true
console.log(reg.__proto__ === RegExp.prototype) // true
console.log(date.__proto__ === Date.prototype) // true
console.log(err.__proto__ === Error.prototype) // true

맞춤 생성자를 다시 보면 여기에 Person이 정의되어 있습니다.
코드 복사 코드는 다음과 같습니다.

function Person(name) {
this.name = name
}
var p = new Person(' jack ')
console.log(p.__proto__ === Person.prototype) // true

p는 Person의 인스턴스 객체이며 p의 내부 프로토타입은 항상 Person을 가리킵니다. 생성자 프로토타입.
각 객체에는 생성자를 가져올 수 있는 생성자 속성이 있으므로 다음 인쇄 결과도 동일합니다.
코드 복사 코드는 다음과 같습니다:

function Person(name) {
this.name = name
}
var p = new Person('jack')
console . log(p.__proto__ === p.constructor.prototype) // true

위의 Person은 프로토타입에 속성이나 메소드를 추가하지 않습니다. 여기서는 프로토타입에 getName 메소드를 추가합니다. >
코드 복사 코드는 다음과 같습니다.
function Person(name) {
this. name = 이름
}
// 프로토타입 수정
Person.prototype.getName = function() {}
var p = new Person('jack')
console.log(p. __proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // true

p.__proto__ 및 Person을 볼 수 있습니다. .prototype, p.constructor.prototype은 모두 동일합니다. 즉, 모두 동일한 객체를 가리킵니다.
프로토타입을 다른 방식으로 설정하면 결과가 조금 달라집니다

코드를 복사하세요 코드는 다음과 같습니다:
function Person(name) {
this.name = name
}
// 프로토타입 재정의
Person.prototype = {
getName: function() {}
}
var p = new Person('jack')
console.log(p.__proto__ === Person.prototype) // true
console.log(p .__proto__ === p. constructor.prototype) // false

Person.prototype은 여기서 직접 다시 작성됩니다(참고: 이전 예는 프로토타입을 수정하는 것입니다). 출력에는 p.__proto__가 여전히 p.constructor.prototype이 아닌 Person.prototype을 가리키는 것으로 표시됩니다.
이 역시 이해하기 쉽습니다. Person.prototype에 할당된 것은 객체 리터럴 {getName: function(){}}입니다. 객체 리터럴 메서드를 사용하여 정의된 객체의 생성자는 루트 생성자를 가리킵니다. Object.prototype은 빈 객체 {}이며, {}는 당연히 {getName: function(){}}과 다릅니다. 다음과 같습니다

코드를 복사합니다 코드는 다음과 같습니다.
var p = {}
console.log (Object.prototype) // 빈 객체입니다 {}
console.log(p.constructor === Object) // 객체 리터럴 모드에서 정의된 객체의 생성자는 Object
console.log(p .constructor.prototype === Object.prototype) // true이면 설명이 제공되지 않습니다

위 코드에 사용된 __proto__는 현재 IE6에서 지원되지 않습니다/ 7/8/9. IE9에서는 Object.getPrototypeOf(ES5)를 사용하여 객체의 내부 프로토타입을 가져올 수 있습니다.

코드 복사 코드는 다음과 같습니다.
var p = {}
var __proto__ = 객체 .getPrototypeOf(p)
console.log(__proto__ === Object.prototype) // true

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