프로토타입

1
2
3
4
5
6
7
const user = {
  name: "Yuri"
};

console.log(user.name); //yuri
console.log(user.hasOwnProperty("name")); //true
console.log(user.hasOwnProperty("age")); //false

hasOwnProperty() 메소드는?

  • 객체가 특정 프로퍼티를 가지고 있는지를 나타내고 불리언 값을 반환한다.
  • user 안에 -> __proto__ -> prototype
  • hasOwnProperty 객체안에있으면 바로 출력하고 없으면 프로토타입에 탐색한다.

1. 공통된 부분이 중복으로 만들고 있음 (안좋은코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const bmw = {
  color: "red",
  wheels: 4,
  navigation: true,
  drive() {
    console.log("드라이브함수");
  }
};
const benz = {
  color: "black",
  wheels: 4,
  drive() {
    console.log("드라이브함수");
  }
};
const audi = {
  color: "blue",
  wheels: 4,
  drive() {
    console.log("드라이브함수");
  }
};

2. 공통된 부분을 따로 뺌, proto로 상속을 받을 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const car = {
  wheels: 4,
  drive() {
    console.log("드라이브함수");
  }
};
const bmw = {
  color: "red",
  navigation: true
};
const benz = {
  color: "black"
};
const audi = {
  color: "blue"
};

bmw.__proto__ = car; // car의 상속을 받게된 bmw
benz.__proto__ = car;
audi.__proto__ = car;

console.log("bmw" + bmw, "benz" + benz, "audi" + audi);
console.log(bmw.color, bmw.wheels); //bmw 내부에서 wheels 프로퍼티를 찾고 없으면 그다음 __proto__에서 찾는다.

Prototype chain

3. 상속은 계속 이어질수 있다.

1
2
3
4
5
6
7
8
//이어서
const porsche = {
  color: "포르쉐 흰색",
  name: "포르쉐"
};
porsche.__proto__ = bmw;
console.log(porsche.navigation);
// porsche __proto__ -> bmw __proto__ -> car __proto__ 순서로 프로토타입을 탐색함

For in 으로 객체의 프로퍼티 순회

1
2
3
4
5
6
for (p in porsche) {
  console.log(p); //
}
console.log(porsche);
console.log(Object.keys(porsche));
console.log(Object.values(porsche));
1
2
3
4
5
6
7
8
for (p in porsche) {
  if (porsche.hasOwnProperty(p)) {
    // 객체가 직접 가지고 있는 프로퍼티만 반환한다
    console.log("o", p);
  } else {
    console.log("x", p);
  }
}

생성자 함수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const Bmw = function (color) {
  this.color = color;
};
// 생성하는객체에 프로토타입을 사용해서 속성을 넣어줌
Bmw.prototype.wheels = 4;
Bmw.prototype.navigation = 1;
Bmw.prototype.drive = function () {
  console.log("드라이브함수");
};

console.log(porsche.wheels, porsche.navigation, porsche.drive);

const porsche = new Bmw("red");
const tesla = new Bmw("blue");

// porsche.__proto__ = car; 이런게 필요없어짐
// tesla.__proto__ = car;

instance of

  • 객체와 생성자를 비교할수 있고, 해당 객체가 생성자로부터 생성된것인지 판단해서 true,false를 판단한다.
1
2
console.log(tesla);
console.log(tesla instanceof Bmw);
1
2
//생성자를 만들어준 인스턴스 객체는 constructor라는 프로퍼티가 존재한다.
console.log(tesla.constructor === Bmw); //true
1
2
3
4
5
6
7
8
9
10
//생성자가 없어지니까 하나씩 프로퍼티를 만들어줘야한다.
Bmw.prototype = {
  //constructor: Bmw, 이렇게 명시해줘도됨
  wheels: 4,
  drive() {
    console.log("드라이브 함수");
  },
  navigation: 1
};
console.log(tesla.constructor === Bmw); //false

getColor

  • 생성될 당시의 값을 기억함
1
2
3
4
5
6
// color값을 마음대로 변경가능한 코드
const Bmw = function (color) {
  this.color = color;
};
const porsche = new Bmw("red");
console.log((porsche.color = "black")); // 마음대로 변경가능함
1
2
3
4
5
6
7
8
9
//getColor 사용 (color를 계속 바꾸면안되니까)
const Bmw = function (color) {
  const c = color;
  this.getColor = function () {
    console.log(c); // 클로저 먼저 값을 기억하게하는것
  };
};
const porsche = new Bmw("red");
console.log(porsche.getColor);