(다음날) 프로토타입, 상속

23450 단어

원형


끌어들이다


우리는 여전히 Person 종류를 정의한다
1  function person(age,name){
2      this.age = age;
3      this.name = name;
4      this.information = function(){
5          return " "+ this.age+","+" "+ this.name;
6      }
7  }    

다음은 저희가 실례화된 대상을 호출하여 관련 정보를 출력합니다
1 var p1 = new Person(12,' ');
2 console.log(p1.information);

위에서 정상적으로 출력할 수 있다면 지금 이런 수요가 있습니다. 만약에 여러 대상이 모두 하나의 방법을 가지고 있다면 어떻게 조작해야 합니까?그건 훨씬 간단해. 직접 개인 클래스에 방법 대상을 만들어서 사용할 때 이걸 직접 사용하면 되잖아!보다
1 var p1 = new person(1, "1");
2 var p2 = new person(2, "2");
3 console.log(p1.information == p2.information);
4 console.log(p1.information === p2.information);
5 
6 /*
7  false, 
8 */

그래서 이것은 모든 개인들의 실례가 각자의 방법이 있고 공유하지 않은 방법과 같다. 그러면 불필요한 메모리 소모를 초래한다!이에 대해prototype(원형 대상)을 도입하여 공유 대상의 실례적인 방법이나 속성을 실현합니다.

개념:


각 JavaScript 객체(null 제외)는 다른 원형 객체와 연관되며 각 객체는 속성을 상속합니다.객체를 통해 직접 작성된 객체는 Object를 통해 작성할 수 있습니다.prototype에서 원형 대상의 인용을 얻습니다.키워드 new와 구조 함수를 통해 생성된 대상의 원형은 구조 함수의prototype 속성의 값입니다.마찬가지로 JavaScript 내장 대상인 Array와 같이 Date가 new Array () 를 통해 만든 대상의 원형은 Array입니다.prototype 및 Date.prototype.[참고] Object.prototype은 원형 대상이 없고 속성을 계승하지 않습니다.
그래서 위에서 말한 바와 같이 우리는 개인류에게prototype을 통해 공유 방법을 정의할 수 있다.common 즉
1 person.prototype.common = function() {
2          return " ktv";
3 }

실례화 대상 p1과 p2를 인쇄하고 console을 인쇄합니다.log(p1.common === p2.common);true로 돌아가면 두 대상이 common 방법을 공유했음을 설명합니다.
다음은 두 가지 방법을 통해 원형의 속성과 방법을 더욱 깊이 있게 학습한다

(1) 구조 함수 정의 대상의'클래스'호출 원형을 수동으로 작성한다.

1 /*
2  
3 */
4 
5 function inherit(p){
6     function f(){};
7     f.prototype = p;
8     return new f();
9 }

다음은 값 범위를 나타내는 클래스를 작성합니다
 1                /*
 2                   
 3                   */
 4             function inherit(p) {
 5                 function f() {};
 6                 f.prototype = p;
 7                 return new f();
 8             }
 9 
10             function range(from, to) {
11                 var r = inherit(range.methods);
12                 r.from = from;
13                 r.to = to;
14                 return r;
15             }
16             range.methods = {
17                 include: function(x) {
18                     return this.from <= x && x <= this.to;
19                 },
20                 foreach: function() {
21                     var arr = [];
22                     for (var x = Math.ceil(this.from); x <= this.to; x++) {
23                         arr.push(x);
24                     }
25                     return arr;
26                 },
27                 toString: function() {
28                     return "(" + this.from + "..." + this.to + ")";
29                 }
30             };
31             var r = range(1, 3); // 
32             console.log(r.include(2)) // =>true:2  
33             console.log(r.foreach()); // 1,2,3 
34             console.log(r); // (1...3)

 
우리는 새로운 대상을 만들고 inherit 함수 계승 함수range에서 정의한 방법인methods를 통해 함수range를 통해 얻은 대상이 모두 이 방법을 공유할 수 있으며 이를 바탕으로 두 개의 계승할 수 없는 속성인from과 to를 정의하기 때문에 이 두 속성은 공유할 수 없습니다!그러나methods 방법에서 공유할 수 있고 계승할 수 있는 방법을 정의하는 데from과 to 속성이 사용되고this 키워드를 사용하며this 키워드로 이 방법을 호출할 대상을 지정하기 때문에 어떠한 방법도this 방법으로 대상의 기본 속성을 읽을 수 있다.따라서 이 방법은 대상을 만들고prototype을 사용하는 방식으로 사용하는 것을 권장하지 않습니다.

