🐊 원시형과 자료형
자바스크립트에서 원시 자료형이 아닌 모든 것은 참조 자료형이다.(Array, Object, function)
const number = 3;
const arr = ['a', 'b', 'c', 'd'];
변수 number
에는 3이라는 원시 자료형 '값'이 할당되고, arr
에는 참조 자료형의 '주소'가 할당된다. 참조 자료형은 실제 데이터가 저장된 주소를 가리킨다. 즉, 참조(reference)가 된다.
원시 자료형은 immutable하지만 참조 자료형은 그렇지 않다. 그렇기 때문에 '주소'를 할당할 수 밖에 없다. 배열에 요소를 추가 및 삭제하고, 객체에 속성을 추가 및 삭제할 수 있다. 이것은 참조 자료형이 immutable하지 않다는 것을 보여준다. (언제든지 데이터가 늘어나고 줄어들 수 있다. = 동적으로 변함) 그렇기 때문에 특별한 저장공간(heap)의 주소를 변수에 할당함으로써 더 잘 관리한다.
const ages = [22, 23, 27];
allowedToDrink = ages;
console.log(allowedToDrink === ages); // true
console.log(allowedToDrink === [22, 23, 27]); // false
const nums1 = [1, 2, 3];
const nums2 = [1, 2, 3];
console.log(nums1 === nums2); // false
[1, 2, 3];
// [1, 2, 3]이라는 데이터가 heap에 저장되지만 변수 할당이 되지 않아 주소는 어디에도 저장되지 않는다.const num1
= [1, 2, 3]; // // [1, 2, 3]이라는 데이터가 heap에 저장되고, 그 주소가 변수num1
에 저장된다.const num2
= [1, 2, 3]; // // [1, 2, 3]이라는 데이터가 heap에 저장되고, 그 주소가 변수num2
에 저장된다.
⇒ 1, 2, 3에서 말하는 주소는 전부 다른 주소이다.
const person = {
son: {
age: 9,
},
};
const boy = person.son;
boy.age = 20;
console.log(person.son.age); // 20
console.log(person.son === boy); // ture
console.log(person.son === { age: 9 }); // false
console.log(person.son === { age: 20 }); // false
🐊 Array
🟢 Array의 element를 다루기
const arr = [];
arr[0];= 1; // [1]
arr[1];= 2; // [1, 2]
arr.push(3); // [1, 2, 3]
arr.pop(); // [1, 2]
🟢 Array method slice()
const arr = ['a', 'b', 'c', 'd'];
arr.slice(1); // ['b', 'c', 'd']
arr.slice(0, 1); // ['a']
arr.slice(0,2); // ['a', 'b']
arr.slice(2,0); // []
arr.slice(2,2); // []
arr.slice(2,20); // ['c', 'd']
arr.slice(3, 0); // []
arr.slice(3, 100); // ['d']
arr.slice(5, 1); // []
arr.slice(0); // ['a', 'b', 'c', 'd']
const arr = ['zero', 'one', 'two', 'three', 'four', 'five'];
function passedByReference(refArr) {
refArr[1] = 'changed in function';
}
passedByReference(arr); // arr[1] = 'changed in function'
const assignedArr = arr;
assignedArr[5] = 'changed in assignedArr';
// arr[5] = 'changed in assignedArr'
const copiedArr = arr.slice();
copiedArr[3] = 'changed in copiedArr';
// arr[3] = 'three'
배열(arr
)을 다른 변수(assignedArr
)에 할당하게 되면 해당 배열의 주소가 공유되기 때문에 변수의 요소를 바꾸면 원본 배열(arr
)도 함께 바뀌게 된다. 반면에, slice() method를 사용하여 변수(copiedArr
)에 할당하면 배열이 복사되어 할당되기 때문에 할당된 배열의 요소를 바꿔도 원본 배열의 요소는 바뀌지 않는다.
const arr = ['a', 'b', 'c', 'd'];
arr.pop(); // 'd'
arr.push('e'); // 4
arr.shift(); // 'a'
arr.unshift('z'); // 4
배열의 요소를 제거하는 pop(), shift() method를 사용하면 제거된 요소를 반환한다. 반면에, 배열의 요소를 추가하는 push(), unshift() method는 배열의 길이를 반환한다. (사용한 후 배열을 확인하기 위해서는 다시 배열을 호출해야 한다!)
🐊 object
let obj = {name:"test",ttt:"NewTest",kim:"kim"};
obj.length; // undefined
Object.keys(obj).length; // 3
object의 길이는 .length를 사용하여 구할 수 없다. 길이를 구하기 위해서는 Object.keys()를 사용하여 key를 배열로 바꾼 후, 배열의 길이를 반환해야 한다.
const person = {name : 'Shin', age : 30, city : 'seoul'}
'name' in person; // true : key 값
'Shin' in person; // false : value 값
person['name'] = 'Kim'; // 'Kim'
person.name; // 'Kim'
person.gender = 'male'; // 'male'
'gender' in person; // true
delete person.gender // true
'gender' in person // false
const currentYear = new Date().getFullYear();
const megalomaniac = {
mastermind: 'James Wood',
henchman: 'Adam West',
birthYear: 1970,
calculateAge: function (currentYear) {
return currentYear - this.birthYear;
},
changeBirthYear: function (newYear) {
this.birthYear = newYear;
},
};
console.log(currentYear);
console.log(megalomaniac.calculateAge(currentYear)); // 2022
megalomaniac.birthYear = 2000;
console.log(megalomaniac.calculateAge(currentYear)); // 52
megalomaniac.changeBirthYear(2010); // 22
console.log(megalomaniac.calculateAge(currentYear)); // 12
method는 '어떤 객체의 속성으로 정의된 함수'를 말한다. method는 항상 '어떤 객체'의 method이다. 따라서 호출될 때마다 어떠한 객체의 method인데, 그 '어떠한 객체'를 묻는 것이 this
이다. this
는 함수의 호출에 따라서 값이 달라지기도 한다.
const obj = {
mastermind: 'Joker',
henchwoman: 'Harley',
relations: ['Anarky', 'Duela Dent', 'Lucy'],
twins: {
'Jared Leto': 'Suicide Squad',
'Joaquin Phoenix': 'Joker',
'Heath Ledger': 'The Dark Knight',
'Jack Nicholson': 'Tim Burton Batman',
},
};
function passedByReference(refObj) {
refObj.henchwoman = 'Adam West';
}
passedByReference(obj);
console.log(obj.henchwoman); // Adam West
const assignedObj = obj;
assignedObj['relations'] = [1, 2, 3];
console.log(obj['relations']); // [1, 2, 3]
const copiedObj = Object.assign({}, obj);
copiedObj.mastermind = 'James Wood';
console.log(obj.mastermind); // Joker
obj.henchwoman = 'Harley';
console.log(copiedObj.henchwoman); // Adam West
delete obj.twins['Jared Leto'];
console.log('Jared Leto' in copiedObj.twins); // false
변수 assignedObj
에 obj를 할당하게 되면 객체가 아닌 주소가 할당된다. 그렇기 때문에 assignedObj
의 property를 바꾸게 되면 obj도 함께 바뀌게 된다. 반면에, assign()을 사용하여 변수 copiedObj
에 할당하게 되면 새로운 객체가 할당되기 때문에 copiedObj
의 property를 바꿔도 obj는 변하지 않는다.
🐊 spread
const spread = [1, 2, 3];
const arr = [0, ...spread, 4];
console.log(arr); // [0, 1, 2, 3, 4]
const fullPre = {
cohort: 7,
duration: 4,
mentor: 'hongsik',
};
const me = {
time: '0156',
status: 'sleepy',
todos: ['coplit', 'koans'],
};
const merged = { ...fullPre, ...me };
console.log(merged);
/*
{cohort: 7,
duration: 4,
mentor: 'hongsik',
time: '0156',
status: 'sleepy',
todos: ['coplit', 'koans'],
}
*/
🟢 spread를 사용하면 배열과 객체를 병합할 수 있다.
function sum(...nums) {
let sum = 0;
for (let i = 0; i < nums.length; i++) {
sum = sum + nums[i];
}
return sum;
}
console.log(sum(1, 2, 3, 4, 5)); // 15
🟢 Rest Parameter는 전달인자의 수가 정해져 있지 않은 경우에도 유용하게 사용할 수 있다.
function getAllParams(required1, required2, ...args) {
return [required1, required2, args];
}
console.log(getAllParams(123)) // [123, undefined, Array(0)]
자바스크립트는 함수 호출 시 전달인자의 순서가 중요하다.(named parameter를 지원하지 않기 때문) Rest Parameter는 전달인자의 일부에만 적용 할 수도 있다.
🐊 구조 분해 할당(Destructing Assignment)
const arr = ['I', 'am', 'inevitable']
const [first, second, third] = arr
console.log(first); // I
console.log(second); // am
console.log(third); // inevitable
const result = []
function foo([first, second, third]) {
result.push(second)
result.push(first)
result.push(third)
}
foo(arr);
console.log(result); // ['am', 'I', 'inevitable']
const array = ['my', 'name', 'is', 'Shin']
const [start, ...rest] = array
console.log(start); // my
console.log(rest); // ['name', 'is', 'Shin']
🟢 rest 문법 이후에는 쉼표가 올 수 없다.const [first, ...middle, last] = arr
🟢 객체의 단축(shorthand) 문법
const name = 'Shin';
const age = 30;
const person = {
name,
age,
level : 3
}
console.log(person); // {name: 'Shin', age: 30, level: 3}
🟢 객체 분해하기
const person = {name : 'Shin', age : 30, level : 3};
const {name} = person;
console.log(name); // 'Shin'
🟢 rest/ spread 문법을 객체 분해에 적용하기
const person = {name : 'Shin', age : 30, level : 3};
const { name, ...args } = person;
console.log(name); // 'Shin'
console.log(args); // {age: 30, level: 3}
const user = {
name: 'shin',
company: {
name: 'GOD',
department: 'Development',
role: {
name: 'Software Engineer'
}
},
age: 30
}
const changedUser = {
...user,
name: 'Lee',
age: 23
}
const overwriteChanges = {
name: 'Lee',
age: 23,
...user
}
const changedDepartment = {
...user,
company: {
...user.company,
department: 'Marketing'
}
}
console.log(changedUser);
{
name: 'Lee',
company: {
name: 'Code States',
department: 'Development',
role: {
name: 'Software Engineer'
}
},
age: 23
}
console.log(overwriteChanges);
{
name: 'Shin',
age: 30
company: {
name: 'Code States',
department: 'Development',
role: {
name: 'Software Engineer'
}
}
}
console.log(changedDepartment);
{
name: 'Shin',
company: {
name: 'Code States',
department: 'Marketing',
role: {
name: 'Software Engineer'
}
},
age: 30
}
'Javascript' 카테고리의 다른 글
고차함수(Higher-order-function) (0) | 2022.05.27 |
---|---|
DOM (0) | 2022.05.21 |
Spread & Rest (0) | 2022.05.13 |
클로저(closure) (0) | 2022.05.13 |
스코프(Scope) (0) | 2022.05.12 |