-복습-
var age = 20;
var obj = {
name: '홍길동'
getName: function() { // 메서드(실제 메서드는 아니다!, 메서드로 취급)
console.log("getName");
}
setName() { // JS의 메서드(ES6에서 도입됨)
...
}
// age: age;
age // property 생성 축약표현
}
JS 함수는 함수의 이름으로 호출되지 않고 식별자로 호출됨 => 익명 함수가 많이 사용됨
Primitive
Reference
: 함수를 표현하기 위한 형식
function functionName(parameter...) {
...
}
function add(x, y) {
return x + y;
}
var myFunc = function(x, y) {
retuurn x + y
}
var add = new Function('x', 'y', 'return x + y');
함수 객체 parameter 함수 실행 코드
var add = (x, y) => x + y;
객체 literal을 이용한 객체 생성
const person = {};
person.name = 'person';
console.dir(person);
생성자 함수를 이용한 객체 생성
=> instance
- new keyword를 이용해서 생성자 함수 호출
- 대표적인 생성자 함수(built-in) : Object(), String(), Number(), Boolean(), Function(), Array()
- 생성자 함수와 일반 함수의 차이는 없다. 생성자 함수로 사용할 때에는 new 키워드를 붙여 사용하면 된다. 그러나 사용 시 혼란이 생길 수 있으므로 생성자 함수의 이름을 대문자로 시작하여 생성자 함수라 표시한다.
```
const person = new Object();
person.name = 'person';
console.dir(person);
```
(User define) 생성자 함수
이름 식별자 : PascalCase
function Person() {
// this
// this라는 keyword는 생성자 함수일 경우도 있고
// 일반 함수인 경우에도 있음
// 생성자 함수에서의 this : 생성자 함수에 의해 만들어질 instance
// 일반함수에서의 this : window
console.log(this);
}
const person1 = Person();
console.log(person1); // undefined : 함수의 반환값이 없기 때문에
const person2 = new Person();
console.log(person2); // Person {} (= this)
// 생성자 함수는 return 구문을 사용하지 않는다. 자동으로 객체를 생성하고 this에 바인딩하여 반환
const person3 = {};
console.log(person3); // {}
생성자 함수를 'new' keyword로 호출 => instance
생성자 함수가 객체를 return하면 변수에 return된 객체가 바인딩된다.
생성자 함수가 객체가 아닌 값을 return하면 정상적으로 객체가 생성되어 바인딩된다.
따라서 생성자 함수에는 return 문을 쓰지 않는 것을 권장
다시 듣기 : 0706-4 20분
var obj = {
name: '홍길동'
}
console.dir(obj);
function square(number) {
return number* number;
}
console.dir(square);
!!! 모든 객체는 내부 슬롯 [[Prototype]] 을 가지고 있음 !!!
Javascript Engine이 동작
1) built-in 객체 생성(Object, String, ...)
2) 전역객체 생성(window)
3) creation phase : 런타임 전 코드를 훑음
- var 또는 사용자 정의 (생성자 함수) 객체의 식별자를 발견하면 전역객체의 property에 추가
- 함수가 선언되어있을 경우, 함수 식별자가 전역객체의 property로 저장됨
- 그 property의 value는 함수를 가리키는 함수의 주소
- let, const 변수는 전역객체의 property에 추가되지 않음
function Person(name) {
// 생성자 함수로 만들어질 instance가 가지는 property를 설정
this.name = name;
}
함수 객체 'Person'
property key | property value |
---|---|
arguments | 인자를 담은 유사 객체 배열 |
caller | 함수 자신을 호출한 함수에 대한 reference |
length | parameter 개수 |
name | 함수 이름 |
[[Prototype]] | |
prototype | Person(생성자 함수 객체)의 prototype 객체 참조 |
생성자 함수로 만든 instance 객체 'person1'
property key | property value |
---|---|
name | '홍길동' |
[[Prototype]] | Person(생성자 함수 객체)의 prototype 객체 참조 |
__proto__ | Person(생성자 함수 객체)의 prototype 객체 참조 |
생성자 함수로 만든 instance 객체 'person2'
property key | property value |
---|---|
name | '홍길동' |
[[Prototype]] | Person(생성자 함수 객체)의 prototype 객체 참조 |
__proto__ | Person(생성자 함수 객체)의 prototype 객체 참조 |
'Person'(생성자 함수 객체)의 prototype 객체
property key | property value |
---|---|
[[Prototype]] | Person(생성자 함수 객체)의 prototype 객체 참조 |
constructor | Person(생성자 함수 객체) |
[[Prototype]]의 목적 : 상속 chain을 구성하기 위해
// 생성자 함수
function Circle(radius) {
this.radius = radius;
this.getDiameter = function() {
return 2 * radius;
}
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter === circle2.getDiameter);
// false : 함수 객체가 두 개 만들어 짐 => 메모리 낭비
Java : 클래스 기반의 상속
JS : prototype 객체 기반의 상속
JS는 상속할 공통 property를 prototype에 저장한다.
function Circle(radius) {
this.radius = radius;
Circle.prototype.getDiameter = function() {
return 2 * this.radius;
}
}
circle1 = new Circle(5);
circle2 = new Circle(10);
console.log(circle1.getDiameter === circle2.getDiameter); // true
function Circle(radius) {
this.radius = radius;
Circle.prototype.getDiameter = function() {
return 2 * this.radius;
};
Circle.prototype.name = '홍길동';
}
circle1 = new Circle(5);
circle2 = new Circle(10);
console.log(circle1.name, circle2.name); // 홍길동 홍길동
console.log(circle1.getDiameter === circle2.getDiameter); // true
console.log(circle1.name, circle2.name); // 홍길동 아이유
// => circle2.name = '아이유'; 는 property를 바꾸는 것이 아니라 새로운 property를 추가한 것이다.
Circle.prototype.name = '아이유';
console.log(circle1.name, circle2.name); // 아이유 아이유
circle1.__proto__.name = '김가나';
console.log(circle1.name, circle2.name); // 김가나 김가나
function Square(width) {
this.width = width;
}
console.log(Square.prototype);
console.log(circle1.name);
[[Prototype]] : (상위) prototype 객체 => 객체 생성 방법에 따라 종류가 달라짐
함께 읽어보면 좋은 글
https://www.howdy-mj.me/javascript/prototype-and-proto/
=> 가변인자함수를 만들 때 사용
function foo(param1, ...args) {
console.log(arguments);
// [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
console.log(args);
// [ 2, 3, 4, 5 ]
}
foo(1, 2, 3, 4, 5);