Muscardinus
JS Types 본문
JavaScript의 7가지 Types
- Number
- Boolean
- String
- Undefined
- Null
- Symbol
- Object
참고: Undefined 와 Null의 차이
Undefined Vs Null Undefined is the absence of definition, it has yet to be defined, and nulll is the absence of value, there is no value there |
이 7가지의 Types 중 Object는 가장 범용적인 자료형이라고 생각해도 좋다. 거의 모든 것이 Object라고 해도 과언이 아니다.
• Booleans can be objects (if defined with the new keyword)
• Numbers can be objects (if defined with the new keyword)
• Strings can be objects (if defined with the new keyword)
• Dates are always objects
• Maths are always objects
• Regular expressions are always objects • Arrays are always objects
• FuncBons are always objects
• Objects are always objects
참고: [Udemy: Javascript The Advanced Concept]
이 7가지 Type들은 작동원리에 따라서 Primitive 와 Unprimitive로 구분 할 수 있다.
Primitive (Passed By Value) - 원시적
Primitive한 값 들은 해석 그대로 원시적으로 작동한다. 해당 값들이 Primitive 한 Type 들이다.
- Number
- Boolean
- String
- Null
- Undefined
- Symbol
Primitives는 단순하게 생각하면, 값의 "형태"가 같다면, 서로 같은 값이다. 값의 "형태"가 다르다면, 서로 다른 값이다.
const a = 5;
const b = 5;
a === b //true
위 코드를 볼 수 있듯이, 같의 "형태"가 같기에 같은 값이다.
참고로,
원시값들은 값 자체로 부르기 때문에 Passed By Value라고 한다.
const a = 5;
let b = a;
b++;
a; // 5
b; // 6
위 코드를 보면 알 수 있듯이, b는 a의 값 자체를 복사해오는 것이다, b를 변화시켜도 a에 영향을 주지 않는다.
Nonprimitive (Passed By Reference) - 비원시적
- Objects
Objects만이 Nonprimitive하다. 이것이 무엇을 뜻하느냐? Object를 가르키는 변수는 그 값 자체를 복사하지 않고, 그 Object 자체의 메모리 주소값을 가지게 될 것이다. 예시를 보자,
// objects are passed by reference
let obj = {};
name: "object 1";
let newObj = obj; // points to same place in memory as obj
newObj.name = "newObj"; // modifies the memory
// Since both point to the same place...
console.log(obj); // {name: newObj}
console.log(newObj); // {name: newObj}
// They are both modified.
let arr = [1, 2, 3];
let newArr = arr;
newArr.push(4);
console.log(arr); // [1, 2, 3, 4]
console.log(newArr); // [1, 2, 3, 4]
위 코드를 보면 알 수 있듯이, obj1와 newObj는 같은 Object의 주소값을 바라보고 있다. 따라서 newObj의 name 속성을 변화 시키면 obj 또한 바뀌게 될 것이다.
우리는 이것을 Passed By Reference라고 한다.
만약에 위의 Primitive들과 같이 값 자체만을 복사하고 싶다면, 우리는 객체에서 사용하는 Object.assign()을 사용하거나 혹은 Spread Operator를 사용하면 된다.
const obj = {
name: "Muscardinus"
};
const newObj = {...obj};
const newObj2 = Object.assign({}, obj);
obj === newObj // false
obj === newObj2 // false
좋은 방법이라고 생각이 들 것이다. 하지만, 이것은 완전한 복사라고 할 수 없다. 아래 코드를 보자.
const originalObj = {
nested: {
nestedKey: "nestedValue",
},
key: "value",
};
// originalObj points to location 1 in memory
const assignObj = originalObj;
// assignObj will point to 1 in memory
const shallowObj = { ...originalObj };
// shallowObj points to a new location 2, but references location 1 for the nested
assignObj === originalObj; // true
shallowObj === originalObj; // false
shallowObj.nested === originalObj.nested; // true ?????
위 코드의 주석에도 달았듯이, originalObj가 1번 주소록에 저장되면 shallowObj는 2번 주소록을 가르키지만, 속성의 nesting된 값은(nested) 그대로 1번 주소록을 가르키게 된다.
이를 해결하는 방법 중 한가지가 바로 JSON.parse와 JSON.stringify를 이용하는 방법이다.
const originalObj = {
nested: {
nestedKey: "nestedValue",
},
key: "value",
};
// originalObj points to location 1 in memory
const assignObj = originalObj;
// assignObj will point to 1 in memory
const shallowObj = { ...originalObj };
// shallowObj points to a new location 2, but references location 1 for the nested object
const deepObj = JSON.parse(JSON.stringify(originalObj));
// deepObj clones all parts of the object to a new memory address
'FrontEnd > JavaScript Basics' 카테고리의 다른 글
Static Vs Dynamic Typed (1) | 2020.12.15 |
---|---|
Type Coercion (0) | 2020.12.15 |
Error Handling (0) | 2020.12.14 |
Modules in JS (1) | 2020.12.14 |
Call Stack And Memory Heap (0) | 2020.11.30 |