원형 객체
모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다
상속
을 JavaScript에서 구현할 때 사용
프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지.
다른 객체에 정의된 메소드와 속성을 특정 객체에서 사용할 수 있도록 하는 근간
상속되는 속성과 메소드들은 (각 객체가 아니라) 객체의 생성자의 prototype이라는 속성에 정의되어 있습니다.
__proto__
[dunder proto]
특정 객체의 프로토타입 객체에 접근 가능하게 하는 속성
(프로토타입 체이닝에 의해서 __proto__
를 참조하게 하는 자바스크립트 자체의 작동 원리)
모든 객체들이 가지는 메소드와 속성들을 상속 받기 위한 템플릿
__proto__
속성으로 접근 가능한 내장 객체
상속 받은 멤버들(속성, 메소드들)이 정의된 객체의 생성자에 있는 속성
프로토타입 체인을 통해 상속하고자 하는 속성과 메소드를 담아두는 버킷으로 주로 사용되는 객체
Object.
(x)
Object.prototype.
(o)
원본 생성자 함수 자신
person1의 프로토타입 객체인 Person()에 정의된 멤버들
— name, age, gender, interests, bio, greeting을 볼 수 있습니다.
또한 — watch, valueOf처럼 Person()의 프로토타입 객체인 Object에 정의된 다른 멤버들도 보실 수 있습니다. 이는 프로토타입 체인이 동작한다는 증거입니다.
[그림] 클래스 Human과 인스턴스, 그리고 프로토타입의 관계 모식도
[그림] 배열 arr과 Array, 프로토타입의 관계 모식도
클래스를 다른 클래스의 자식으로 만들기 위해 class 선언 또는 class 식에 사용
상위 클래스의 생성자를 호출하며 super()의 매개변수를 통해 상위 클래스의 멤버를 상속받을 수 있는 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Object-oriented JavaScript class further exercises</title>
</head>
<body>
<p>This example requires you to enter commands in your browser's JavaScript console (see <a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">What are browser developer tools</a> for more information).</p>
</body>
<script>
function Person(first, last, age, gender, interests) {
this.name = {
'first': first,
'last' : last
};
this.age = age;
this.gender = gender;
this.interests = interests;
this.bio = function() {
// First define a string, and make it equal to the part of
// the bio that we know will always be the same.
var string = this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. ';
// define a variable that will contain the pronoun part of
// the second sentence
var pronoun;
// check what the value of gender is, and set pronoun
// to an appropriate value in each case
if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
pronoun = 'He likes ';
} else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
pronoun = 'She likes ';
} else {
pronoun = 'They like ';
}
// add the pronoun string on to the end of the main string
string += pronoun;
// use another conditional to structure the last part of the
// second sentence depending on whether the number of interests
// is 1, 2, or 3
if(this.interests.length === 1) {
string += this.interests[0] + '.';
} else if(this.interests.length === 2) {
string += this.interests[0] + ' and ' + this.interests[1] + '.';
} else {
// if there are more than 2 interests, we loop through them
// all, adding each one to the main string followed by a comma,
// except for the last one, which needs an and & a full stop
for(var i = 0; i < this.interests.length; i++) {
if(i === this.interests.length - 1) {
string += 'and ' + this.interests[i] + '.';
} else {
string += this.interests[i] + ', ';
}
}
}
// finally, with the string built, we alert() it
alert(string);
};
this.greeting = function() {
alert('Hi! I\'m ' + this.name.first + '.');
};
};
let person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']);
</script>
</html>
기계적 사고방식이 너무 어려웠기 때문에
사람이 사고하는 방식과 비슷하게 만들기 위해서 필요해졌다.
// Case 1. 컴퓨터에게 편한 방식
// assembly === 절차 지향적 언어
메모리 0 - 카운터 할당 = 0
메모리 1 - 카운터 증가
메모리 2 - 출력 'hongsik'
메모리 3 - 카운터와 원하는 반복 횟수 비교
메모리 4 - 카운터 === 원하는 반복 횟수 false? 메모리 1
// 메모리 0 ~ 3을 for문을 통해 반복한다.
// Case 2. 은행 송금 기능
메모리 0 - 송금 주소 할당 = 0000000000
메모리 1 - 전달 받은 주소의 정보를 조회
메모리 2 - 16글자가 넘어서.. 그 다음 메모리 조회
메모리 3 - 16글자가 넘어서.. 그 다음 메모리 조회
...
메모리 10 - 전달 받은 주소 정보 조회 끝!
메모리 11 - 전달 받은 주소로 송금하기 메모리 1259124 조회
하드디스크 1 - ? 아니네
하드디스크 2 - ? 아니네
// Case 3 객체 지향 프로그래밍
// => 컴퓨터 왜 쓰나요? 게임 ,일, => 편할려고, 좀 더 쉽게
// => 개발 => 상업적 가치
// => 효율적으로 해야 한다. 사람이 쓸 수 있게 개발해야 한다.
// 기계적 사고방식이 너무 어려웠기 때문에
// 사람이 사고하는 방식과 비슷하게 만들기 위해서 필요해졌다.
class 은행계좌 {
constructor(){
}
은행계좌주소: string
송금 : () => {
송금에 필요한 코드
}
입금 : () => {
입금에 필요한 코드
}
}
A - 주장
R - 근거
E - 예시
참조
하는지 그림으로 그려보자.메모리 주소(refeence) 값을 가리키고 있다
class Humam를 생성한다.
그 안에 속성(name
, age
)과 메소드(sleep()
)를 정의한다.
new 연산자를 사용하여 인스턴스를 생성한다.new Human('kimcoding, 30)
Human의 이름은 'kimcoding', 나이는 30살.
2번 코드를 작성함과 동시에(new Human('kimcoding', 30
), __proto__
가 자동으로 생성된다.
new 연산자를 사용하여 인스턴스(kimcoding
)를 호출할 때,
속성
과 메소드
를 전달해줄 수 있는 객체
class 내부에 constructor
내부의 속성
과 하단의 메소드
가 적혀있긴 하지만, Human.prototype
내부에 있다고 보는 것이 맞다.
속성을 인스턴스
로 전달해주는 일련의 코드
인스턴스
에는 메소드 관련 정보가 담겨있지 않다.
따라서, __proto__
가prototype chaining
을 통해서 해당 메소드에 접근할 수 있음
즉, 메소드 관련 정보
가 담겨있음
__proto__
(kimcoding.__proto__
)dunder proto
new 연산자를 사용하여 인스턴스(kidmcoding
)를 호출할 때, 자동으로 생기는 '객체'
참조 자료형인 객체(kimcoding.__proto__
)는 prototype chaining
을 통해서
메소드 sleep
을 찾기 위해 Human.prototype
을 참조한다.
따라서, 인스턴스
에는 메소드 관련 정보가 담겨있지 않지만메소드 sleep()
을 호출할 수 있다.
kimcoding
은 __proto__
객체를 거쳐서 Human.prototype
을 참조한다.
따라서 이 코드는 true
가 된다.
kimcoding
인스턴스에 메소드(sleep()
)이 없기 때문에,
__proto__
객체를 거쳐서 이 주소가 Human.prototype
으로 간다.
이러한 prototype.chaining
을 통해 Human.prototype.sleep
을 참조한다.
따라서 이 코드는 true
가 된다.
클래스(Human
)안에 prototype(Human.prototype
)이라는 객체가 연결되어 있다.
이 객체 안에 constructor
라는 속성(주소)를 만들었다.
이 주소(Human.prototype.constructor
)는 Human
을 가리킨다(참조한다).
Human을 new로 호출했을 때, 속성을 인스턴스 객체로 전달하는 역할을 한다.
constructor라는 속성은 Human과 같다.
따라서 이 코드는 true
가 된다.
따라서 이 코드는 {[ native code ]}가 된다.
'그런건 없다'고 생각하면 된다.
클래스가 인스턴스를 호출할 때, 클래스.prototype을 거쳐서 속성을 전달해준다.
반드시 new 연산자를 사용해야 한다.
이때 호출된 인스턴스에는 메소드 정보가 담겨있지 않기 때문에,
인스턴스는 호출 시 자동 생성된 __proto__
을 거쳐서 '클래스.prototype'을 참조하여 메소드를 호출할 수 있다. 이때, '클래스.prototype'은 '클래스.prototype.constructor'를 통해 클래스를 참조한다.
// 1번 코드
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
sleep() {
console.log(`${this.name}은 잠에 들었습니다`);
}
}
// 2번 코드
let kimcoding = new Human('김코딩', 30);
// 실습해보세요
// 실습1
Human.prototype.constructor === Human; // 결과는 무엇일까요? true
// 실습2
Human.prototype === kimcoding.__proto__; // 결과는 무엇일까요? true
// 실습3
Human.prototype.sleep === kimcoding.sleep; // 결과는 무엇일까요? true