자바스크립트는 객체기반의 프로그래밍 언어이며, 자바스크립트를 구성하는 거의 "모든 것"이 객체이다. (원시값 제외!)
프로퍼티: 객체의 상태를 나타내는 값
메서드: 프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라 부른다.
자바스크립트에서 함수와 객체는 분리해서 생각할 수 없는 개념이다. 즉, 객체를 이해해야 함수를 제대로 이해할 수 있고, 반대로 함수를 이해해야 객체를 완전히 이해할 수 있다.
객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임을 객체지향 프로그램이라고 한다.
자바스크립트에서 객체 생성 방법
객체 리터럴
Object 생성자 함수
생성자 함수
Object.create 메서드
클래스(ES6)
객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.
let person = {
// 프로퍼티 키는 name, 프로퍼티 값은 "Park"
name: "Park",
// 프로퍼티 키는 age, 프로퍼티 값은 27
age: 27
};
let obj = {};
let key = "hello";
// ES5: 프로퍼티 키 동작 생성
obj[key] = "world";
// ES6: 계산된 프로퍼티 이름
// let obj = { [key]: 'world' };
console.log(obj); // {hello: "world"}
let person = {
name: "Park",
};
console.log(person.name); // Park
console.log(person["name"]); // Park
let x = 1; y = 2;
const obj = {x, y};
console.log(obj); // {x: 1, y: 2}
const prefix = "prop";
let i = 0;
const obj = {
[`${prefix}-${++i}`]: i,
[`${prefix}-${++i}`]: i,
[`${prefix}-${++i}`]: i
};
console.log(obj); // {prop-1: 1, prop-2: 2, prop-3: 3};
프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라 부른다. 즉, 메서드는 객체에 묶여 있는 함수이다.
let circle = {
radius: 5, // 프로퍼티
// 원의 지름
getDiameter: function() { // 메서드
return 2 * this.radius; // this는 circle을 가리킨다.
};
console.log(circle.getDiameter()); // 10
메서드 내부에서의 this는 객체 자신을 가리키는 참조 변수다.
const obj = {
name: 'Park',
sayHi() {
console.log('Hi! ' + this.name);
}
};
obj.sayHi(); // Hi ! Park
변경 불가능하다는 것은 변수가 아니라 값에 대한 진술이다.
원시 값은 변경 불가 ! 즉 읽기 전용 값 !
// const 키워드를 사용해 선언한 변수는 재할당이 금지된다. 상수는 재할당이 금지된 변수일 뿐이다.
const o = {};
// const 키워드를 사용해 선언한 변수에 할당한 원시 값(상수)은 변경할 수 없다.
// 하지만 const 키워드를 사용해 선언한 변수에 할당한 객체는 변경할 수 있다.
o.a = 1;
console.log(o); // {a: 1}
1)
let score = 80;
let copy = score;
console.log(score); //80
console.log(copy); // 80
score = 100;
console.log(score); // 100
console.log(copy); // 80
2)
let score = 80;
let copy = score;
console.log(score, copy); // 80 80
console.log(score === copy); // true
이때 score 변수와 copy변수 의 값 80은 다른 메모리 공간에 저장된 별개의 값이다.
3)
let score = 80;
let copy = score;
console.log(score, copy); // 80 80
console.log(score === copy); // true
score = 100;
console.log(score, copy); // 100 80
console.log(score === copy); // false;
1)
let person = {
name: 'Park'
};
객체를 할당한 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근한다.
2) 얕은 복사 깊은 복사
객체를 프로퍼티 값으로 갖는 객체의 경우 얕은 복사는 한 단계까지만 복사하는 것을 말하고 깊은 복사는 객체에 중첩되어 있는 객체까지 모두 복사하는 것을 말한다.
const o = { x: { y: 1} };
// 얕은 복사
const c1 = {...o};
console.log(c1 === o); // false
console.log(c1.x === o.x); // true
const v = 1;
// 깊은 복사
const c1 = v;
console.log(c1 === v); // true
const o = { x: 1};
// 얖은 복사
const c2 = o;
console.log(c2 === o); // true
3) 참조에 의한 전달
let person = {
name: 'Park'
};
// 참조 값을 복사 (얕은 복사)
let copy = person;
Quiz) 다음을 실행하면 1번과 2번은 뭐가 출력될까?
let person1 = {
name: 'Park'
};
let person2 = {
name: 'Park'
};
console.log(person1 === person2); 1번
console.log(person1.name === person2.name); 2번
정답: 1번은 false. 2번은 true이다.
이유는 person1과 person2의 내용을 같지만 서로가 다른 메모리에 저장되어 있기 때문에 참조 값은 전혀 다르므로 1번은 false 이다.
프로퍼티 값을 참조하는 person1.name과 person2.name은 값으로 평가될 수 있는 표현식이므로 두 표현식의 원시 값은 'Park'이므로 true이다.
function add(x, y) {
return x + y;
}
let add = function add(x, y) {
return x + y;
};
console.log(add(2, 5)); // 7
자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.
함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다.
const add = function(x, y) {
return x + y;
}
const add = new Function('x', 'y', 'return x + y');
const add = (x, y) => x + y;
함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르다.
(function () {
let a = 3;
let b = 5;
return a + b;
}());
function countdown(n){
if (n < 0) return;
console.log(n);
countdown(n - 1); // 재귀호출
}
countdown(10);
function outer() {
let x = 1;
function inner() {
let y = 2;
console.log(x + y); // 3
}
inner();
}
outer();
function introduce (lastName, firstName, callback) {
let fullName = lastName + firstName;
callback(fullName);
}
introduce ("박", "경빈", function (name) {
console.log(name);
};
// 결과 -> 박경빈
// 비 순수함수
let count = 0;
function increase(n) {
return ++count; // 외부 상태에 의존
}
increase();
console.log(count); // 1
increase();
console.log(count); // 2
// 순수함수
let count = 0;
function increase(n) {
return ++n;
}
count = increase(count);
console.log(count); // 1
count = increase(count);
console.log(count); // 2