자바스크립트 프로토타입에 대한 심층적인 탐색은 프로토타입 상속_자바스크립트 기술만큼 간단하지 않습니다.
JavaScript에서 객체의 프로토타입 속성은 객체 유형의 프로토타입에 대한 참조를 반환할 수 있습니다. 다소 헷갈리는 설명입니다. 이를 이해하려면 먼저 객체 유형(Type)과 프로토타입(prototype)의 개념을 올바르게 이해해야 합니다.
1 프로토타입이란 무엇입니까
JavaScript에서 객체의 프로토타입 속성은 객체 유형의 프로토타입에 대한 참조를 반환할 수 있습니다. 다소 헷갈리는 설명입니다. 이를 이해하려면 먼저 객체 유형(Type)과 프로토타입(prototype)의 개념을 올바르게 이해해야 합니다.
앞서 객체의 클래스(Class)와 객체 인스턴스(Instance) 사이에 '생성' 관계가 있다고 말씀드렸습니다. 따라서 '클래스'를 객체 특성의 모델링으로, 객체를 클래스로 간주합니다. 특성 또는 클래스(Class)는 객체의 유형(Type)입니다. 예를 들어 이전 예에서 p1과 p2의 유형은 모두 Point입니다. JavaScript에서는 다음과 같이 instanceof 연산자를 통해 확인할 수 있습니다.
p1 instanceof Point
p2 instanceof Point
Point는 p1과 p2의 유일한 유형이 아니므로 Object는 Point보다 더 일반적인 클래스이므로 Object와 Point 사이에 파생된 관계가 있다고 말합니다. 이 관계를 "상속"이라고 한다는 것은 나중에 알 수 있습니다. 이는 객체 간의 일반화된 관계의 특수한 경우이며 객체지향에서는 없어서는 안 될 기본 관계입니다.
객체 지향 분야에서 설명 가능한 추상 관계의 쌍은 인스턴스와 유형만이 아닙니다. JavaScript에서 또 다른 중요한 추상 관계는 유형(Type)과 프로토타입(prototype)입니다. 이 관계는 더 높은 수준의 추상 관계로, 유형과 인스턴스 간의 추상 관계로 3계층 체인을 형성합니다.
실생활에서 우리는 어떤 것이 다른 것을 기반으로 한다고 종종 말합니다. 이 두 가지는 동일한 유형일 수도 있고 다른 유형일 수도 있습니다. "follow the gourd and draw the gourd"라는 관용어에서, 여기서 조롱박은 프로토타입이고, 조롱박은 타입을 표현하기 위해 "ladle.prototype = 특정 조롱박" 또는 "ladle.prototype = 새로운 조롱박"입니다. ()".
프로토타입을 깊이 이해하기 위해서는 디자인 패턴 중 하나인 프로토타입 패턴을 공부하면 됩니다. 이 패턴의 핵심은 프로토타입 인스턴스를 사용하여 생성할 객체의 유형을 지정하고, 이러한 프로토타입을 복사하여 새로운 객체를 생성하는 것입니다. JavaScript 프로토타입은 이 방법과 유사합니다.
프로토타입 패턴에 대한 자세한 내용은 "디자인 패턴"("Design Patterns")을 참조하세요. 이는 이 기사의 범위를 벗어납니다.
유형과 인스턴스 간의 관계와 달리 프로토타입과 유형 간의 관계에서는 유형이 한 번에 하나의 프로토타입만 가질 수 있어야 합니다(그리고 인스턴스는 분명히 한 번에 여러 유형을 가질 수 있습니다). JavaScript의 경우 이 제한에는 두 가지 의미가 있습니다. 첫 번째는 각 특정 JavaScript 유형에 하나의 프로토타입만 있다는 것입니다. 기본적으로 이 프로토타입은 Object 객체입니다(Object 유형이 아니라는 점에 유의하세요!). 두 번째는 이 객체가 속한 유형이 프로토타입 관계를 만족하는 유형 체인이어야 한다는 것입니다. 예를 들어 p1의 유형은 Point와 Object이고 Object 객체는 Point의 프로토타입입니다. ClassA, ClassB, ClassC 및 Object 유형의 객체가 있는 경우 이 네 가지 클래스는 완전한 프로토타입 체인을 형성해야 합니다.
흥미로운 점은 JavaScript가 유형의 프로토타입의 유형을 지정하지 않는다는 것입니다(이것은 또 다른 매우 어색한 진술입니다). 따라서 어떤 유형이든, 일반적으로 일종의 객체가 될 수 있으므로 객체-유형-프로토타입(객체 ) 링 구조 또는 기타 흥미로운 토폴로지 구조를 형성할 수 있습니다. 이러한 구조는 JavaScript에 다양한 용도를 제공하며 그 중 일부는 영리할 뿐만 아니라 아름다움도 가득합니다. 다음 섹션에서는 주로 프로토타입의 사용법을 소개합니다.
2가지 프로토타입 활용팁
프로토타입 활용 스킬을 이해하기 전에 먼저 프로토타입의 특성을 이해해야 합니다. 우선, JavaScript는 각 유형(Type)에 대한 프로토타입 속성을 제공합니다. 이 속성은 객체를 가리키며 이 객체는 이 유형의 "프로토타입"이 됩니다. 이는 이 유형으로 생성된 모든 객체가 프로토타입의 특성을 가짐을 의미합니다. . 또한 JavaScript 객체는 동적이며 프로토타입도 예외는 아닙니다. 프로토타입에 속성을 추가하거나 빼면 이 유형의 프로토타입이 변경됩니다. 예를 들면 다음과 같습니다.
<script> function Point(x,y) { this.x = x; this.y = y; } var p1 = new Point(1,2); var p2 = new Point(3,4); Point.prototype.z = 0; //动态为Point的原型添加了属性 alert(p1.z); alert(p2.z); //同时作用于Point类型创建的所有对象 </script>
객체 유형의 프로토타입에 a라는 속성이 추가되고, 객체 자체에 a라는 동일한 이름의 속성이 있는 경우, 객체의 a 속성에 접근하면 객체 자체의 속성 프로토타입 속성을 "덮지만" 프로토타입 속성은 사라지지 않습니다. 삭제 연산자를 사용하여 객체 자체의 속성 a를 삭제하면 객체의 프로토타입 속성이 다시 표시됩니다. 이 기능을 사용하면 객체의 속성에 대한 기본값을 설정할 수 있습니다. 예를 들면 다음과 같습니다.
<script> function Point(x, y) { if(x) this.x = x; if(y) this.y = y; } Point.prototype.x = 0; Point.prototype.y = 0; var p1 = new Point; var p2 = new Point(1,2); </script>
위의 예에서는 프로토타입을 통해 Point 객체의 기본값(0,0)을 설정하므로 p1의 값은 (0,0)이고, p2의 값은 (1,2)이며, p2.x를 삭제하고 p2.y를 삭제하여 p2의 값을 (0,0)으로 복원할 수 있습니다. 더 흥미로운 예는 다음과 같습니다.
<script> function classA() { this.a = 100; this.b = 200; this.c = 300; this.reset = function() { for(var each in this) { delete this[each]; } } } classA.prototype = new classA(); var a = new classA(); alert(a.a); a.a *= 2; a.b *= 2; a.c *= 2; alert(a.a); alert(a.b); alert(a.c); a.reset(); //调用reset方法将a的值恢复为默认值 alert(a.a); alert(a.b); alert(a.c); </script>
프로토타입을 사용하면 개체 속성에 대해 읽기 전용 getter를 설정하여 덮어쓰는 것을 방지할 수도 있습니다. 예는 다음과 같습니다.
<script> function Point(x, y) { if(x) this.x = x; if(y) this.y = y; } Point.prototype.x = 0; Point.prototype.y = 0; function LineSegment(p1, p2) { //私有成员 var m_firstPoint = p1; var m_lastPoint = p2; var m_width = { valueOf : function(){return Math.abs(p1.x - p2.x)}, toString : function(){return Math.abs(p1.x - p2.x)} } var m_height = { valueOf : function(){return Math.abs(p1.y - p2.y)}, toString : function(){return Math.abs(p1.y - p2.y)} } //getter this.getFirstPoint = function() { return m_firstPoint; } this.getLastPoint = function() { return m_lastPoint; } this.length = { valueOf : function(){return Math.sqrt(m_width*m_width + m_height*m_height)}, toString : function(){return Math.sqrt(m_width*m_width + m_height*m_height)} } } var p1 = new Point; var p2 = new Point(2,3); var line1 = new LineSegment(p1, p2); var lp = line1.getFirstPoint(); lp.x = 100; //不小心改写了lp的值,破坏了lp的原始值而且不可恢复 alert(line1.getFirstPoint().x); alert(line1.length); //就连line1.lenght都发生了改变 </script>
this.getFirstPoint()를 다음과 같이 다시 작성합니다.
this.getFirstPoint = function()
{
function GETTER(){}; GETTER.prototype = m_firstPoint;
return new GETTER();
}
는 이 문제를 방지하고 m_firstPoint 속성의 읽기 전용 특성을 보장할 수 있습니다.
<script> function Point(x, y) { if(x) this.x = x; if(y) this.y = y; } Point.prototype.x = 0; Point.prototype.y = 0; function LineSegment(p1, p2) { //私有成员 var m_firstPoint = p1; var m_lastPoint = p2; var m_width = { valueOf : function(){return Math.abs(p1.x - p2.x)}, toString : function(){return Math.abs(p1.x - p2.x)} } var m_height = { valueOf : function(){return Math.abs(p1.y - p2.y)}, toString : function(){return Math.abs(p1.y - p2.y)} } //getter this.getFirstPoint = function() { function GETTER(){}; GETTER.prototype = m_firstPoint; return new GETTER(); } this.getLastPoint = function() { function GETTER(){}; GETTER.prototype = m_lastPoint; return new GETTER(); } this.length = { valueOf : function(){return Math.sqrt(m_width*m_width + m_height*m_height)}, toString : function(){return Math.sqrt(m_width*m_width + m_height*m_height)} } } var p1 = new Point; var p2 = new Point(2,3); var line1 = new LineSegment(p1, p2); var lp = line1.getFirstPoint(); lp.x = 100; //不小心改写了lp的值,但是没有破坏原始的值 alert(line1.getFirstPoint().x); alert(line1.length); //line1.lenght不发生改变 </script>
<script> function Polygon() { var m_points = []; m_points = Array.apply(m_points, arguments); function GETTER(){}; GETTER.prototype = m_points[0]; this.firstPoint = new GETTER(); this.length = { valueOf : function(){return m_points.length}, toString : function(){return m_points.length} } this.add = function(){ m_points.push.apply(m_points, arguments); } this.getPoint = function(idx) { return m_points[idx]; } this.setPoint = function(idx, point) { if(m_points[idx] == null) { m_points[idx] = point; } else { m_points[idx].x = point.x; m_points[idx].y = point.y; } } } var p = new Polygon({x:1, y:2},{x:2, y:4},{x:2, y:6}); alert(p.length); alert(p.firstPoint.x); alert(p.firstPoint.y); p.firstPoint.x = 100; //不小心写了它的值 alert(p.getPoint(0).x); //不会影响到实际的私有成员 delete p.firstPoint.x; //恢复 alert(p.firstPoint.x); p.setPoint(0, {x:3,y:4}); //通过setter改写了实际的私有成员 alert(p.firstPoint.x); //getter的值发生了改变 alert(p.getPoint(0).x); </script>
다음은 예입니다.
<script> var p1 = new Point(1,2); var points = []; var PointPrototype = function(){}; PointPrototype.prototype = p1; for(var i = 0; i < 10000; i++) { points[i] = new PointPrototype(); //由于PointPrototype的构造函数是空函数,因此它的构造要比直接构造//p1副本快得多。 } </script>
3 프로토타입의 본질
위에서 프로토타입의 역할에 대해 언급했습니다. 이제 규칙을 통해 프로토타입의 본질을 밝혀보겠습니다.
프로토타입은 C의 정적 필드처럼 동작합니다. 프로토타입의 속성으로 속성을 추가합니다. 이 속성은 이 유형으로 생성된 모든 인스턴스에서 공유되지만 이 공유는 읽기 전용입니다. 어떤 경우에도 이 속성을 동일한 이름의 자체 속성으로 덮어쓸 수만 있고 변경할 수는 없습니다. 즉, 객체가 특정 속성을 읽을 때 항상 자신의 도메인의 속성 테이블을 먼저 확인하고, 그러한 속성이 있으면 이 속성을 반환하며, 그렇지 않으면 프로토타입 도메인을 읽고 해당 속성을 반환합니다. 프로토타입 도메인. 또한 JavaScript에서는 프로토타입 필드가 모든 유형의 객체를 참조할 수 있도록 허용합니다. 따라서 프로토타입 필드를 읽은 후에도 속성을 찾을 수 없으면 JavaScript는 프로토타입 필드가 가리키는 객체의 프로토타입 필드를 반복적으로 검색합니다. 객체 자체이거나 주기가 발생할 때까지 다음 다이어그램을 사용하여 프로토타입과 객체 인스턴스 간의 관계를 설명할 수 있습니다.
//TODO:
4 프로토타입의 가치와 제한
위의 분석을 통해 프로토타입을 이해하게 되었는데 이를 통해 객체를 프로토타입으로 활용하여 안전하게 수많은 인스턴스를 생성할 수 있다는 것이 프로토타입의 진정한 의미이자 가치입니다. 프로토타입의 이 기능을 사용하면 객체의 상속을 시뮬레이션할 수 있다는 사실을 나중에 살펴보겠지만, 프로토타입이 상속을 시뮬레이션하는 데 사용되지만 프로토타입이 상속의 중요한 가치이기는 하지만 확실히 핵심은 아니라는 점을 알아야 합니다. 즉, JavaScript 따라서 프로토타입 지원은 객체 상속을 구현하는 데만 사용되는 것이 아닙니다. 프로토타입 상속이 없더라도 JavaScript의 프로토타입 메커니즘은 여전히 매우 유용합니다.
프로토타입은 객체를 프로토타입으로 사용하여 유형의 복사본을 만들기 때문에 한계도 큽니다. 우선, 해당 유형의 프로토타입 필드에 있는 값 복사본으로 동작하지 않고 "부작용"을 가져오는 참조 복사본으로 동작합니다. 프로토타입에서 참조 유형의 속성 값을 변경하면(또 다른 다소 어색한 설명:P) 이 유형으로 생성된 모든 인스턴스에 완전히 영향을 미칩니다. 때로는 이것이 정확히 우리에게 필요한 것일 수도 있지만(예: 특정 클래스의 모든 객체의 기본값 변경) 때로는 이것이 우리가 원하지 않는 것일 수도 있습니다(예: 클래스 상속의 경우)는 다음과 같습니다.
<script> function ClassA() { this.a=[]; } function ClassB() { this.b=function(){}; } ClassB.prototype=new ClassA(); var objB1=new ClassB(); var objB2=new ClassB(); objB1.a.push(1,2,3); alert(objB2.a); //所有b的实例中的a成员全都变了!!这并不是这个例子所希望看到的。 </script>

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 오늘날의 디지털 시대에는 점점 더 많은 기업과 서비스에서 온라인 예약 기능을 제공해야 합니다. 효율적인 실시간 온라인 예약 시스템을 구현하는 것이 중요합니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. WebSocket이란 무엇입니까? WebSocket은 단일 TCP 연결의 전이중 방식입니다.

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

사용법: JavaScript에서 insertBefore() 메서드는 DOM 트리에 새 노드를 삽입하는 데 사용됩니다. 이 방법에는 삽입할 새 노드와 참조 노드(즉, 새 노드가 삽입될 노드)라는 두 가지 매개 변수가 필요합니다.

JavaScript에서 HTTP 상태 코드를 얻는 방법 소개: 프런트 엔드 개발에서 우리는 종종 백엔드 인터페이스와의 상호 작용을 처리해야 하며 HTTP 상태 코드는 매우 중요한 부분입니다. HTTP 상태 코드를 이해하고 얻는 것은 인터페이스에서 반환된 데이터를 더 잘 처리하는 데 도움이 됩니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. HTTP 상태 코드란 무엇입니까? HTTP 상태 코드는 브라우저가 서버에 요청을 시작할 때 서비스가
