Shin-Yeonghwa / Core_JS

Core_JS
2 stars 0 forks source link

6.2 프로토타입 체인 #20

Open KimHyeSeon opened 4 years ago

KimHyeSeon commented 4 years ago

study 완료 후 체크 부탁드립니다.

Lee-Bom commented 4 years ago

6-2 프로토타입 체인 6-2-1 메서드 오버라이드

6-2-2 프로토타입 체인

6-2-3 객체 전용 메서드의 예외사항

6-1-4 다중 프로토타입 체인

KimHyeSeon commented 4 years ago

프로토타입 체인

1. 메서드 오버라이드

var iu = new Person('지금'); iu.getName = function() { return '바로 ' + this.name; }; console.log(iu.getName()); // 바로 지금

- getName을 찾는 방식은 가장 가까운 대상인 자신의 프로퍼티를 검색하고, 없으면 그 다음으로 가까운 대상인 __proto__를 검색하는 순서로 진행
- __proto__는 검색순서에서 밀려 호출되지 않음
- this가 prototype을 바라보고 있는 것을 인스턴스를 바라볼 수 있도록 call이나 apply를 사용하여 해결가능

console.log(iu.proto.getName.call(iu)); // 바로 지금


**2. 프로토타입 체인**
- 어떤 데이터의 __proto__ 프로퍼티 내부에 다시 __proto__ 프로퍼티가 연쇄적으로 이어진 것
- 이 체인을 따라가며 검색하는 것을 프로토타입 체이닝이라 함
- 자바스크립트 엔진은 데이터 자신의 프로퍼티들을 검색해서 원하는 메서드가 있으면 그 메서드를 실행하고, 없으면 __proto__를 검색해서 있으면 그 메서드를 실행하고, 없으면 다시 __proto__를 검색해서 실행하는 식으로 진행

var arr = [1, 2]; Array.prototype.toString.call(arr); // 1,2 Object.prototype.toString.call(arr); // [object Array] arr.toString(); // 1,2

arr.toString = function() { return this.join('_'); }; arr.toString(); // 1_2


**3. 객체 전용 메서드의 예외사항**
- 어떤 생성자 함수든  prototype은 반드시 객체이기 때문에 Object.prototype이 언제나 프로토타입 체인의 최상단에 존재하게 됨
- 객체에서만 사용할 메서드를 Object.prototype 내부에 정의한다면 다른 데이터 타입에도 해당 메서드를 사용할 수 있게 됨
- Object.prototype에는 어떤 데이터에서도 활용할 수 있는 범용적인 메서드들만 있음
  - toString, hasOwnProperty, valueOf, isPrototypeOf 등

**4. 다중 프로토타입 체인**
- 기본 내장 데이터 타입들은 모두 프로토타입 체인이 1단계(객체)이거나 2단계(나머지)로 끝나는 경우만 있었지만, 사용자가 새롭게 만드는 경우는 그 이상 확장 가능
- 대각선의 __proto__를 연결하는 방법은 __proto__가 가리키는 대상, 즉 생성자 함수의 prototype이 연결하고자 하는 상위 생성자 함수의 인스턴스를 바라보게끔 해주면 됨

var Grade = function() { var args = Array.prototype.slice.call(arguments); for (var i = 0; i < args.length; i++) { this[i] = args[i]; } this.length = args.length; }; var g = new Grade(100, 80); // g는 Grade의 인스턴스를 바라봄 //Grade 인스턴스는 배열 형태를 지녔지만, 배열 메서드를 사용할 수 없는 유사배열객체

Grade.prototype = []; //배열 메서드를 사용할 수 있도록 배열의 인스턴스를 바라볼 수 있도록 함

console.log(g); // Grade(2) [100, 80] g.pop(); console.log(g); // Grade(1) [100] g.push(90); console.log(g); // Grade(2) [100, 90]

OHKuenYoung commented 4 years ago

프로토타입 체인

6-2-1 메서드 오버라이드

메서드 위에 메서드를 덮어씌운 것을 메서드 오버라이드라 한다.

var Person = function(name) {
  this.name = name;
};

Person.prototype.getName = function() {
  return this.name;
}

var iu = new Person('지금');
iu.getName = function() {
  return '바로' + this.name;
}

console.log(iu.getName()); //바로 지금

메서드 오버라이딩이 이뤄져 있는 상황에서 prototype에 있는 메서드에 접근 하는 법

console.log(iu.__proto__.getName.call(ui)); //지금

일반 적으로 메서드가 오버라이드된 경우에는 자신으로 부터 가장 가까운 메서드에만 접근할 수 있지만, 그다음으로 가까운 proto 의 메서드도 우회적인 방법을 통해서 접근이 가능하다.

6-2-2 프로토타입 체인

어떤 데이터의 proto 프로퍼티 내부에서 다시 proto 프로퍼티가 연쇄적으로 이어진 것을 프로토타입 체인 이라고 한다.

var arr =[1,2];
Array.prototype.toString.call(arr); // 1,2
Object.prototype.toString.call(arr); // [Object Array]
arr.toString(); // 1,2

arr.toString = function() {
  return this.join('_');
}

arr.toString(); // 1,2

6-2-3 객체 전용 메서드의 예외사항

prototype은 객체이기 때문에 Object.prototype이 언제나 프로토타입 최상단의 존재. 따라서 객체에서만 사용할 메서드는 다른 여느 데이터 타입에서 프로토타입 객체 안에 정의할 수 없다.

