객체(Object)
let a;
변할 수 있는 데이터를 만든다, 이 데이터의 식별자는 a로 한다.
let a; // 변수선언
a = 'abc'; // 데이터 할당
let = 'abc' // 한문장으로 표현
let a = 'abc';
a = 'abcdef';
기본형 데이터는 모두 불변값 이지만, 참조형의 경우 기본적인 성질은 가변값이지만,
설정에 따라 변경 불가능한 경우도 있다.(Object.defineProperty, Object.freeze 등)
let obj1 = {
a: 1,
b: 'bbb'
};
var obj1 = {
a: 1,
b: 'bbb'
};
obj1.a = 2;
var obj1 = {
x: 3,
arr: [3,4,5]
};
let obj = {
x: 3,
arr: [ 3, 4, 5]
};
obj.arr = 'str';
let user = {
name: 'Seongil',
gender: 'male'
};
const changeName = (user, newName) => {
let newUser = user;
newUser.name = newName;
return newUser;
}
const user2 = changeName(user, 'modolee');
if (user !== user2) {
console.log('유저 정보가 변경되었습니다.');
}
console.log(user.name, user2.name); // modolee modolee
console.log(user === user2); // true
우리가 원하던것과 전혀 다르게 동작한다.
이유는 object type의 특성상 주소값을 복사하게 되서, user2도 기존의 user의 name property를
가리키게 되므로, user의 네임까지 변경시켜버린다.
let user = {
name: 'Seongil',
gender: 'male'
};
const changeName = (user, newName) => {
return {
name: newName,
gender: user.gender
};
}
const user2 = changeName(user, 'modolee');
if (user !== user2) {
console.log('유저 정보가 변경되었습니다.'); // 유저 정보가 변경되었습니다.
}
console.log(user.name, user2.name); // Seongil modolee
console.log(user === user2); // false
위 코드처럼 deep copy를 통해 immunitable을 보장 할 수있다.
undefined는 사용자가 지정할 수 도있지만, JS엔진이 자동부여 할 때 도있다.
엔진이 자동으로 부여하는 경우는 다음과 같다
값을 대입하지 않은 변수, 즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근
객체 내부의 존재하지 않는 프로퍼티에 접근하려할때
return 문이 없거나 호출되지 않는 함수의 실행결과
var a;
console.log(a); //(1) undefined 값을 대입하지 않은 변수에 접근
var obj = { a:1 };
console.log(obj.b); // (2) 존재하지 않는 props 에 접근
var func = function() {};
var c = func();
console.log(c); //(3) 명시적인 반환값이 없는 함수에 반환값
주의 할점은 '비어있는 요소' 와 'undefined를 할당한 요소'는 출력결과가 다른걸 유의 해야한다.
var arr1 = [undefined, 1];
var arr2 = [];
arr[2] = 1;
arr1.forEach(function (v,i) {console.log(v,i)}); // undefined 0 / 1 1
arr2.forEach(function (v,i) {console.log(v,i)}); // 1 1
// 엔진에 의해 할당된 undefined 같은경우, 아예 없는 값으로 취급이된다.
// 메서드의 순환 대상에서 제외 된다는 것이다.