[javascript] prototypal inheritance


プロトタイプチェーンとは?


上に接続されたprotoは近づくことができます.

プロトタイプチェーンの確認

__proto__と確認できます.
const array = [];
array.__proto__ // Array
array.__proto__.__proto__ // Object

array.toString() // 이걸 사용할 수 있는 이유는 prototype chain에서 Object에 toString이 있기 때문이다.

memory efficient


proto chainによって、共同で使うものの記憶を減らすことができます.(そうでなければ、arrayを作成するたびに新しいmap関数が作成されることを想像するなど、同じ方法を使用することをコピーする必要があります.)

Example


bigobjectは、プロトタイプチェーンを用いて1つ以上の方法を取得することができる.
const dog = {
  sound() {
    return `${this.name} is barking`
  }
}

const brown = {
  type: 'dog',
  name: 'brown',
  color: 'black'
}

brown.__proto__ = dog;
brown.sound(); // brown is barking
dog.isPrototypeOf(brown) // true

__proto__

__proto__とは、上部に位置するprototye objectを指す.

実際には、__proto__はコードでは使用されません.__proto__の代わりにObject.getPrototypeOf(obj)を使用します.
const dog = {
  sound() {
    return `${this.name} is barking`
  }
}

const brown = {
  type: 'dog',
  name: 'brown',
  color: 'black'
}

brown.__proto__ = dog;

Object.getPrototypeOf(brown) // {sound: f}

prototype


コンストラクション関数の名前はPascalCaseを使用します.
// Person은 constructor function이 된다.
function Person(name) {
	this.name = name;
}
/* Person 함수는 아래 class와 동일합니다.
class Person {
	constructor(name) {
    	this.name = name;
    }
}
*/

Person.prototype // { constructor: f Person(name) }

const brown = new Person('brown') // constructor로 instance를 생성합니다.
brown.name // brown

Brown.prototype.sayHi = function() { // sayHi라는 method를 추가합니다.
  return 'Hello'
}
brownClone.sayHi() // Hello
object(またはinstance)ではプロトタイプを作成できません.
const brown = {}
console.log(brown.prototype) // undefined

brown.prototype = 'brown'
console.log(brown) // { prototype: 'brown' } 단순히 prototype이라는 이름의 property가 생김
prototype property(prototype名のkeyだけでなく)を持つのはfunctionのみです.
Object.Prototypeがあるので、オブジェクト自体がコンストラクション関数であると混同される可能性があります.△次のtypeofの違いを見ればわかります.
typeof Object // function
typeof Object.prototype // object

protoとprototypeの関係

__proto__は上流チェーンのプロトタイプを指す.
const array = [];
array.__proto__ === Array.prototype // true
array.__proto__.hasOwnProperty('map') // true
arrayの父のモデルはArrayです.原型です.したがって、array.__proto__Array.prototypeである.

hasOwnProperty


objectに特定の属性があるかどうかを確認できます.
const obj = { name: 'cho' }
obj.hasOwnProperty('name'); // true

Object.create


objectのprototype chainを作成するには、「Object」をクリックします.作成できます.
let human = {
  mortal: true,
}

let socrates = Object.create(human)
socrates.age = 80
socrates.mortal

console.log(human.isPrototypeOf(socrates)) // true
console.log(socrates.hasOwnProperty('mortal')) // false

Practice


LastYearメソッドをDateに追加

Date.prototype.lastYear = function() {
  return this.getFullYear() - 1; // this는 new Date()의 모든값을 받는다. (lastYear을 invoke한게 new Date()이기 때문)
}

new Date('1900-10-10').lastYear() // 1899

mapメソッド#1の作成(既存のArrayを上書き)

Array.prototype.map = function() {
  const array = [];
  for (let i = 0; i < this.length; i++) {
    array.push(this[i] + '🚀') // this는 arr의 모든 값을 받는다. (map을 invoke한게 arr이기 때문)
  }
  return array;
}

const arr = [1,2,3];
arr.map() // ['1🚀', '2🚀', '3🚀']

mapメソッド#2の作成

function MyArray(arr) {
    this.arr = arr;
}

MyArray.prototype.map = function (callback) { // 여기서는 arrow function을 쓰지 않아야합니다. (this에 접근하기 위해서)
    let newArr = [];
    for (let value of this.arr) {
        newArr.push(callback(value));
    }
    return newArr;
}

const myArray = new MyArray([1,2,3]);

console.log(myArray.map(num => num+1))