예외적으로 Object.create를 이용하면 Object.prototype 메서드의 접근할 수 엇는 경우

var _proto= Object.create(null);
_proto.getValue = function (key) {
    return this[key];
};

var obj = Object.create(_proto);
obj.a = 1;
console.log(obj.getValue('a));
console.dir(obj);

6-2-4 다중 프로토타입 체인

대각 선의 proto를 연결해나가기만 하면 무한대로 체인 관계를 이어나갈 수 있다.

var Grade = function() {
   var args = Array.prototype.slice.call(arguments);

   for (var i = 0; i < args.length; i++) {
      this[i] = args[i]
    }

   this.length = args.length;
}

var g = new Grade(100, 80);
hyeonggyo commented 4 years ago

6-2-1 메서드 오버라이드

var Person = function (name) {
    this.name = name;
};
Person.prototype.getName = function () {
    return this.name;
};

var iu = new Person('지금');
iu.getName = function () {
    return + '바로' + this.name;
};
console.log(iu.getName()); //바로 지금

//iu.__protoo__.getName이 아닌 iu 객체에 있는 getName 메서드가 호출됨

6-2-2 프로토 타입 체인

// 메서드 오버 드라이브와 프로토타입 체이닝
var = arr = [1, 2];
Array.prototype.toString.call(arr); // 1, 2
Object.prototype.to String.call(arr); // [object, Array]
arr.toString();                                 // 1, 2

arr toString = function () {
    return this.join('_');
};
arr.toString();                                  // 1_2

6-2-3 객체 적용 메서드의 예외사항

//Object.prototype에 추가한 메서드에서의 접근
Object.prototype.getEntries = function() {
    var res = [];
    for (var prop in this) {
        if (this.hasOwnprotoperty(prop)) {
             res.push([prop, this[prop]]);
        }
    }
    return res;
};
var date = [
    ['object', {a:1,b:2, c:3}], // [["a",1],["b",2],["c",3]]
    ['number', 345],//[]
    ['string', 'abc'], // [["0","a"],["1","b"],["2","c"]]
    ['boolean', false],  //[]
    ['func', function () {}],  //[]
    ['array', [1,2,3,4,5]] // array lterator {}
];
data.forEach(function(datum){
    console.log(datum[1].getEntries());
});

6-2-4 다중 프로토타입 체인

// Grade 생성자 함수와 인스턴스
var Grade = function () {
    var args = Array.prototype.slice.call)arguments);
    for (var i = 0; i < args.length; i++) {
        this[i] = args[i];
    }
    this.length = args.length;
};
var g = new Grade(100, 80);
eunzy38 commented 4 years ago

프로토타입 체인

1. 메서드 오버라이드

var Person = function(name) {
  this.name = name;
};
Person.prototype.getName = function() {
  return this.name;
};

var iu = new Person('지금');
iu.getName = function() {
  return '바로 ' + this.name;
};
console.log(iu.getName());     // 바로 지금

ㄴ getName이라는 메서드를 찾는 방식은 가장 가까운 대상인 자신의 프로퍼티를 검색하고, 없으면 그 다음으로 가까운 대상인 proto를 검색하는 순서로 진행

console.log(iu.__proto__.getName.call(iu)); // 바로 지금

ㄴ this가 prototype을 바라보고 있는 것을 인스턴스를 바라볼 수 있도록 call이나 apply를 사용하여 해결가능

일반적으로 메서드가 오버라이드된 경우에는 자신으로부터 가장 가까운 메서드에만 접근할 수 있지만, 그 다음으로 가까운 proto의 메서드도 우회적인 방법을 통해 접근 가능

2. 프로토타입 체인

arr.toString = function() { return this.join('_'); }; arr.toString(); // 1_2


### 3. 객체 전용 메서드의 예외사항
- 어떤 생성자 함수든  prototype은 반드시 객체이기 때문에 Object.prototype이 언제나 프로토타입 체인의 최상단에 존재
- 객체에서만 사용할 메서드를 Object.prototype 내부에 정의한다면 다른 데이터 타입에도 해당 메서드를 사용할 수 있게 됨
- Object.prototype에는 어떤 데이터에서도 활용할 수 있는 범용적인 메서드들만 있음
   (toString, hasOwnProperty, valueOf, isPrototypeOf 등)

### 4. 다중 프로토타입 체인
- 기본 내장 데이터 타입들은 모두 프로토타입 체인이 1단계(객체)이거나 2단계(나머지)로 끝나는 경우만 있었지만, 사용자가 새롭게 만드는 경우는 그 이상 확장 가능
- 대각선의 __proto__를 연결해나가기만 하면 무한대로 체인 관계를 이어나갈 수 있음
- 대각선의 __proto__를 연결하는 방법은 __proto__가 가리키는 대상, 즉 생성자 함수의 prototype이 연결하고자 하는 상위 생성자 함수의 인스턴스를 바라보게끔 해주면 됨

```javascript
var Grade = function() {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < args.length; i++) { 
    this[i] = args[i];
  }
  this.length = args.length;
}; //Grade 인스턴스는 배열 형태를 지녔지만, 배열 메서드를 사용할 수 없는 유사배열객체
var g = new Grade(100, 80);  // g는 Grade의 인스턴스를 바라봄
Grade.prototype = []; //배열 메서드를 사용할 수 있도록 배열의 인스턴스를 바라볼 수 있도록 함
console.log(g);  // Grade(2) [100, 80]
g.pop();
console.log(g);  // Grade(1) [100]
g.push(90);
console.log(g);  // Grade(2) [100, 90]