(2) 구조 함수의prototype 속성을 통해 원형의 속성과 방법을 얻는다


구조 함수를 호출하는 중요한 특징: 구조 함수의prototype 속성은 새로운 대상의 원형으로 사용된다.또한 같은 구조 함수를 통해 만들어진 모든 대상이 같은 대상에서 계승되기 때문에 같은 클래스의 구성원이라는 것을 의미한다.
다음에 우리는 위의 코드를 개조하여 구조 함수를 사용하여 원형 대상의 속성과 방법을 얻는다
 1 function Range(from, to) {
 2     this.from = from;
 3     this.to = to;
 4 }
 5 Range.prototype = {
 6     include: function(x) {
 7         return this.from <= x && x <= this.to;
 8     },
 9     foreach: function(f) {
10         for (var x = Math.ceil(this.from); x <= this.to; x++)
11            f(x);
12     },
13     toString: function() {
14         return "(" + this.from + "..." + this.to + ")";
15     }
16 };
17 var r = new Range(1, 9);
18 r.include(2);
19 r.foreach(console.log());
20 console.log(r);

[주] 따르는 프로그래밍 약정: 정의 구조 함수는 정의 클래스일 뿐만 아니라 클래스 이름의 자모는 대문자로 써야 한다.일반적인 함수와 방법은 모두 알파벳 소문자다.
이 코드는 new 키워드로만 대상을 만들 수 있으며 상기 inherit로 수동으로 만들어서 원형 대상의 인용을 추가할 필요가 없습니다!구조 함수를 호출하기 전에 새 대상을 만들었습니다.this 키워드를 통해 이 대상을 얻을 수 있습니다.Range는this를 초기화할 뿐입니다. 구조 함수는 새로 만든 대상을 되돌릴 필요가 없습니다. 구조 함수는 자동으로 만들어지고, 구조 함수를 이 대상으로 하는 방법으로 한 번 호출되며, 마지막으로 이 대상을 되돌려줍니다.상술한 이 말은 듣기에 매우 까다롭거나 이해하기가 쉽지 않은 것 같다. 개인적인 이해에 C#대상을 대상으로 하는 창설류의 사상으로 이렇게 생각한다. (잘못이 있으면 친구들에게 비판과 시정을 간청한다. 나도 더욱 잘 배우고 이해할 수 있다).

(1) 퇴적 공간 개척


(2) 객체 작성


(3) 구조 함수를 호출하고 창설된 대상을 상하문으로 호출하기 때문에this 키워드로 창설된 대상을 인용할 수 있다


(4) 마지막으로 이 대상에 속성이나 방법을 지정한 다음에 새로 만든 대상을 되돌려줍니다


보태다


constructor 속성


각 JavaScript 함수에는 prototype 속성이 자동으로 있습니다.이 속성의 값은 하나의 대상입니다. 이 대상은 매거할 수 없는 유일한 속성constructor를 포함합니다.그것의 값은 함수 대상이다
1 var F = function(){};
2 var p = F.prototype;
3 var c = p.constructor;
4 console.log(c === F)
5 
6 /*
7  true: F.prototype.constructor == F
8 */

구조 함수의 원형에 미리 정의된 constructor 속성이 존재하는 것을 볼 수 있다. 이것은 대상이 통상적으로 계승하는 constructor는 모두 그들의 구조 함수를 가리킨다. 구조 함수는 클래스의'공용 표지'이기 때문에 이 constructor 속성은 대상에게 클래스를 제공한다.

위의 원형을 이해함으로써 계승을 더욱 잘 이해할 수 있다


물려받다


