>  기사  >  웹 프론트엔드  >  JavaScript에서 __proto__와 프로토타입 간의 관계에 대한 간략한 분석

JavaScript에서 __proto__와 프로토타입 간의 관계에 대한 간략한 분석

零到壹度
零到壹度원래의
2018-03-22 11:37:151117검색

이번에는 JavaScript에서 __proto__와 프로토타입의 관계에 대해 간략하게 분석하겠습니다. 다음은 실제 사례입니다.

1. 모든 생성자/함수의 __proto__는 빈 함수인 Function.prototype을 가리킵니다(Empty 함수)

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__ === Function.prototype   // true
RegExp.__proto__ === Function.prototype  // true
Error.__proto__ === Function.prototype   // true
Date.__proto__ === Function.prototype    // true

JavaScript에는 총 12개의 내장(빌드인) 생성자/객체가 있습니다(JSON은 ES5에 새로 추가되었습니다). 다음은 8개의 액세스 가능한 생성자입니다. 나머지 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의 유일한 유형이기도 합니다. "함수"의 프로토타입. 다른 생성자의 프로토타입은 객체입니다. 예를 들면:

console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype)   // object
console.log(typeof Number.prototype)   // object
console.log(typeof Boolean.prototype)  // object
console.log(typeof String.prototype)   // object
console.log(typeof Array.prototype)    // object
console.log(typeof RegExp.prototype)   // object
console.log(typeof Error.prototype)    // object
console.log(typeof Date.prototype)     // object
console.log(typeof Object.prototype)   // object

아, 위에서도 빈 함수라고 언급했는데, Alert(Function.prototype)를 살펴보겠습니다.

이제 모든 생성자(내장 및 사용자 정의 포함)의 __proto__가 Function.prototype이라는 것을 알았으니, 그렇다면 Function.prototype의 __proto__는 누구일까요?

JavaScript의 함수도 일급 시민이라는 말을 다들 들어보셨을 텐데요, 이것을 어떻게 보여줄 수 있을까요? 아래와 같이

console.log(Function.prototype.__proto__ === Object.prototype) // true

모든 생성자도 일반 JS 객체임을 알 수 있으며, 생성자에 속성을 추가/제거할 수 있습니다. 동시에 Object.prototype의 모든 메소드(toString, valueOf, hasOwnProperty 등)도 상속합니다.

마지막으로 Object.prototype의 __proto__는 누구인가요?

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

이(가) 정상에 도달했으며 null입니다.

2. 모든 객체의 __proto__는 생성자의 프로토타입을 가리킵니다

위에서는 모든 내장 생성자와 사용자 정의 생성자의 __proto__를 테스트했습니다. 생성자. _proto__는 누구를 가리킵니까?

먼저 JavaScript 엔진의 내장 생성자를 살펴보세요

var obj = {name: 'jack'}
var arr = [1,2,3]
var reg = /hello/g
var date = new 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 = 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를 가리킵니다. Object.prototype은 빈 객체입니다. {}, {}는 당연히 {getName: function(){}}이 동일하지 않습니다. 다음과 같습니다

var p = {}
console.log(Object.prototype) // 为一个空的对象{}
console.log(p.constructor === Object) // 对象直接量方式定义的对象其constructor为Object
console.log(p.constructor.prototype === Object.prototype) // 为true,不解释

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

아아아아

위 내용은 JavaScript에서 __proto__와 프로토타입 간의 관계에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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