JavaScript의 각 객체에는 내장 속성 프로토 타입이 있습니다. JavaScript에서 객체의 프로토 타입 속성에 대한 설명은 다음과 같습니다. 객체 유형 프로토 타입에 대한 참조를 반환합니다. 이는 프로토 타입 속성이 현재 객체의 부모 역할을하는 다른 JavaScript 객체에 대한 참조를 가지고 있음을 의미합니다.
코드 사본은 다음과 같습니다.
A. 프로토 타입 = 새로운 B ();
프로토 타입을 이해하는 것이 상속과 혼동되어서는 안됩니다. A의 프로토 타입은 B의 인스턴스입니다. A는 B의 모든 방법과 특성을 복제했다는 것을 이해할 수 있습니다. A는 B의 방법과 특성을 사용할 수 있습니다. 여기서 강조되는 것은 상속보다는 복제입니다. A의 프로토 타입은 B의 인스턴스이며 B의 프로토 타입은 A의 인스턴스이기도합니다.
다음 분석을 계속 살펴보십시오.
개인 변수 및 기능
함수 내부에서 정의 된 변수 및 함수가 외부로 제공되지 않으면 외부에서 액세스 할 수 없습니다. 즉, 함수의 개인 변수 및 함수.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 박스 () {
var color = "blue"; // 개인 변수
var fn = function () // 개인 함수
{
}
}
</스크립트>
이러한 방식으로 변수 색상 및 FN은 기능 객체 상자 외부에서 액세스 할 수 없으며 개인이됩니다.
코드 사본은 다음과 같습니다.
var obj = new Box ();
경고 (obj.color); // 정의되지 않은 팝업
Alert (obj.fn); // 위와 동일합니다
정적 변수 및 함수
함수가 정의되면 객체 자체를 통해 추가 된 속성 및 함수에 액세스 할 수 있지만 예제에 액세스 할 수 없습니다. 이러한 변수와 함수를 각각 정적 변수와 정적 함수라고합니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 obj () {};
obj.num = 72; // 정적 변수
obj.fn = function () // 정적 함수
{
}
경고 (obj.num); // 72
ALERT (typeof obj.fn) // 함수
var t = new obj ();
경고 (t.name); // 정의되지 않았습니다
Alert (typeof t.fn); // 정의되지 않았습니다
</스크립트>
인스턴스 변수 및 함수
객체 지향 프로그래밍에서 일부 라이브러리 기능 외에도 객체 정의가 인스턴스화 후 액세스 할 수 있도록 일부 속성과 메소드를 동시에 정의하고 JS도이를 수행 할 수 있습니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 박스 () {
this.a = []; // 인스턴스 변수
this.fn = function () {// 인스턴스 메소드
}
}
Console.log (typeof box.a); //한정되지 않은
console.log (typeof box.fn); //한정되지 않은
var box = new Box ();
Console.log (typeof box.a); //물체
console.log (typeof box.fn); //기능
</스크립트>
인스턴스 변수 및 메소드에 새로운 메소드 및 속성 추가
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 박스 () {
this.a = []; // 인스턴스 변수
this.fn = function () {// 인스턴스 메소드
}
}
var box1 = new Box ();
Box1.A.Push (1);
box1.fn = {};
Console.log (Box1.a); // [1]
console.log (typeof box1.fn); //물체
var box2 = new Box ();
Console.log (box2.a); // []
Console.log (typeof box2.fn); //기능
</스크립트>
A 및 FN은 Box1에서 변형되었지만 Box2에서는 변형되지 않았다. 배열 및 함수는 객체이며 참조 유형이므로 Box1의 특성 및 메소드는 Box2의 특성과 메소드와 동일하지만 참조가 아니라 Box 객체에 의해 정의 된 특성 및 방법의 사본이라는 것을 의미합니다.
이는 속성에 문제가 없지만 메소드가 정확히 동일한 기능을 수행하고 있지만 두 개의 사본이 있기 때문에 메소드에 큰 문제가 있습니다. 함수 객체에 수천 및 인스턴스 메소드가있는 경우 각 인스턴스는 수천 개의 메소드의 사본을 유지해야합니다. 이것은 분명히 비과학적입니다. 무엇을 할 수 있습니까? 프로토 타입이 시작되었습니다.
기본 개념
우리가 만든 각 함수에는 프로토 타입 속성이 있는데,이 속성은 객체에 대한 포인터이며, 그 목적은 특정 유형의 모든 인스턴스에서 공유 할 수있는 속성과 방법을 포함하는 것입니다. 그런 다음 프로토 타입은 생성자를 호출하여 생성 된 객체 인스턴스의 프로토 타입 객체입니다.
프로토 타입을 사용하는 장점은 객체 인스턴스가 포함 된 속성 및 메소드를 공유 할 수 있다는 것입니다. 즉, 생성자에 정의 객체 정보를 추가하는 대신이 정보를 프로토 타입에 직접 추가 할 수 있습니다. 생성자 사용의 주요 문제는 각 인스턴스에서 각 방법을 한 번만 만들어야한다는 것입니다.
JavaScript에는 원래 값과 객체 값의 두 가지 유형의 값이 있습니다. 각 객체에는 내부 속성 프로토 타입이 있으며 일반적으로 프로토 타입이라고합니다. 프로토 타입의 값은 물체 또는 null 일 수 있습니다. 값이 객체 인 경우 객체에 자체 프로토 타입이 있어야합니다. 이것은 선형 체인을 형성하여 프로토 타입 체인이라고합니다.
의미
함수는 생성자로 사용할 수 있습니다. 또한 함수 만 프로토 타입 속성을 가지고 있고 액세스 할 수 있지만 객체 인스턴스에는이 속성이 없으며 내부에 액세스 할 수없는 __proto__ 속성 만 있습니다. __proto__는 관련 프로토 타입과의 개체에서 신비한 링크입니다. 표준에 따르면, __proto__는 대중에게 공개되지 않으며, 이는 사유 재산이지만 Firefox의 엔진이 노출되어 공통 재산이되어 액세스하고 설정할 수 있습니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
var browser = function () {};
Browser.prototype.run = function () {
Alert ( "나는 Gecko, Firefox의 커널");
}
var bro = 새로운 브라우저 ();
bro.run ();
</스크립트>
Bro.Run () 메소드를 호출 할 때 BRO에는 그러한 메소드가 없기 때문에 __proto__, 즉 Browser.Prototype에서 검색 할 것이므로 Run () 메소드가 최종적으로 실행됩니다. (여기서, 함수의 대문자 문자는 일반 함수를 구별하기위한 생성자를 나타냅니다)
인스턴스를 생성하기 위해 생성자를 호출 할 때 인스턴스에는 생성자의 프로토 타입을 가리키는 내부 포인터 (__proto__)가 포함됩니다. 이 연결은 인스턴스와 생성자의 프로토 타입 사이에서 인스턴스와 생성자 사이에 존재합니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능인 (이름) {// 생성자 함수
this.name = 이름;
}
person.prototype.printname = function () // 프로토 타입 개체
{
경고 (this.name);
}
var person1 = 새로운 사람 ( 'byron'); // 객체를 인스턴스화합니다
console.log (person1 .__ proto __); // person
console.log (person1.constructor); // 그것이 무엇인지 확인하기 위해 직접 시도하십시오
Console.log (person.prototype); // 프로토 타입 객체 사람을 가리 킵니다
var person2 = 새로운 사람 ( 'Frank');
</스크립트>
Person의 인스턴스 Person1은 이름 속성을 포함하며, 개인의 프로토 타입을 가리키는 __proto__ 속성을 자동으로 생성하며 프로토 타입에 정의 된 인쇄 이름 메소드에 액세스 할 수 있습니다.
각 JavaScript 함수에는 프로토 타입 속성이 있으며,이 속성은 프로토 타입 객체 인 객체를 나타냅니다. 초기화 할 때 프로토 타입 객체가 비어 있습니다. 속성과 메소드를 사용자 정의 할 수 있습니다. 이러한 방법과 속성은 생성자가 만든 객체에 의해 상속됩니다.
이제 문제는입니다. 생성자, 인스턴스 및 프로토 타입 객체의 관계는 무엇입니까?
생성자, 인스턴스 및 프로토 타입 객체의 차이
인스턴스는 생성자를 통해 생성됩니다. 인스턴스가 생성되면 생성자 속성 (생성자 함수를 가리키는) 및 __proto__ 속성 (프로토 타입 개체를 가리키는)이 있습니다.
생성자에는 프로토 타입 객체에 대한 포인터 인 프로토 타입 속성이 있습니다.
프로토 타입 객체 내부에는 생성자를 가리키는 포인터 (생성자 특성)도 있습니다 : person.prototype.constructor = person;
인스턴스는 프로토 타입 객체에 정의 된 속성 및 메소드에 액세스 할 수 있습니다.
여기서 Person1과 Person2는 인스턴스이며 프로토 타입은 프로토 타입 객체입니다.
또 다른 밤나무 :
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 동물 (이름) // 생성자 축적
{
this.name = name; // 객체 속성을 설정합니다
}
Animal.prototype.behavior = function () // 기본 클래스 생성자의 프로토 타입에 동작 메소드 추가
{
경고 ( "이것은"+this.name);
}
var dog = new Animal ( "Dog"); // 개 대상을 만듭니다
var cat = 새로운 동물 ( "고양이"); // 고양이 물체를 만듭니다
dog.behavior (); // Dog Object를 통해 직접 행동 방법을 호출하십시오
cat.behavior (); // 출력 "이것은 고양이"
Alert (dog.behavior == cat.behavior); // true;
</스크립트>
프로그램 실행 결과에서 생성자의 프로토 타입에 정의 된 메소드를 실제로 객체를 통해 직접 호출 할 수 있으며 코드가 공유된다는 것을 알 수 있습니다. (동물성에서 프로토 타입 속성을 제거하려고 시도 할 수 있습니다.
배열 객체 인스턴스
배열 객체의 인스턴스를 살펴 보겠습니다. Object Array1을 만들 때 JavaScript 엔진의 Array1의 실제 객체 모델은 다음과 같습니다.
코드 사본은 다음과 같습니다.
var array1 = [1,2,3];
Array1 객체의 길이 속성 값은 3이지만 다음 방법으로 Array1에 요소를 추가 할 수 있습니다.
코드 사본은 다음과 같습니다.
배열 1.push (4);
푸시 메소드는 array1 (array.prototye.push ())의 __proto__ 구성원에 의해 객체를 가리키는 메소드에서 비롯됩니다. 모든 배열 객체 ([]를 통해 생성)에는 푸시, 리버스 등이있는 동일한 메소드 객체를 가리키는 __proto__ 멤버 (Array.Prototype)가 포함되어 있기 때문에이 배열 객체는 푸시, 리버스 및 기타 메소드를 사용할 수 있기 때문입니다.
기능 객체 인스턴스
코드 사본은 다음과 같습니다.
함수 base () {
this.id = "base"
}
코드 사본은 다음과 같습니다.
var obj = new Base ();
그러한 코드의 결과는 무엇입니까? JavaScript 엔진에서 볼 수있는 객체 모델은 다음과 같습니다.
새로운 운영자는 정확히 무엇을 했습니까? 사실, 그것은 매우 간단했습니다. 단지 세 가지 일을했습니다.
코드 사본은 다음과 같습니다.
var obj = {};
obj .__ proto__ = base.prototype;
base.call (obj);
프로토 타입 체인
프로토 타입 체인 : 객체에서 속성 또는 방법이 검색되면 객체 자체에 그러한 속성이나 방법이없는 경우와 관련된 프로토 타입 객체를 검색합니다. 프로토 타입이 없으면 프로토 타입과 관련된 프로토 타입의 전임자를 검색합니다. 더 이상 없으면 프로토 타입으로 참조 된 객체를 계속 검색하십시오. 프로토 타입까지 프로토 타입까지의 프로토 타입이 정의되지 않아 (물체의 프로토 타입이 정의되지 않음) 소위 "프로토 타입 체인"을 형성하십시오.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 모양 () {
this.name = "shape";
this.tostring = function () {
이 this.name;
}
}
함수 twoshape () {
this.name = "2 shape";
}
기능 삼각형 (측면, 높이) {
this.name = "삼각형";
this.side = 측면;
this.height = 높이;
this.getArea = function () {
이 this.side*this.height/2;
}
}
twoshape.prototype = new Shape ();
Triangle.prototype = new twoshape ();
</스크립트>
여기서는 새 엔티티가 생성자 모양 ()로 생성 된 다음 객체의 프로토 타입을 덮어 쓰는 데 사용됩니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 모양 () {
this.name = "shape";
this.tostring = function () {
이 this.name;
}
}
함수 twoshape () {
this.name = "2 shape";
}
기능 삼각형 (측면, 높이) {
this.name = "삼각형";
this.side = 측면;
this.height = 높이;
this.getArea = function () {
이 this.side*this.height/2;
}
}
twoshape.prototype = new Shape ();
Triangle.prototype = new twoshape ();
twoshape.prototype.constructor = twoshape;
Triangle.prototype.constructor = 삼각형;
var my = 새로운 삼각형 (5,10);
my.getArea ();
my.tostring (); // 삼각형
my.constructor; // 삼각형 (측면, 높이)
</스크립트>
프로토 타입 상속
프로토 타입 상속 : 프로토 타입 체인의 끝에서, 그것은 객체 생성자 프로토 타입 속성에 의해 지적되는 프로토 타입 객체입니다. 이 프로토 타입 객체는 모든 객체의 조상이며,이 조상은 Tostring과 같은 모든 객체가 선천적으로 가져야하는 방법을 구현했습니다. 기능, 부울, 문자열, 날짜 및 Regexp와 같은 다른 내장 생성자는이 조상으로부터 상속되지만 각각 자체 속성과 방법을 정의하여 자손이 각각의 클랜의 특성을 보여줍니다.
ECMAScript에서, 상속을 구현하는 방법은 프로토 타입 체인에 의존함으로써 달성된다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
function box () {// 상속 된 함수는 superType (부모 클래스, 기본 클래스)라고합니다.
this.name = "잭";
}
function tree () {// 상속 된 함수는 하위 유형 (서브 클래스, 파생 클래스)이라고합니다.
this.age = 300;
}
// 프로토 타입 체인을 통해 상속, 하위 유형의 프로토 타입 속성을 지정하십시오.
// new Box ()는 박스 구성의 정보와 프로토 타입의 정보를 트리로 넘겨줍니다.
tree.prototype = new Box (); // 트리는 상자를 상속하고 프로토 타입을 통해 체인을 형성합니다.
var tree = new Tree ();
Alert (tree.name); // Popt Jack
</스크립트>
프로토 타입 체인의 문제 : 프로토 타입 체인은 매우 강력하고 상속을 구현하는 데 사용될 수 있지만 몇 가지 문제가 있습니다. 가장 중요한 문제는 기준 유형을 포함하는 값 프로토 타입에서 비롯됩니다. 참조 유형을 포함하는 프로토 타입 속성은 모든 인스턴스에서 공유됩니다. 그렇기 때문에 속성이 프로토 타입 객체가 아닌 생성자에 정의되는 이유입니다. 프로토 타입을 통해 상속을 달성하면 프로토 타입은 실제로 다른 유형의 인스턴스가됩니다. 따라서 원래 인스턴스 속성은 프로토 타입 속성이됩니다.
하위 유형의 인스턴스를 생성 할 때, 인수는 SuperType 생성자에게 전달 될 수 없습니다. 실제로, 모든 객체 인스턴스에 영향을 미치지 않으면 서 슈퍼 타입 생성자에게 매개 변수를 전달할 수있는 방법이 없다고 말해야합니다. 프로토 타입에 참조 유형 값을 포함하여 방금 논의한 문제 외에도 프로토 타입 체인 만 사용하는 것은 드 rare니다.
또 다른 밤나무 :
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 담당자 (이름)
{
this.name = name; // 객체 속성을 설정합니다
};
person.prototype.company = "Microsoft"; // 프로토 타입의 속성을 설정합니다
person.prototype.sayhello = function () // 프로토 타입 메소드
{
Alert ( "hello, 나는"+ this.name+ "의"+ this.company);
};
var Billgates = New Person ( "Billgates"); // 사람 객체 생성
Billgates.sayhello (); // 프로토 타입 및 출력의 내용을 상속합니다. "안녕하세요, Microsoft의 Billgates"
var jobs = 새로운 사람 ( "직업");
jobs.company = "Apple"; // 프로토 타입의 회사 속성을 덮기 위해 자신의 회사 속성을 설정
jobs.sayhello = function ()
{
Alert ( "hi," + this.name + "like" + this.company);
};
jobs.sayhello (); // 자신을 무시하는 속성과 방법, 출력 "안녕하세요, 애플과 같은 작업"
Billgates.sayhello (); // 작업의 적용 범위는 프로토 타입에 영향을 미치지 않으며 Billgates는 여전히 출력됩니다.
</스크립트>
프로토 타입 체인의 다음 예를 참조하십시오.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 연도 () {
this.value = 21;
}
연도. prototype = {
방법 : function () {
}
};
기능 hi () {
};
// HI의 프로토 타입 속성을 올해의 인스턴스 객체로 설정
hi.prototype = 새해 ();
hi.prototype.year = 'Hello World';
hi.prototype.constructor = hi;
var test = new hi (); // hi의 새 인스턴스 생성
// 프로토 타입 체인
테스트 [HI 예제]
hi.prototype [올해의 예]
{연도 : 'Hello World'}
연도. 프로로 타입
{방법:…};
object.prototype
{Tostring : ...};
</스크립트>
위의 예에서, 테스트 객체는 Hi.prototype 및 Year.prototype에서 상속됩니다. 따라서 연도의 프로토 타입 방법 방법에 액세스 할 수 있으며 동시에 인스턴스 속성 값에 액세스 할 수 있습니다.
__ptoto__ 속성
__ptoto__ 속성 (IE 브라우저에서 지원하지 않음)은 인스턴스의 프로토 타입 객체에 대한 포인터입니다. 그 기능은 생성자의 프로토 타입 속성 생성자를 가리키는 것입니다. 이 두 가지 속성을 통해 프로토 타입의 속성과 메소드에 액세스 할 수 있습니다.
JavaScript의 객체 인스턴스는 본질적으로 일련의 속성으로 구성됩니다. 이러한 속성 중에는 내부적으로 보이지 않는 특수 속성 인 __proto__가 있습니다. 이 속성의 값은 객체 인스턴스의 프로토 타입을 가리 킵니다. 객체 인스턴스에는 고유 한 프로토 타입 만 있습니다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 박스 () {// 대문자, 생성자를 나타냅니다
box.prototype.name = "trigkit4"; // 프로토 타입 속성
box.prototype.age = "21";
box.prototype.run = function () // 프로토 타입 메소드
{
this.name + this.age + '공부';
}
}
var box1 = new Box ();
var box2 = new Box ();
Alert (Box1.constructor); // 속성을 구성하면 생성자 자체를 얻을 수 있습니다.
// 기능은 프로토 타입 포인터에 의해 배치 된 다음 생성자 자체를 얻는 것입니다.
</스크립트>
__proto__ 속성과 프로토 타입 속성의 차이
프로토 타입은 기능 객체의 독점 속성입니다.
__proto__는 일반 객체의 암시 적 특성입니다. 새로운 경우, 그것은 프로토 타입으로 가리키는 물체를 가리킬 것입니다.
__ptoto__는 실제로 특정 엔티티 객체의 속성이며 프로토 타입은 생성자에 속하는 속성입니다. __ptoto__는 환경 학습 또는 디버깅에만 사용될 수 있습니다.
프로토 타입 모드 실행 프로세스
1. 먼저 생성자 인스턴스의 속성 또는 메소드를 찾아서 즉시 반환하십시오.
2. 생성자의 인스턴스가 없으면 프로토 타입 객체로 이동하여 즉시 돌아갑니다.
프로토 타입 객체
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능 박스 () {// 대문자, 생성자를 나타냅니다
box.prototype.name = "trigkit4"; // 프로토 타입 속성
box.prototype.age = "21";
box.prototype.run = function () // 프로토 타입 메소드
{
this.name + this.age + '공부';
}
}
var box1 = new Box ();
Alert (Box1.name); // Trigkit4, 프로토 타입의 값
box1.name = "Lee";
경고 (box1.name); // Lee, 원리로 이동하십시오
var box2 = new Box ();
alert (box2.name); // trigkit4, 프로토 타입의 값, box1에 의해 수정되지 않은 것
</스크립트>
생성자
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
함수 박스 () {
this.name = "Bill";
}
box.prototype.name = "trigkit4"; // 프로토 타입 속성
box.prototype.age = "21";
box.prototype.run = function () // 프로토 타입 메소드
{
this.name + this.age + '공부';
}
var box1 = new Box ();
Alert (Box1.name); // Bill, 프로토 타입의 값
box1.name = "Lee";
경고 (box1.name); // Lee, 원리로 이동하십시오
</스크립트>
요약하려면 정리해 봅시다.
코드 사본은 다음과 같습니다.
<script type = "text/javaScript">
기능인 () {};
person.prototype.name = "trigkit4";
person.prototype.say = function () {
경고 ( "hi");
}
var p1 = new Person (); // 프로토 타입은 P1과 P2의 프로토 타입 객체입니다.
var p2 = new person (); // p2
console.log (p1.prototype); // 정의되지 않은이 속성은 객체이며 액세스 할 수 없습니다.
Console.log (person.prototype); // person
console.log (person.prototype.constructor); // 생성자 함수를 가리키는 프로토 타입 객체 안에 포인터 (생성자 속성)도 있습니다.
console.log (p1 .__ proto __); //이 속성은 프로토 타입의 프로토 타입 개체를 가리키는 포인터입니다.
p1.say (); // 인스턴스는 프로토 타입 객체에 정의 된 속성 및 메소드에 액세스 할 수 있습니다.
</스크립트>
공장 모델
코드 사본은 다음과 같습니다.
함수 createobject (이름, 나이) {
var obj = new Object ();
obj.name = 이름;
obj.age = 나이;
반환 obj;
}
공장 패턴은 인스턴스화 된 객체의 대규모 복제 문제를 해결하지만 또 다른 문제가 있습니다. 즉, 객체의 인스턴스를 파악하는 것은 불가능합니다.
생성자 방법을 사용하면 반복 된 인스턴스화의 문제를 해결할뿐만 아니라 객체 인식 문제를 해결합니다.
생성자 방법과 공장 패턴 사용의 차이점은 다음과 같습니다.
1. 생성자 메소드에 의해 표시되지 않는 개체 (new Object ())을 작성합니다.
2.이 개체에 속성과 방법을 직접 할당하십시오
3. 반환 명세서 없음
생성자가 사용되고 새 생성자 ()가 사용되면 새로운 Object ()가 백그라운드에서 실행됩니다.
기능 본문에서 이것은 new Object ()에서 파생 된 객체를 나타냅니다.
1. 속성이 생성자 인스턴스인지 또는 프로토 타입에 있는지 확인하면`hasownProperty ()`function을 사용할 수 있습니다.
2. 리터럴을 생성하는 방법은 생성자 속성을 생성하는 데 사용되어 인스턴스를 가리키지 않고 객체를 가리키며 생성자를 생성하는 방법은 그 반대입니다.
왜 대상을 가리키는가? vox.prototype = {};이 글쓰기 방식은 실제로 새로운 객체를 만드는 것입니다.
함수가 생성 될 때마다 프로토 타입이 동시에 생성 되며이 객체는 자동으로 생성자 속성을 얻습니다.
3. 인스턴스 방법 인 경우, 인스턴스화가 다르면 메소드 주소는 다르고 고유합니다.
4. 프로토 타입 방법이라면 주소가 공유됩니다.