검색 대상 o의 속성 x를 가정합니다. 만약 o에 x가 존재하지 않는다면, o의 원형 대상에서 속성 x를 검색합니다.만약 원형 대상에 x가 없지만, 이 대상에도 원형이 있다면, 이 원형 대상의 원형에 대해 x를 찾거나 원형이null인 대상을 찾을 때까지 계속 검색을 실행합니다.이를 통해 알 수 있듯이 대상의 원형 속성은 하나의'체인'즉 원형 체인을 구성하여 속성의 계승을 실현한다.
1 var o = {};
2 o.x = 1;
3 
4 /*
5 o Object.prototype  , o x
6 */

조회 조작을 통해서만 상속의 존재를 충분히 체득할 수 있다. 아래의 거대한 예를 들어 설명한다.
 1 function inherit(p){
 2     function f(){};
 3     f.prototype = p;
 4     return new f(); 
 5 }
 6 
 7 var obj = { r : 1 };
 8 var c = inherit(obj);
 9 c.x = 1; c.y = 1;
10 c.r = 2;
11 cosole.log(obj.r);
12 
13 /*
14 c x,y r,c.r = 2 , 1, 
15 */

현재 대상 o의 속성 x에 값을 부여한다고 가정합니다. 만약 o에 이미 속성 x가 있다면 (이 속성은 계승된 것이 아닙니다.) 이 값 부여 조작 값은 이미 있는 속성의 값만 바꿉니다.만약 o에 속성 x가 존재하지 않는다면, 값 부여 작업은 o에 새로운 속성 x를 추가합니다.만약 이전에 o가 속성 x에서 계승했다면, 이 계승된 속성은 새로 만든 동명 속성에 의해 덮어쓰일 것입니다.[주] 속성 값 부여 작업은 먼저 원형 체인을 검사하여 값 부여 작업이 허용되는지 여부를 판정한다. 만약에 o가 읽기 전용 속성 x를 계승한다면 값 부여 작업은 허용되지 않는다. 예를 들어 상기 대상의obj속성 r를 읽기 전용 Object로 설정한다.defineProperty(obj, "x", { writeable: false }); !
다음은 계속해서 예를 들어 더욱 깊이 있는 예를 들어 계승을 배운다
 1 function parent(age,name){
 2     this.age = age;
 3     this.name = name;
 4 }
 5 
 6 parent.prototype.information = function(){
 7 
 8          console.log(" ");
 9 }
10 
11 children.prototype = parent.prototype;   // 
12 
13 function children(age,name){
14     parent.call(this, age, name); //call , 
15 }

현재 클래스children을 실례화하고 속성 값을 가져옵니다. 호출 방법입니다.
1 var child = new Children(12," ");
2 console.log(child.age);
3 console.log(child.name);
4 console.log(child.information());

위와 같이 모든 물이 도랑에 흐르는 것 같으니, 다음에 우리는 자류의 원형을 위해 방법을 정의한다
children.prototype.childPrivateMethod = function(){
    console.log(" "); 
}

부류를 초기화하고 호출 방법을 시도해 보십시오
1 var parent = new Person(12,' ');
2 console.log(parent.childPrivateMethod());

무슨 일이야???부류가 자류의 사유 방법을 사용할 수 있다는 것도 C#의 계승 특성에 완전히 부합되지 않는다. 그리고 죄행을 탈옥하여 용서할 수 없다. 사실은 그렇지 않으면 나의 코드가 그것을 유기적으로 탈 수 있게 한다!
children.prototype = parent.prototype;이때 부류와 자류의 원형은 완전히 같다. 그러면 부류 대상의 실례가 그 방법에 접근할 수 있는 것도 일리가 있고 근거가 있다!관건은 어떻게 부류가 자류를 호출할 수 없게 하는 방법입니까?다행히 이전에 수동으로 클래스를 사용하여 대상을 만드는 것을 보았습니다. 앞에서 inherit에서 알 수 있듯이 부모 클래스를 실례화한 대상을 다음과 같이 수정합니다.
 children.prototype = new parent(); 
사실은 옳다는 것을 증명한다. 단지 부류의 실례를 자류에게 주었을 뿐이다. 자류는 자연히 부류의 모든 것을 얻을 수 있고 부류는 영원히 자신의 땅에서만 왕이 될 수 있다!

좋은 웹페이지 즐겨찾기