질문 : JavaScript .prototype은 어떻게 작동합니까?
나는 동적 프로그래밍 언어는 아니지만 JavaScript 코드의 공정한 부분을 작성했습니다. 저는이 프로토 타입 기반 프로그래밍에 대해 전혀 몰랐습니다. 이것이 어떻게 작동하는지 아는 사람이 있습니까?
var obj = new Object();
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();
예전에 사람들과 많은 토론을했던 기억이납니다 (내가 뭘하고 있는지 정확히 모르겠습니다).하지만 이해하기 때문에 수업의 개념은 없습니다. 그것은 단지 하나의 개체이고 그 개체의 인스턴스는 원본의 복제물입니다.
그러나 JavaScript에서이 ".prototype"속성의 정확한 목적은 무엇입니까? 개체를 인스턴스화하는 것과 어떤 관련이 있습니까?
var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert('Hello?'); }; // this is wrong!
function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert('OK'); } // OK
또한이 슬라이드는 정말 많은 도움이되었습니다.
답변
모든 자바 스크립트 객체에는 값이 null
또는 object
[[Prototype]]
이라는 내부 "슬롯" 이 있습니다. 슬롯은 작성한 코드에서 숨겨져있는 JavaScript 엔진 내부의 객체에 대한 속성으로 생각할 수 있습니다. [[Prototype]]
주위의 대괄호는 의도적이며 내부 슬롯을 나타내는 ECMAScript 사양 규칙입니다.
[[Prototype]]
이 가리키는 값을 구어체로 "그 개체의 프로토 타입"이라고합니다.
obj.propName
) 또는 대괄호 ( obj['propName']
) 표기법을 통해 속성에 액세스하고 객체에 이러한 속성 (즉, obj.hasOwnProperty('propName')
통해 확인할 수있는 자체 속성)이 직접 포함되지 않은 경우 obj.hasOwnProperty('propName')
), 런타임은 대신 [[Prototype]]
참조하는 객체에서 해당 이름을 가진 속성을 찾습니다. [[Prototype]]
에도 이러한 속성이 없으면 [[Prototype]]
이 차례로 선택됩니다. 이런 식으로 원래 개체의 프로토 타입 체인 은 일치하는 항목을 찾거나 끝점에 도달 할 때까지 걸어갑니다. 프로토 타입 체인의 맨 위에는 null
값이 있습니다.
최신 JavaScript 구현은 다음과 같은 방법으로 [[Prototype]]
에 대한 읽기 및 / 또는 쓰기 액세스를 허용합니다.
- 새 연산자(생성자 함수에서 반환되는 기본 객체의 프로토타입 체인 구성)
- 확장 키워드(클래스 구문을 사용할 때 프로토타입 체인을 구성함)
- Object.create는 제공된 인수를 결과 개체의 [[Prototype]] 으로 설정합니다.
- Object.getPrototypeOf 및 Object입니다.PrototypeOf 설정(개체 생성 후 [Prototype] 가져오기/설정) 및
- __proto__라는 이름의 표준화된 접근자(즉, getter/setter) 속성입니다. (4와 유사)
Object.getPrototypeOf
및 Object.setPrototypeOf
__proto__
보다 선호됩니다. 부분적으로 null
의 프로토 타입을 가질 때 o.__proto__
의 동작이 비정상적 이기 때문입니다.
개체의 [[Prototype]]
은 개체 생성 중에 초기 설정됩니다.
new Func()
를 통해 새 객체를 생성하는 경우 객체의 [[Prototype]]
Func.prototype
참조하는 객체로 설정됩니다.
따라서 new
연산자와 함께 사용할 수있는 모든 클래스 및 모든 함수에는 자체 [[Prototype]]
내부 슬롯 .prototype
이라는 속성이 있습니다. "프로토 타입"이라는 단어의 이러한 이중 사용은 언어를 처음 접하는 사람들 사이에서 끊임없는 혼란의 근원입니다.
new
with 생성자 함수를 사용하면 JavaScript에서 고전적인 상속을 시뮬레이션 할 수 있습니다. JavaScript의 상속 시스템은-우리가 본 것처럼-프로토 타입이며 클래스 기반이 아닙니다.
JavaScript에 클래스 구문을 도입하기 전에는 생성자 함수가 클래스를 시뮬레이션하는 유일한 방법이었습니다. 생성자 함수의 .prototype 속성이 참조하는 객체의 속성을 공유 멤버로 .prototype
즉. 각 인스턴스에 대해 동일한 구성원. 클래스 기반 시스템에서 메서드는 각 인스턴스에 대해 동일한 방식으로 구현되므로 개념적으로 .prototype
속성에 메서드가 추가됩니다. 그러나 개체의 필드는 인스턴스에 따라 다르므로 구성 중에 개체 자체에 추가됩니다.
클래스 구문이 없으면 개발자는 기존 상속과 유사한 기능을 달성하기 위해 프로토 타입 체인을 수동으로 구성해야했습니다. 이로 인해이를 달성하기위한 다양한 방법이 우세하게되었습니다.
한 가지 방법은 다음과 같습니다.
function Child() {}
function Parent() {}
Parent.prototype.inheritedMethod = function () { return 'this is inherited' }
function inherit(child, parent) {
child.prototype = Object.create(parent.prototype)
child.prototype.constructor = child
return child;
}
Child = inherit(Child, Parent)
const o = new Child
console.log(o.inheritedMethod()) // 'this is inherited'
... 또 다른 방법이 있습니다.
function Child() {}
function Parent() {}
Parent.prototype.inheritedMethod = function () { return 'this is inherited' }
function inherit(child, parent) {
function tmp() {}
tmp.prototype = parent.prototype
const proto = new tmp()
proto.constructor = child
child.prototype = proto
return child
}
Child = inherit(Child, Parent)
const o = new Child
console.log(o.inheritedMethod()) // 'this is inherited'
ES2015에 도입 된 클래스 구문은 JavaScript에서 고전적인 상속을 시뮬레이션하기 위해 프로토 타입 체인을 구성하는 "하나의 진정한 방법"으로 extends
따라서 위의 코드와 유사하게 클래스 구문을 사용하여 다음과 같이 새 객체를 생성하는 경우 :
class Parent { inheritedMethod() { return 'this is inherited' } }
class Child extends Parent {}
const o = new Child
console.log(o.inheritedMethod()) // 'this is inherited'
... 결과 객체의 [[Prototype]]
[[Prototype]]
이 다시 Parent.prototype
인 Parent
의 인스턴스로 설정됩니다.
Object.create(foo)
를 통해 새 객체를 생성하면 결과 객체의 [[Prototype]]
foo
로 설정됩니다.
출처 : https://stackoverflow.com/questions/572897/how-does-javascript-prototype-work
'프로그래밍 언어 > HTML,CSS,JS' 카테고리의 다른 글
JavaScript에서 문자열을 Base64로 인코딩하는 방법 (0) | 2021.07.28 |
---|---|
HTML 레이아웃에 테이블을 사용하지 않는 이유 (0) | 2021.07.27 |
JavaScript 문자열 개행 문자 (0) | 2021.07.27 |
React.js의 상태 배열 수정 (0) | 2021.07.27 |
JavaScript에서 스택과 큐를 구현하는 방법 (0) | 2021.07.27 |