이번에는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!