프로그래밍은 변수를 통해 값을 저장하고 참조하며 연산자로 값을 연산, 평가하고 조건문과 반복문에 의한 흐름제어로 데이터의 흐름을 제어하고 함수로 재사용이 가능한 구문의 집합을 만들며 객체, 배열 등으로 자료를 구조화하는 것이다.
이전 작성 자료 참고
변수(Variable)는 프로그램에서 사용되는 데이터를 일정 기간 동안 기억하여 필요한 때에 다시 사용하기 위해 데이터에 고유의 이름인 식별자(identifier)를 명시한 것이다. 변수에 명시한 고유한 식별자를 변수명이라 하고 변수로 참조할 수 있는 데이터를 변수값이라 한다.
변수는 값의 위치(주소)를 기억하는 저장소이다. 값의 위치란 값이 위치하고 있는 메모리 상의 주소(address)를 의미한다. 즉, 변수란 값이 위치하고 있는 메모리 주소(Memory address)에 접근하기 위해 사람이 이해할 수 있는 언어로 명명한 식별자이다.
자바스크립트는 동적 타입(Dynamic/Weak Type) 언어이다. 변수의 타입 지정(Type annotation)없이 값이 할당되는 과정에서 자동으로 변수의 타입(Type Inference)이 결정된다. 즉, 변수는 고정된 타입이 없다. 따라서 같은 변수에 여러 타입의 값을 자유롭게 할당할 수 있다.
- 변수는 중복 선언이 가능하다.
- 같은 변수에 여러 타입의 값을 할당할 수 있다. (동적 타이핑)
const
타입은 상수, 바뀌지 않는 변수를 생성할 때 사용한다. 반면에 let
은 변할 수 있는 변수를 생성할 때 사용한다. let
변수 값을 변경하고자 할 때 let을 다시 써서 정의할 수 없고 let 변수를 보호할 수 있다. (재선언 실수 방지)
const
, let
변수 타입은 업데이트를 통해 반영된 것이며 과거에는 var
변수 타입을 사용했었다. 하지만 var
변수는 변수 업데이트에 대한 보호를 받지 못하기 때문에 사용하지 않는 걸 권장한다.
주로 const가 사용되며 가끔 변수에 변화를 주고자 할 때 let을 씀
변수가 동작할 수 있는 유효 범위(Scope)는 해당 변수가 있는 블럭 내에 있어야 한다.
switch문은 switch-case-break-default 이렇게 사슬로 기억하면 좋다.
참고로 getRandom.js 파일 안에는
export default function random() { return Math.floor(Math.random() * 10); }
라는 코드가 있다.
조건문은 크게 if...else문과 switch문으로 나눈다.
if else 문은 주어진 조건식(불리언 값으로 평가될 수 있는 표현식)의 평가 결과, 즉 논리적 참, 거짓에 따라 실행할 코드 블록을 결정한다.
만약 조건식의 평가 결과가 불리언 값이 아니면 불리언 값으로 강제 변환되어 논리적 참, 거짓을 구별한다.
switch 문은 switch 문의 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case 문으로 실행 순서를 이동시킨다. case 문은 상황(case)을 의미하는 표현식을 지정하고 콜론으로 마친다. 그리고 그 뒤에 실행할 문들을 위치시킨다.
switch 문의 표현식과 일치하는 표현식을 갖는 case 문이 없다면 실행 순서는 default 문으로 이동한다. default 옵션으로 사용할 수도 있고 사용하지 않을 수도 있다.
default 문에는 break 문을 생략하는 것이 일반적이다. default 문은 switch 문의 가장 마지막에 위치하므로 default 문의 실행이 종료하면 switch 문을 빠져나간다. 따라서 별도로 break 문이 필요없다.
cf) case 문은 반드시 단독으로 사용되어야 하는 것은 아니다.
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
if...else문은 불리언 값을 이용
switch문은 하나의 자료에 대한 값을 이용 (가독성이 더 좋다.)
실행 순서는 조건문(if, switch)이나 반복문(while, for)의 사용으로 제어할 수 있다 이를 흐름제어(Control Flow)라 한다. 또는 함수 호출로 변경될 수 있다.
반복문(Loop statement)은 주어진 조건식(conditional expression)의 평가 결과가 참인 경우 코드 블럭을 실행한다. 그 후 조건식을 다시 검사하여 여전히 참인 경우 코드 블록을 다시 실행한다. 이는 조건식이 거짓일 때까지 반복된다.
반복문은 크게 for문
, while문
, do...while문
으로 나눌 수 있다.
for문은 초기화식, 조건식, 증감식에 의해 실행되고,
while문은 조건식에 의해 실행된다.
cf) 무한루프 만들기: while (true) { }
함수란 어떤 작업을 수행하기 위해 필요한 statement들의 집합을 정의한 코드 블록이다. 함수는 이름과 매개변수를 갖으며 필요한 때에 호출하여 코드 블록에 담긴 문들을 일괄적으로 실행할 수 있다.
즉, 함수는 코드의 집합을 모아 놓은 뒤에 한 번 이상 호출하기 위해 설정한다.
동일한 작업을 반복적으로 수행하여야 한다면 함수를 만들어서 호출하는 것이 효율적이다. 이러한 특성으로 함수는 코드의 재사용이 매우 유용하다.
- 함수 선언식
(function funcName() {})
- 함수 표현식
(let 변수명= function() {})
함수 호이스팅 문제로, 함수 표현식만을 사용할 것을 권고하고 있다. 함수 호이스팅이 함수 호출 전 반드시 함수를 선언하여야 한다는 규칙을 무시하므로 코드의 구조를 엉성하게 만들 수 있다는 문제점이 있다.
function sayHi(X) {
console.log("Hi! my name is X");
}
sayHi("Song");
sayHi("Lee");
sayHi("Hwang");
sayHi("Jang");
호이스팅: 함수 선언부가 유효범위(Scope) 최상단으로 끌어올려지는 현상
함수 선언문으로 함수가 정의되기 이전에 함수 호출이 가능하다. 함수 선언문의 경우, 함수 선언의 위치와는 상관없이 코드 내 어느 곳에서든지 호출이 가능한데 이것을 함수 호이스팅(Function Hoisting)이라 한다. 즉, 자바스크립트는 모든 선언문(var, let, const, function, function*, class)이 선언되기 이전에 참조 가능하다.
let a = square(5);
function square(number) {
return number * number;
}
(함수 호이스팅 vs 변수 호이스팅)
함수는 자신을 호출한 코드에게 수행한 결과를 반환(return)할 수 있다. 이때 반환된 값을 반환값(return value)이라 한다. 함수는 반환을 생략할 수 있다.
자바스크립트 해석기는 return 키워드를 만나면 함수의 실행을 중단한 후, 함수를 호출한 코드로 되돌아간다. 만일 return 키워드 이후에 다른 구문이 존재하면 그 구문은 실행되지 않는다.
.caller
,.length
,.name
,._proto_
,.prototype
콜백(callback): 함수의 인수로 사용되는 함수
실행 위치를 보장하기 위해서 사용한다.
콜백 함수(Callback function)는 함수를 명시적으로 호출하는 방식이 아니라 특정 이벤트가 발생했을 때 시스템에 의해 호출되는 함수를 말한다. 즉, 콜백 함수는 매개변수를 통해 전달되고 전달받은 함수의 내부에서 어느 특정시점에 실행된다.
콜백 함수는 주로 비동기식 처리 모델(Asynchronous processing model)에 사용된다. 비동기식 처리 모델이란 처리가 종료하면 호출될 함수(콜백함수)를 미리 매개변수에 전달하고 처리가 종료하면 콜백함수를 호출하는 것이다.
() => {}
vsfunction () {}
외우기 힘들면 function이 화살표로 바뀌어 이동한다고 생각하자.
cf) 화살표 함수로 객체 데이터 {}를 반환할 때는 소괄호()로 감싸줘야 한다.
const a = (x) => ({ name: 'Song' })
const b = (y) => { statement }
즉시실행함수 (IIFE, Immediately-Invoked Function Expression)은 만들자 마자 바로 한 번만 사용하고 이름을 짓지 않아도 된다는 장점을 가지고 있다. 사용 방법은 함수 블럭을 소괄호()로 감싸주고 세미콜론을 적어주면 된다.
(function () {
console.log(a * 2);
}());
- setTimeout(함수, 시간): 일정 시간 후 함수 실행
- setInterval(함수, 시간): 시간 간격마다 함수 실행
- clearTimeout(): 설정된 Timeout 함수를 종료
- clearInterval(): 설정된 Interval 함수를 종료
주의할 점) 1000ms = 1초
const timer= setTimeout(function() {}, 3000) //3초 뒤에 익명 함수 실행
clearTimeout(timer) //timer 라는 타이머 함수 종료
자바스크립트는 객체(object) 기반의 스크립트 언어이며 자바스크립트를 이루고 있는 거의 모든 것이 객체이다.
객체는 키(이름)와 값으로 구성된 프로퍼티(property)의 집합이다. 프로퍼티의 값으로 자바스크립트에서 사용할 수 있는 모든 값을 사용할 수 있다. 자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다. 따라서 프로퍼티 값으로 함수를 사용할 수도 있으며 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메소드라 부른다.
이와 같이 객체는 데이터를 의미하는 프로퍼티(property)와 데이터를 참조하고 조작할 수 있는 동작(behavior)을 의미하는 메소드(method)로 구성된 집합이다.
객체 생성 방법 #1 (선호)
객체 생성 방법 #2
// 빈 객체의 생성
let ID = new Object();
// 프로퍼티 추가
ID.name = 'Song';
ID.age = 26;
ID.sayHi = function () {
console.log('Hi! My name is ' + this.name);
};
객체 생성 방법 #3
생성자 함수를 사용하면 마치 객체를 생성하기 위한 템플릿(클래스)처럼 사용하여 프로퍼티가 동일한 객체 여러 개를 간편하게 생성할 수 있다.
cf) 생성자 함수 이름은 일반적으로 대문자를 사용한다. 생성자 함수(큰 틀)임을 인식하도록 도움을 준다. (Person)
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHi = function(){
console.log('Hi! My name is ' + this.name);
};
}
// 인스턴스의 생성
let person1 = new Person('Lee', 25);
let person2 = new Person('Kim', 21);
함수를 프로토타입으로 미리 설정해놓기 (참조 가능하게 만들기)
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
return `Hi! My name is ${this.name}`;
}; //프로토타입으로 미리 함수를 상위에 설정해놓기
const song = new Person('Song', 26);
console.log(song.sayHi);
객체의 프로퍼티 값에 접근하는 방법은 마침표(.) 표기법
과 대괄호([]) 표기법
이 있다. 프로퍼티 키가 유효한 자바스크립트 이름이고 예약어가 아닌 경우 프로퍼티 값은 마침표 표기법, 대괄호 표기법 모두 사용할 수 있다.
프로퍼티 이름이 유효한 자바스크립트 이름이 아니거나 예약어인 경우 프로퍼티 값은 대괄호 표기법으로 읽어야 한다. 대괄호([]) 표기법을 사용하는 경우, 대괄호 내에 들어가는 프로퍼티 이름은 반드시 문자열이어야 한다.
let person = {
'last-name': 'Song',
age: 26,
};
console.log(person.last-name); // NaN: undefined-undefined
console.log(person[last-name]); // ReferenceError: first is not defined
console.log(person['last-name']); // 'Song'
console.log(person.age); // 26
console.log(person[age]); // ReferenceError: age is not defined
console.log(person['age']); // 26
객체.새로운키="새로운값";
person.location="Seoul";
Object.assign()
: 출처 객체로부터 대상 객체로 속성을 복사할 때 사용한다. const target = { a: 1, b: 2} // target: 대상 객체
const source = { b: 4, c: 5} // source: 출처 객체
const returnedTarget = Object.assign(target, source);
console.log(target); // {a: 1 , b: 4, c: 5}
console.log(returedTarget); // {a: 1 , b: 4, c: 5}
const target = { a: 1, b: 2} // target: 대상 객체
const source = { b: 4, c: 5} // source: 출처 객체
const returnedTarget = Object.assign({}, target, source); // 원본 데이터 보존
console.log(target); // {a: 1 , b: 4, c: 5}
console.log(returedTarget); // {a: 1 , b: 2}
Object.keys()
: 객체 키들을 모은다.const user = {
name: 'Song',
age: 26,
};
const keys = Objcet.keys(user);
console.log(keys) // ['name', 'age']
console.log(user['age']); //인덱싱, 26
const values = keys.map(key => user[key]);
console.log.log(values); // ["Song", 26]
객체 데이터를 순서대로 변수로 치환해서 작성하기 편하게 만든다.
const user = {
name: 'Song',
age: 26,
};
const { name, age } = user; // 구조 분해 할당
const fruits = ['Apple', 'Banana', 'Cherry']
const [a, b, c, d] = fruits // 구조 분해 할당
console.log(a, b, c, d); // Apple, Banana, Cherry, undefined
전개 연산자 (Spread)
const fruits = ['Apple', 'Banana', 'Cherry'];
console.log(fruits[0], fruits[1], fruits[2]); //Apple, Banana, Cherry
console.log(...fruits); //Apple, Banana, Cherry