HelloCodeit
- 테스트 디렉터리 작성
- chrome으로 index.html을 열고 개발자 도구에서 console에서 “Hello Codeit!”을 확인 가능
- 세미콜론
- JS에서는 한줄에 하나의 명령이면 자동으로 ;을 붙인다.
- 한줄에 여러 명령이면 ;으로 명령 구분이 필요하다.
- 세미콜론으로 명령을 구분해주는 게 좋다.
- 주석 처리(comment)
자료형
- number
- string
- ‘’, “”,`` 모두 가능
- +로 concatenate 가능
- escaping은 \으로 가능
- backtick(`)으로 감싸서 내부 특수문자(”, ‘)을 사용하는게 가독성이 더 좋음
- +연산에서 피연산자가 하나라도 문자열이면 나머지 모두 문자열로 바꿈(auto cast)
- boolean
- 값이 같은 지는 ==, 다른 지는 !=
- true, false를 사용
- and 연산은 &&
- or 연산은 ||
- not 연산은 !
- function
- typeof 연산자(function이 아니라 연산자임)
- 뒤에 오는 변수의 type명을 string으로 반환함
let t = true;
let f1 = '';
let f2 = 0;
let nan = NaN; // NaN도 type은 number임
console.log(typeof (8 - 3)); // number
console.log(Number(t)); // true를 Number로 변환하면 1이 나옴
console.log(Boolean(f1)); // false, empty string은 false
console.log(Boolean(f2)); // false, zero number은 false
console.log(Boolean(nan)); // false, NaN은 false
- 형 변환(Type conversion)
- String, Number Boolean 쓰면 됨
console.log(Number('10') + Number('5')); // 15
- 자동 형변환
// 요약하면, 연산은 모두 숫자로 자동 형변환하여 계산한다.
// 다만, +은 둘 중 하나라도 문자열이 있으면 문자열로 형변환하여 계산한다.
console.log(4 + '2'); // 42, 문자열 연결이 숫자 더하기 보다 더 우선순위 있다.
console.log('4' * 1); // 4
console.log(4 + 2);
console.log(4 - true);
console.log(4 * false);
console.log(4 / '2');
console.log('4' ** true);
console.log(4 % 'two'); // NaN, NaN은 어떤 값과 연산해도 NaN
console.log(2 < '3'); // 2 < 3, true
console.log(2 > true); // 2 > 1, true
console.log('2' <= false); // 2 <= 0, false
console.log('two' >= 1); // false, NaN이 떠서 비교불가능하면 false를 반환
console.log(1 === '1'); // false, type이 달라서 false
console.log(1 == '1'); // true, 숫자로 형변환하고 값비교
console.log(1 === true); // false, type이 달라서 false
console.log(1 == true); // true, 숫자로 형변환하고 값비교
- +을 사용해서 String→Number 형변환 가능
let a = +'10'; console.log(typeof a); console.log(a);
추상화
- 뽑을 추, 코끼리 상
- 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용을 추상이라 한다.
- 개발에서는 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것
- 방향
- 목적을 명확히
- 불필요한 것들은 숨기기
- 핵심만 드러내기
변수선언
let espressoPrice; // create a variable
espressoPrice = 3000; // assignment
let espressoPrice = 3000;
- 반드시 지켜야하는 작명 가이드
- [a-zA-Z], _, $로 시작해야한다. 두번 째 글자부터는 숫자도 가능
- 대소문자가 구분됨
- reserved keyword는 사용 불가
- 지키면 좋은 작명 가이드
- 의미 없는 변수명을 쓰지 않는다.
- 너무 추상적인 이름을 쓰지 않는다.
- e.g. let name;
- 다양한 이름이 존재하기 때문
- 모든 변수는 camelCase로 작성한다.
함수선언
- function keyword를 사용한다
function funcName(param1, param2) { cmd1; cmd2; };
// 보통은 { 이후 줄바꿈 함
function funcName(param1, param2) {
cmd1;
cmd2;
};
// 함수호출
funcName()
// 문자열이 존재하면 모두 문자열을 auto cast
function teraToGiga(x) {
console.log(x + 'TB는')
console.log(x * 1024 + 'GB 입니다.')
};
템플릿 문자열
let year = 2018;
let month = 3;
let day = 11;
function getTwice(number) {
return 2 * number
}
// backtick으로 str을 나타내고, ${variable}로 template string 가능
console.log(`생년월일은 ${year}년 ${month}월 ${day}일 입니다.`);
console.log(`${myNumber}의 두 배는 ${getTwice(myNumber)}입니다.`);
null과 undefined
Default value를 갖는 parameter
// default value를 갖는 parameter는 뒤에 위치하게 작성한다.
function introduce(name, age, nationality = '한국') {
console.log(`제 이름은 ${name}입니다.`)
console.log(`나이는 ${age}살 입니다.`)
console.log(`국적은 ${nationality}입니다.`)
}
변수의 scope
// Scope: 범위, 영역
let y = 4;
function myFunction() { // 블록문 (block statement)
let x = 3; // 블록문 내에 선언한 변수를 지역 변수(Local variable)이라 한다.
console.log(x); // 로컬 변수는 블록문 안에서만 유효하다.
console.log(y); // 글로벌 변수는 블록문 밖에서 정의했어도 블록문 안에서 사용 가능
}
myFunction();
console.log(x); // ReferenceError: x is not defined
console.log(y); // 실행안됨, 위의 error로
// Scope: 범위, 영역
let x = 5;
function myFunction() { // 블록문 (block statement)
let x = 3; // 블록문 내에 선언한 변수를 지역 변수(Local variable)이라 한다.
console.log(x); // 블록문안에서 변수의 값을 찾는 것은 로컬 변수부터 찾아서 3을 출력
}
myFunction();
console.log(x); // 글로벌 변수 x를 출력, 5
상수
if statement
/*
if (조건1) {
동작1
} else if (조건2) {
동작2
} else {
동작3
}
*/
let temperature = 0;
if (temperature <= 0) {
console.log('물이 업니다.')
}
switch statement
/*
switch (비교할_값) {
case 조건값_1: // ===로 비교함, 즉 값과 type 둘 다 같아야 함
동작부분1;
break;
case 조건값_2:
동작부분2;
break;
default: // 생략가능
동작부분3;
}
*/
for loop statement
/*
for (초기화부분; 조건부분; 추가동작부분) {
동작부분
}
*/
// 초기화부분은 loop 시작시 한 번 실행, 생략가능하지만 세미콜론은 생략 불가
// 조건부분이 true이면 동작부분을 시행
// 동작부분 이후 추가동작부분이 시행됨, 생략가능하고 이부분은 동작부분에서 해결해도됨
// 초기화부분에서 생성한 변수는 for statement의 로컬 변수
// 예시
for (let i=1; i <= 10; i++) {
console.log('코드잇 최고!')
}
console.log(i) // ReferenceError: i is not defined.
// 만약 i를 for loop 이전에 let i = 3; 이 있으면 여기서 3을 출력함
// 코드잇 최고!을 10번 출력하는 것에는 변함없음
while statement
/*
while (조건부분) {
동작부분
}
*/
// 초기화부분이 따로 없기 떄문에 while문 이전에 global 초기화변수 필요
// 추가동작부분이 따로 없이 때문에 동작부분에서 보통 해결
// for문은 초기화부분에서 사용한 변수가 로컬변수다 보니까 statement가 끝나면 사용 안함
// while문은 global변수를 사용해서 statement가 끝나고도 사용
break와 continue
// break는 switch, for, while statement를 탈출
// continue는 이하 명령을 실행하지 않고 다음 단계로 이동
객체(object)와 속성(property)
// object의 생성
{
brandName: '코드잇',
bornYear: 2017,
isVeryNice: true,
worstCourse: null
}
// 각 key와 value가 존재하고 (key, value) 쌍을 property라 한다.
// key를 property name, value를 property value라 한다.
// property name은 string 타입이다. '을 생략해도 JavaScript가 알아서 문자열로 사용
// property name작성 시 '을 사용하지 않는다면 주의사항
// 첫 글자는 반드시 문자, 밑줄(_), $중 하나로 시작
// 띄어쓰기 사용 금지
// 하이픈(-) 금지
// '을 사용한다면 위의 문제 없이 사용 가능
// property value는 모든 자료형이 가능, 심지어 object도 가능
// object를 typeof 연산자의 결과를 보면 object가 나온다.
객체 데이터 접근하기
// 점 표기법
// objectName.propertyName
console.log(objectSample.bornYear);
// '를 생략한 propertyName에 접근이 안되는 단점을 갖는다.
// 대괄호 표기법
// objectName['propertyName']
let propertyName = 'born' + ' Year';
console.log(objectSample[propertyName]);
// 장점은 propertyName을 가리키는 변수를 사용할 수 있고, 유연한 propertyName 사용가능
// object안의 object 접근은 위의 두 가지를 반복
console.log(codeit.bestCourse.title);
console.log(codeit['bestCourse']['title']);
console.log(codeit.bestCourse['title']);
// propertyName이 없는 경우에 접근하면
// undefined값을 반환한다. not error raised
객체 다루기
// codeit이 object라 했을 때
// property value 변경 혹은 property 추가
codeit.name = 'codeit';
// property 삭제
delete codeit.worstCourse;
// property name으로 property 존재 확인
'propertyName' in codeit;
// 없는 property name으로 조회 시 undefined가 나오는 걸 통해
// property name으로 object안에 존재하는 지 확인하려고 할 때
// 실제로 property name이 object에 없었을 경우
codeit.propertyName in codeit; // false
codeit.propertyName !== undefined; // false
// property name으로 object에 존재하지만
// property value가 undefined였다면(이러면 안되지만)
codeit.propertyName in codeit; // true
codeit.propertyName !== undefined; // false
// 따라서, property name의 object 내 존재 확인은 'in'을 권장한다.
메소드(method)
/*
property value에는 function도 들어갈 수 있다.
이러한 function을 method라 한다.
*/
let greetings = {
sayHello: function(name) {
console.log(`Hello ${name}!`);
},
sayHi: function() {
console.log('Hi!');
}
}
let name = 'codeit';
greetings.sayHello(name);
greetings['sayHello'](name);
// 사실 console.log()도 console이라는 object에 존재하는 method를 실행한 셈
/*
왜 function을 그냥 쓰면 되지 왜 메소드를 사용하는 것인가?
어떤 object냐에 따라 함수 이름이 중복됐으나 다른 기능을 적용할 수 있기 때문
좀 더 object에 집중해서 함수 동작을 정의할 수 있다.
*/
let rectAngle = {
width: 30,
height: 50,
getArea: function () {
return rectAngle.width * rectAngle.height
}
}
let triAngle = {
width: 15,
height: 40,
getArea: function() {
return triAngle.width * triAngle.height / 2;
}
}
for...in 반복문
/*
object의 property에 대해 for문
for (변수 in 객체) {
동작부분
}
변수는 property name이 온다.
*/
let codeit = {
name: '코드잇',
bornYear: 2017,
isVeryNice: true,
worstCourse: null,
bestCourse: '자바스크립트 프로그래밍 기초'
}
for (let k in codeit) {
console.log(k);
console.log(codeit[k]);
}
/*
주의사항
-property name을 숫자를 사용하면 object 생성 후에는 어쨌든 문자열로 형변환되어 사용됨
-따라서 property를 가져와 사용할 때는 문자열로 가져와야한다.
-for..in을 쓸 때, property가 나올 순서에 대해
-정수형 property name을 사용했다면, 해당 정수형부터 오름차순해서 나온다.
-이외 나머지 자료형에 대해서는 기입한 순서대로 나온다.
*/
Date객체
/*
console객체처럼 JavaScript의 내장 객체(Standard built-in objects)가 존재
그 중 Date 객체에 대해 알아보자.
*/
// Date객체 생성
let myDate = new Date();
console.log(myDate); // 객체가 생성된 datetime이 출력됨
// Date객체 생성 with UTC plus 1000 milliseconds
let myDate1 = new Date(1000); // 1970년 1월 1일 00:00:00 UTC + 1초
console.log(myDate1)
// Date객체 생성 YYYY-MM-DD
let myDate2 = new Date('2017-01-01');
console.log(myDate2)
// Date객체 생성 YYYY-MM-DDThh:mm:ss
let myDate3 = new Date('2017-01-01T23:59:59')
console.log(myDate3)
// Date객체 생성 with multiple arguments, YYYY, MM, DD, hh, mm, ss, ms
// MM(month)는 시작이 0부터임
// required : YYYY, MM
// 나머지 생략하면 DD는 1, 그 외는 0으로 입력됨
let myDate4 = new Date(2017, 0, 1, 23, 59, 59);
console.log(myDate4);
// Date객체로부터 time stamp 가져오기(1970-01-01T00:00:00 UTC부터 흐른 milliseconds)
console.log(myDate4.getTime());
// Date객체로부터 여러 정보 가져오기
// 주의할 점은 Day는 요일을 가리키며, 0부터 시작함
console.log(myDate4.getFullYear()); // 2017
console.log(myDate4.getMonth()); // 0
console.log(myDate4.getDate()); // 1
console.log(myDate4.getDay()); // 0, 즉 일요일
console.log(myDate4.getHours()); // 23
console.log(myDate4.getMinutes()); // 59
console.log(myDate4.getSeconds()); // 59
console.log(myDate4.getMilliseconds()); // 0
// Date객체 수정하기
let myDate = new Date(2017, 4, 18, 19, 11, 16);
myDate.setFullYear(year, [month], [date])
myDate.setMonth(month, [date])
myDate.setDate(date);
myDate.setHours(hour, [min], [sec], [ms]);
myDate.setMinutes(min, [sec], [ms]);
myDate.setSeconds(sec, [ms]);
myDate.setMilliseconds(ms);
myDate.setTime(milliseconds); // 1970년 1월 1일 00:00:00 UTC 기준 2 milliseconds 지난 datetime
// Date객체로부터 Locale에 맞는 date/time 가져오기
myDate.toLocaleDateString(); // 사용자 브라우저 locale에 맞는 date를 가져옴
myDate.toLocaleTimeString(); // 사용자 브라우저 locale에 맞는 time를 가져옴
myDate.toLocaleString(); // 사용자 브라우저 locale에 맞는 datetime을 가져옴
// 똑똑한 Date객체, 범위를 벗어나는 값을 설정하면 날짜 수정
let myDate = new Date(1988, 0, 32); // 1988년 1월 32일은 없음, 1988년 2월 1일로 설정됨
// 호출한 순간의 datetime이 필요하다면 Date.now() 사용
Date.now(); // 호출한 시점의 datetime이 나옴
// Date객체의 형변환
let myDate = new Date(2017, 4, 18);
console.log(typeof myDate); // object
console.log(String(myDate)); // Thu May 18 2017 00:00:00 GMT+0900 (Korean Standard Time)
console.log(Number(myDate)); // 1495033200000
console.log(myDate.getTime() === Number(myDate)); true
console.log(Boolean(myDate)); // true
// Date객체끼리의 사칙연산
let myDate1 = new Date(2017, 4, 18);
let myDate2 = new Date(2017, 4, 19);
let timeDiff = myDate2 - myDate1;
console.log(timeDiff); // 86400000 (ms)
console.log(timeDiff / 1000); // 86400 (sec)
console.log(timeDiff / 1000 / 60) // 1440 (min)
console.log(timeDiff / 1000 / 60 / 60) // 24 (hour)
console.log(timeDiff / 1000 / 60 / 60 / 24) // 1 (date)
배열
// 배열의 생성
let courseRanking = [
'자바스크립트 프로그래밍 기초',
'Git으로 배우는 버전 관리',
'컴퓨터 개론'
]
// 배열의 element에는 자료형 제한이 없다.
// index로 가져오기(indexing)
// 0부터 시작
console.log(courseRanking[0]); // 자바스크립트 프로그래밍 기초
// 순서가 있는 경우 배열 사용
// for..in 문 사용 시, 변수는 배열의 index를 가리킨다.
let dataType = ['number', 'string', 'boolean', 'null', 'undefined', 'object'];
for (let idx in dataType) { // idx는 0, 1, 2, ..., 5
console.log(dataType[idx]);
}
// 배열도 object type
console.log(typeof dataType); // object
배열의 원소 추가 및 수정
let dataType = ['number', 'string', 'boolean', 'null', 'undefined', 'object'];
// 배열에 element 추가 혹은 수정
dataType[0] = 'numeric'; // 수정
dataType[6] = 'etc'; // 추가
dataType[10] = 'temp'; // 이 경우 index 7, 8, 9에는 undefined가 들어감
console.log(dataType);
/*
[
'numeric',
'string',
'boolean',
'null',
'undefined',
'object',
'etc',
<3 empty items>,
'temp'
]
*/
배열의 메소드-length
let dataType = ['number', 'string', 'boolean', 'null', 'undefined', 'object'];
console.log(dataType.length); // 6
console.log(dataType['length']); // 6
console.log(dataType[dataType.length - 1]); // last element, 'object'
배열의 메소드-splice
// delete를 이용한 element 삭제
// 이 경우 element value 자체는 없어지지만, 배열에 해당 index 위치에 undefined가 남음
delete dataType[10];
// splice를 이용한 element 삭제
dataType.splice($startIndex, $deleteCount);
// index=1부터 1개만 삭제하려면
dataType.splice(1, 1);
// index=1부터 이후 전체를 삭제하려면
dataType.splice(1);
// index=1부터 1개를 삭제하고 그 자리에 n개의 element를 추가하기
dataType.splice(1, 1, 'added1', 'added2');
// index=1자리에 삭제는 하지말고 element 추가하기
dataType.splice(1, 0, 'added3');
// index=2자리에 원소를 바꾸기(삭제하고 추가하는)
dataType.splice(2, 1, 'added4');
배열의 메소드-shift, pop, unshift, push
let memebers = ['쿤갈레', 'Zerrad66', '우리생각해써', '흙토끼', 'End Miracle'];
console.log(memebers);
// 배열의 첫 요소 삭제
members.shift();
console.log(members);
// 배열의 마지막 요소 삭제
members.pop();
console.log(members);
// 배열의 첫 요소로 값 추가
members.unshift('NiceCodeit');
console.log(members);
// 배열의 마지막 요소로 값 추가
members.push('HiCodeit');
console.log(members);
/*
배열의 양 끝부분을 다루는 경우는 splice보다 위의 메소드를 사용하는게 간결하게 가능
*/
배열에서 value로 index찾기-indexOf, lastIndexOf
let brands = ['Google', 'Kakao', 'Naver', 'Kakao'];
/*
indexOf
- 배열에 value가 존재하면 first index를 반환
- 배열에 value가 없으면 -1을 반환
lastIndexOf
- 배열이 value가 존재하면 last index를 반환
- 배열에 value가 없으면 -1을 반환
*/
console.log(brands.indexOf('Kakao')); // 1
console.log(brands.indexOf('Daum')); // -1
console.log(brands.lastIndexOf('Kakao')); // 3
console.log(brands.lastIndexOf('Daum')); // -1
배열에 value의 존재성-inclues
let brands = ['Google', 'Kakao', 'Naver', 'Kakao'];
console.log(brands.includes('Kakao')); // true
console.log(brands.includes('Daum')); // false
배열 뒤집기-reverse
let brands = ['Google', 'Kakao', 'Naver', 'Kakao'];
console.log(brands); // **["Google", "Kakao", "Naver", "Kakao"]**
brands.reverse();
console.log(brands); // ["Kakao", "Naver", "Kakao", "Google"]
배열의 메소드 레퍼런스
Array - JavaScript | MDN (mozilla.org)
배열의 value로 loop 돌기 - for..of
/*
for (변수 of 배열) { // 변수는 배열의 value가 나옴
동작부분
}
*/
let influencer = ['a', 'b', 'c', 'd'];
for (let element of influencer) {
console.log(element);
}
// for..in문은 배열에 작성하지 않는 것을 권장
// 이는 동작부분에서 배열의 property를 수정할 가능성이 존재하기 때문
// for..in은 객체에 사용할 것을 권장
// for..of를 배열에 사용하기
다차원 배열
let twoDimensional = [[1, 2], [3, 4, 5], ['a']]; // 꼭 element의 길이가 같을 필요 없음
console.log(twoDimensional[0][1]);
다양한 숫자표기법
// 지수표기법
console.log(25e5 === 2500000);
console.log(-6.1e3 === -6100);
console.log(16e-3 === 0.016);
console.log(-9.1e-3 === -0.0091);
// 16진법
let hex1 = 0xff; // 16진법(Hexademical의 x를 따와서 쓴 것)
let hex2 = 0xFF; // 대소문사 구분 없음
// 8진법
let octal = 0o377;
// 2진법
let binary = 0b11111111;
console.log(hex1); // 255
console.log(hex2); // 255
console.log(octal); // 255
console.log(binary); // 255
숫자 메소드
// JavaScript에서 숫자도 객체
// toFixed
// 출력값은 string임, 따라서 숫자로 사용하려면 Number로 casting해줘야함
// toFixed(0~100), 입력한 자리수 까지 보여줌, 그 이하는 반올림
let myNumber = 1.3591;
console.log(myNumber.toFixed(3)); // 1.359
// 입력한 자리수가 실제 숫자의 자리수보다 크면, 초과분에 0을 채워넣음
console.log(myNumber.toFixed(5)); // 1.35910
// toString
// 입력한 값의 진법으로 바꾸고, String type결과를 반환한다.
// toString(2~36)
let myNumber1 = 255;
console.log(myNumber1.toString(2)); // 11111111
console.log(255..toString(8)); // 377
console.log((255).toString(8)); // 377
// 정수에 바로 .을 쓰면 property찾는지, 소수점 표기인지 헷갈려함
// 이 경우, .을 두 번 쓰면 된다. 혹은 ()로 한번 감싸면 된다.
Math객체
// 절댓값
console.log(Math.abs(-10)); // 10
// 최댓값
console.log(Math.max(2, -1, 4, 5, 0)); // 5
// 최솟값
console.log(Math.min(2, -1, 4, 5, 0)); // -1
// 거듭제곱
console.log(Math.pow(2, 3)); // 8
// 제곱근
console.log(Math.sqrt(26)); // 5.0990195135927845
// 반올림
console.log(Math.round(2.49)); // 2
// 버림과 올림
console.log(Math.floor(2.9)); // 2
console.log(Math.ceil(2.1)); // 3
// [0,1) random
console.log(Math.random());
소수점 오류
let sum = 0.1 + 0.2;
console.log(sum); // 0.300000000000004?
// 필요한 자리수만큼 반올림하기
console.log(Number(sum.toFixed(1)));
console.log(+sum.toFixed(1));
console.log(Math.round(sum * 10) / 10);
문자열 메소드
let myString = 'Hi Codeit';
// 문자열 길이
console.log(myString.length); // 9
// 요소 접근
console.log(myString[3]); // C
console.log(myString.charAt(3)); // C
// 요소 탐색
console.log(myString.indexOf('i')); // 1
console.log(myString.lastIndexOf('i')); // 7
console.log(myString.indexOf('z')); // -1
// 대소문자 변환
console.log(myString.toUpperCase()); // HI CODEIT
console.log(myString.toLowerCase()); // hi codeit
// 양 끝 공백 제거
console.log(myString.trim()); // Hi Codeit
// 부분 문자열 접근 slice(start, [end(not inclusive)])
// 두번째 인자가 개수가 아니라 endIndex를 넣어야함!!!
console.log(myString.slice(0, 2)); // 'Hi'
console.log(myString.slice(3)); // Codeit
console.log(myString.slice()); // Hi Codeit
문자열과 배열의 차이점은?
// 배열은 mutable
// 문자열은 immutable
let myString = 'Codeit';
myString[0] = 'B'; // error가 발생 안함! 그렇다고 myString의 첫 character가 바뀐 것도 아님
console.log(myString); // 'Codeit'
기본형과 참조형
/*
Number, String, Boolean, null, undefined는 기본형(Primitive type)
Object는 참조형(Reference type)
*/
// 기본형에 대한 예시
let x = 3;
let y = x;
console.log(x); // 3
console.log(y); // 3
y = 5;
console.log(x); // 3
console.log(y); // 5
// 참조형에 대한 예시
let x = {'name': 'Codeit'}; // x는 우측 객체의 주소를 가리킴
let y = x; // y는 x가 가진 주소를 가리킴, 따라서 x, y 모두 주소를 가리킴
console.log(x); // {'name': 'Codeit'}
console.log(y); // {'name': 'Codeit'}
y.birth = 2017;
console.log(x); // {'name': 'Codeit', 'birth':2017}
console.log(y); // {'name': 'Codeit', 'birth':2017}
// 배열도 객체니까 참조형
// 우측이 기본형인지 참조형인지가 중요
// 예시
let x = {
numbers: [1, 2, 3, 4],
title: 'Codeit',
};
let y = x.numbers;
let z = x.title;
x.numbers.unshift(5);
x.title = 'Hello';
console.log(y); // [5, 1, 2, 3, 4]
console.log(z); // 'Codeit'
참조형 복사하기
// 참조형을 복사하기(Reference type copy)
// 배열
let numbers1 = [1, 2, 3];
let numbers2 = numbers1; // 참조형
let numbers3 = numbers1.slice();
// 객체
let course1 = {
'title': '파이썬 프로그래밍 기초',
'language': 'Python',
'prerequisites': [101, 102]
}
let course2 = Object.assign({}, course1);
course2.title = '알고리즘의 정석';
course2.prerequisites.push(103);
console.log(course1);
console.log(course2);
/*
{
title: '파이썬 프로그래밍 기초',
language: 'Python',
prerequisites: [ 101, 102, 103 ] << 원하지 않은 변경,
}
{
title: '알고리즘의 정석',
language: 'Python',
prerequisites: [ 101, 102, 103 ]
}
*/
// 따라서 아래의 함수를 만들어 사용하자.
function cloneObject(object) {
if (object === null || typeof object !== 'object') {
return object
}
let temp;
if (Array.isArray(object)) {
temp = [];
} else {
temp = {};
}
for (let key of Object.keys(object)) {
temp[key] = cloneObject(object[key])
}
return temp;
}
const, 변수와 상수 사이
// let과 const의 차이는 "재할당" 가능 여부
// const로 변수 선언을 함으로서 재할당이 이후에 없음을 보여주는게
// 유지보수 측면에서 좋다. 따라서, 재할당이 안될 const로 최대한 선언해주는 것이 좋다.
// const로 선언하여도 객체의 주소를 바라본다면(참조형), 객체를 수정하는 것은 가능
// 이는 모든 언어에서도 권장함, 최대한 재할당없게 const쓰고, 재할당이 필요하면 let 사용
const x = {'name': 'Codeit'};
x.birth = 2017; // x가 가리키는 참조 주솟값은 유지되니까, 가능함