자바스크립트 객체는 객체지향의 상속을 구현하기 위해
프로토타입(prototype)이라고 부르는 객체의 프로퍼티와 메소드를 상속받을 수 있다.
프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 symbol(원시 자료형) 값
프로퍼티 값 : 모든 값
프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메소드라 부름
즉, 메소드는 객체에 제한되어 있는 함수를 의미
//객체 리터럴 문법 = 객체 선언 시 주로 객체 리터럴 사용
var user = new Object();
// {} 내에 아무것도 기술하지 않으면 빈 객체 생성
var user = {};
var person = {
name : 'Choi',
gneder : 'femail',
sayHi : function() {
console.log(`Hi!`);
}
};
console.log(person);
//{name: 'Choi', gneder: 'femail', sayHi: ƒ}
person.sayHi();
//Hi!
//빈 객체 생성
var person2 = new Object();
//프로퍼티 추가
person2.name = 'Choi';
person2.gender = 'female';
person2.sayHi = function() {
console.log('Hi! My name is ' + this.name);
};
console.log(typeof person2); //object
console.log(person2); //{name: 'Choi', gender: 'female', sayHi: ƒ}
Object 생성자 함수를 사용해 빈 객체를 생성해야 하는 것은 아님!
객체 생성법은 리터럴을 사용하는 것을 권장.
사실 객체 리터럴 방식으로 생성된 객체는
결국 빌트인 함수인 Object 생성자 함수로 객체를 생성하는 것을 단순화시킨 축약 표현
var person3 = {
name : 'Choi',
gender : 'female',
sayHi : function() {
console.log('Hi! i am ' + this.name);
}
};
var person4 = {
name : 'Kim',
gender : 'female',
sayHi : function() {
console.log('Hi! i am' + this.name);
}
};
//생성자 함수를 사용하며 마치 객체를 생성하기 위한 템플릿(클래스)처럼 사용하여
//프로퍼티가 동일한 객체 여러개를 간편하게 사용할 수 있다.
//생성자 함수
function Person(name, gender) {
this.name = name;
this.gender = gender;
this.sayHi = function() {
console.log('Hi i am ' + this.name);
};
}
//인스턴스 생성
var person1 = new Person('Kim', 'male');
var person2 = new Person('Lee', 'feamle');
console.log('person1 : ', typeof person1);
console.log('person2 : ', typeof person2);
console.log('person1 : ', person1);
console.log('person2', typeof person2);
person1.sayHi();
person2.sayHi();
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male',
1: 10,
function: 1 // OK. 하지만 예약어는 사용하지 말아야 한다.
};
console.log(person);
//프로퍼티 키 first-name에는 반드시 따옴표를 사용해야 하지만 first_name에는 생략 가능
// '-' 연산자가 있는 표현식이기 때문에
var person = {
first-name: 'Ung-mo', // SyntaxError: Unexpected token -
};
var person = {
[first-name]: 'Ung-mo', // ReferenceError: first is not defined
};
//예약어를 프로퍼티 키로 사용하여도 에러가 발생하지 않는다. 하지만 예상치 못한 에러가 발생할 수 있으므로
//예약어를 프로퍼티 키로 사용하면 안됨!
/* 자바스크립트 예약어
abstract arguments boolean break byte
case catch char class* const
continue debugger default delete do
double else enum* eval export*
extends* false final finally float
for function goto if implements
import* in instanceof int interface
let long native new null
package private protected public return
short static super* switch synchronized
this throw throws transient true
try typeof var void volatile
while with yield
// *는 ES6에서 추가된 예약어
*/
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male',
1: 10
};
console.log(person);
//유효하지 않은 이름이기 때문에 따옴표 쓰고 대괄호([])로 접근
//대괄호로 접근시 문자열로!!!!
console.log(person.first-name); // NaN: undefined-undefined
console.log(person[first-name]); // ReferenceError: first is not defined
console.log(person['first-name']); // 'Ung-mo'
//유효한 이름이기 때문에 따옴표 생략하고 마침표(.)로 접근
console.log(person.gender); // 'male'
console.log(person[gender]); // ReferenceError: gender is not defined
console.log(person['gender']); // 'male'
//유효하지 않은 이름이기 때문에 따옴표 쓰고 대괄호([])로 접근
//대괄호로 접근시 문자열로!!!!
console.log(person['1']); // 10
console.log(person[1]); // 10 : person[1] -> person['1']
console.log(person.1); // SyntaxError
//프로퍼티 이름이 유효한 자바스크립트 이름이 아니거나 예약어인 경우, 프로퍼티 값은 대괄호 표기법 사용
//대괄호 표기법 사용시, 대괄호 내에 들어가는 프로퍼티 이름은 반드시 문자열이어야 한다.
//객체에 존재하지 않는 프로퍼티를 참조하면 undefined
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male',
};
console.log(person.age); // undefined
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male',
};
person['first-name'] = 'Kim';
console.log(person['first-name'] ); // 'Kim'
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male',
};
person.age = 20;
console.log(person.age); // 20
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male',
};
delete person.gender;
console.log(person.gender); // undefined
delete person;
console.log(person); // Object {first-name: 'Ung-mo', last-name: 'Lee'}
for-in문은 객체의 문자열 키를(key)를 순회하기 위한 문법이다. 배열에는 사용하지 않는 것을 권장.
var person = {
'first-name': 'Ung-mo',
'last-name': 'Lee',
gender: 'male'
};
// prop에 객체의 프로퍼티 이름이 반환된다. 단, 순서는 보장되지 않음
for (var prop in person) {
console.log(prop + ': ' + person[prop]);
}
/*
first-name: Ung-mo
last-name: Lee
gender: male
*/
var array = ['one', 'two'];
// index에 배열의 경우 인덱스가 반환됨
for (var index in array) {
console.log(index + ': ' + array[index]);
}
/*
0: one
1: two
*/
const array = [1, 2, 3];
array.name = 'my array';
for (const value of array) {
console.log(value);
}
/*
1
2
3
*/
for (const [index, value] of array.entries()) {
console.log(index, value);
}
/*
0 1
1 2
2 3
*/
for–in 문은 객체의 프로퍼티를 순회하기 위해 사용하고
for–of 문은 배열의 요소를 순회하기 위해 사용한다.
Object type을 객체 타입 또는 참조 타입이라고 함
참조 타입 : 객체의 모든 연산이 실제 값이 아닌 - 참조값으로 처리
원시 타입 : 값이 한 번 정해지면 변경할 수 없음 (immutable)
객체는 프로퍼티 변경, 추가, 삭제가 되므로 변경 가능(mutable)한 값이라 할 수 있음
따라서 객체 타입은 동적으로 변할 수 있으므로 어느 정도 메모리 공간을 확보해야 하는지 예측할 수 없음.
런타입에 메모리 공간을 확보하고 메모리의 힙 영역(Heap Segment)에 저장.
이에 반대로 원시 타입은 값(value)으로 전달, 즉, 복사되어 전달
// Pass-by-reference
var a = [1, 2, 3];
var b = a;
a[0] = 10000
console.log(b);
//b의 결과는 [10000,2, 3]이 됨
//이유 : 값을 복사하여 새로운 메모리에 저장한 것이 아닌 a의 주소 참조
// >>> pass-by-reference
// Pass-by-value
var a = 10;
var b = a;
//b에 10이라는 값 할당, 메모리에 새로운 공간에 10이라는 값 저장
//만약 a에 다른 값을 재할당해도 b에 영향 X
// >>> pass-by-value
멋있읍니다.~