JavaScript는 객체 지향 프로그래밍이 가능한 언어이다. 객체를 생성하고 관리하는 데 강점이 있어 복잡한 기능을 구현할 수 있다.
객체 지향 프로그래밍
데이터와 함수를 객체라는 그룹으로 묶어서 처리하는 방법이다.. 라는데 이렇게는 바로 이해하기 무리가 있다.절차지향 프로그래밍과 비교하면 좀 더 와 닿는데, 절차 지향 프로그래밍은 컴퓨터가 순서대로 실행하는 과정을 단계적으로 코드로 짜서 프로그램을 만드는 거고, 객체 지향 프로그래밍은 순서대로 일을 처리하는 프로그램을 만드는 게 아니라 상태와 행동을 가지고 있는 객체 그룹으로 묶어서 처리를 한다.
JavaScript에서 객체를 어떻게 만드냐?
중괄호({}
)를 사용해 객체를 만들고, 각 속성을 쉼표(,
)로 구분하여 추가한다. 각 속성들은 이름과 값을 가지는데, 값에는 다양한 데이터 타입을 사용할 수 있다.
객체 내부 함수를 method라고 부르고, 속성의 값으로 함수를 추가할 수 있다.
즉, 객체를 만들어서 필요한 속성과 메소드를 추가해서 사용한다.
JavaScript는 동적 타이핑을 지원하는 언어이다. 변수를 선언할 때 타입을 지정하지 않는다. Java에서 변수를 선언할 때 string 변수명 = 값 할당
이런 식으로 앞에 타입을 지정하는데, JavaScript는 타입 지정 없이 그냥 변수명만 선언하면 런타임 시점에 변수에 할당되는 값에 따라 자동으로 데이터 타입이 결정된다.
런타임(Runtime)
런타임 시점은 프로그램이 실행되는 동안의 시점을 말한다. 즉 Java로는 내가 코드를 작성할 때 미리 타입을 지정해주고 실행을 하는데, JavaScript는 타입 생각 안하고 일단 코드 작성한 후에 프로그램을 실행하면 컴퓨터가 코드를 실행시키면서 데이터 타입을 결정한다.(터미널에 코드가 실행될 때 데이터 타입이 결정된다)
런타임의 반대 의미로는 컴파일 시점이라고 한다. TypeScript에서 컴파일 시점에 데이터 타입이 결정된다.
JavaScript는 함수를 일급 객체로 취급하고, 고차 함수를 지원해서 코드의 재사용성과 가독성을 높일 수 있다.
일급객체(first-class object)
함수를 일반 값과 마찬가지로 변수에 할당하거나, 함수의 인자로 전달하거나, 함수의 반환값으로 사용할 수 있는 객체를 말한다.// // 함수를 변수에 할당 const add = function(a, b) { return a + b; } // 함수를 인자로 받는 함수 function calculate(func, a, b) { return func(a, b); } // 함수를 반환하는 함수 function getAddFunction() { return add; } // 함수를 일급 객체로 다루어 코드의 재사용성을 높임 console.log(calculate(add, 2, 3)); // 5 console.log(getAddFunction()(2, 3)); // 5
고차 함수(higher-order function)
함수를 인자로 받거나, 함수를 반환하는 함수를 말한다.function operate(func, a, b) { return func(a, b); } function add(a, b){ return a + b; } function multiply(a, b){ return a * b; } console.log(operate(add, 2, 3)); // 5 console.log(operate(multiply, 2, 3)); // 6
작업을 순차적으로 기다리지 않고, 병렬로 처리할 수 있도록 하는 방식이다.
JavaScript는 Node.js를 이용해 서버 측에서도 사용할 수 있다. 웹 개발 전반에 걸쳐 JS를 활용할 수 있는 것.
모든 프로그래밍 언어는 기억하려는 값을 메모리에 저장하고, 저장된 값을 읽어들여 재사용하기 위해 변수를 이용한다. 변수를 이용하지 않으면, 변수 이름만 넣으면 되는 작업을 일일이 계속해서 작성해야 하는 반복적인 작업이 되고, 오타도 나기 쉽다.
변수의 주요 개념
- 변수 이름: 저장된 값의 고유 이름
- 변수 값: 변수에 저장된 값
- 변수 할당: 변수에 값을 저장하는 행위
- 변수 선언: 변수를 사용하기 위해 컴퓨터에 알리는 행위
- 변수 참조: 변수에 할당된 값을 읽어오는 것
JS에서 변수는 var
, let
, const
세 가지 방법으로 선언할 수 있다.
var
let
const
''
)나 큰 따옴표(""
)로 감싸서 표현string.length
string1.concat(string2)
string.subtr(,)
string.slice(,)
string.search("")
→ index값 리턴string.replace("", "")
string.split("")
{}
)를 사용해서 객체를 생성한다.[]
)를 사용해서 배열을 생성한다.JavaScript에서는 다양한 자료형을 다룰 수 있고, 이 자료형들은 서로 형 변환이 가능하다.
console.log(1 + "2"); // "12"
console.log("1" + true); // "1true"
console.log("1" + {}); // "1[object Object]"
console.log("1" + null); // "1null"
console.log("1" + undefined); // "1undefined"
console.log(1 - "2"); // -1
console.log("2" * "3"); // 6
console.log(4 + +"5"); // 9
// 빈 문자열("")이나 공백 문자열(" ")은 0으로 변환
Boolean()
함수를 이용한 boolean 변환console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
// 위 이외의 값은 true
console.log(Boolean("false")); // true
console.log(Boolean({})); // true
String()
console.log(String(123)); // "123"
console.log(String(true)); // "true"
console.log(String(false)); // "false"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
console.log(String({})); // "[object Object]"
Number()
console.log(Number("123")); // 123
console.log(Number("")); // 0
console.log(Number(" ")); // 0
console.log(Number(true)); // 1
console.log(Number(false)); // 0
JavaScript에서는 다양한 연산자를 제공해 변수나 상수를 다양한 방법으로 조작할 수 있다.
더하기 연산자 +
숫자와 문자열을 함께 사용할 경우, 자동으로 문자열로 변환
빼기 연산자 -
숫자와 문자열을 함께 사용할 경우, 숫자로 변환 (글자인 문자열과 함께 쓰면 NaN)
곱하기 연산자 *
숫자와 문자열을 함께 사용할 경우, 숫자로 변환 (글자인 문자열과 함께 쓰면 NaN)
나누기 연산자 /
숫자와 문자열을 함께 사용할 경우, 숫자로 변환 (글자인 문자열과 함께 쓰면 NaN)
나머지 연산자 %
나눗셈의 나머지를 구할 수 있음
숫자와 문자열을 함께 사용할 경우, 숫자로 변환 (글자인 문자열과 함께 쓰면 NaN)
=
+=
-=
*=
/=
%=
===
!==
→ 자료형 타입까지 비교<
>
<=
>=
→ 숫자와 문자열을 함께 사용할 경우, 숫자로 변환&&
||
!
? true : false
조건에 따라 값을 선택할 수 있다.
let result = (10 > 5) ? "크다" : "작다"
console.log(result); // "크다"
typeof
console.log(typeof 123); // "number"
console.log(typeof "123"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"
함수는 input(매개변수)과 output(반환값)을 가지고 있는 단위이다.
JavaScript에서는 함수를 정의해서 코드의 재사용성을 높일 수 있다.
왜? 자주 사용하는 로직을 함수 블록에 넣어 두면, 매번 그 로직을 일일이 써야 할 필요 없이 함수명만 적어서 호출하면 되기 때문에!
function add(x,y) {
return x + y;
}
let add = function(x, y) {
return x + y;
}
function add(x, y) {
return x + y;
}
console.log(add(2, 3));
함수를 호출할 때는 함수 이름 뒤에 괄호를 사용한다.
함수 매개변수
함수를 호출할 때는 매개변수에 값을 전달한다.
function add(x, y) {
return x + y;
}
console.log(add(2, 3)); // 5
위 예제에서 add 함수는 x, y 매개변수를 받아들인다.
함수 반환값
함수 안에 return문이 있다면, 함수를 호출한 결과값을 변수에 할당하여 사용할 수 있다.
scope는 범위를 말한다. 변수가 어디까지 영향을 끼칠 수 있느냐!
전역 스코프(global scope)
변수가 전체 범위에 영향을 끼치는 경우.
전역 스코프에서 선언된 변수는 어디에서든지 참조할 수 있다.
지역 스코프 (local scope)
함수 내에서만 변수가 영향을 끼칠 수 있는 경우.
함수 내 지역 스코프에서 선언된 변수는 해당 함수 내에서만 참조할 수 있다.
블록 스코프(block scope)
if문 내에서 선언된 변수는 해당 블록 내에서만 참조할 수 있다.
let add = (x, y) => {
return x + y;
}
let add = (x, y) => x + y;
// 중괄호, return 키워드 생략 가능
let add = x => x * x;
// 매개변수 괄호 생략 가능
JavaScript에서는 조건문을 사용해 특정 조건을 만족하는 경우에만 코드를 실행할 수 있다.
if (condition) {
// main logic
}
if (condition) {
// main logic 1
} else {
// main logic 2
}
if (condition) {
// main logic 1
} else if (condition1) {
// main logic 2
} else {
// main logic 3
}
let variable = "사과";
switch (variable) {
case "사과":
console.log("사과는 빨간색");
break; // break문을 넣어줘야 해당 코드만 실행되고 중괄호를 빠져나올 수 있다.
// 없으면 계속 흐름
case "바나나":
console.log("바나나는 노란색");
break;
case "오렌지":
console.log("오렌지는 주황색");
break;
default:
console.log("해당하는 과일이 없습니다.");
break;
}
switch문은 변수의 값에 따라 여러 경우(case) 중 하나를 선택해 해당하는 코드를 실행한다.
default
는 모든 경우에 맞지 않는 경우에 실행되는 코드를 작성한다.
let age = 20;
let message = (age >= 18) ? "성인입니다." : "미성년자입니다.";
console.log(message); // "성인입니다."
if문과 비슷한 역할을 하며, 조건이 참인 경우와 거짓인 경우 각각 다른 값을 반환한다.
let age = 20;
let gender = "여성";
if (age >= 18) {
if (gender === "남성") {
console.log("성인 남성입니다.");
} else {
console.log("성인 여성입니다.");
}
} else {
console.log("미성년자입니다.");
}
조건문 안에 또다른 조건문을 사용해 복잡한 조건을 판별할 수 있다.
let x = 10;
(x > 0) && console.log("x는 양수")
&& 연산자를 이용해 변수의 값에 따라 조건부 실행을 하도록 할 수 있다.
let x; // x = undefined
let y= x || 10;
// 변수 x가 존재하지 않는 경우(값이 할당되지 않은 경우) 기본값으로 10을 사용
console.log(y); // 10
|| 연산자를 사용하여 단축 평가(short-circuit evaluation)를 할 수 있다.
변수 x가 존재하지 않는 경우, || 연산자는 false 값을 반환하고, 기본값으로 지정한 10을 반환한다.
if (0) {
console.log("이 코드는 실행되지 않습니다.");
}
0
, 빈 문자열(""
), null
, undefined
, NaN
, false
for (초기값; 조건식; 증감식) {
// 반복할 코드
}
let numbers = [1,2,3,4,5];
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
// 배열 numbers의 요소들을 순서대로 출력
}
let person = { name: "John", age: 30, gender: "male" };
for (let key in person) {
console.log(key + ": " + person[key]);
// 객체 person의 프로퍼티를 순서대로 출력
// name: John
// age: 30
// gender: male
}
조건식에 들어갈 초기값 선언;
while (조건식) {
반복할 코드;
초기값 증가;
}
조건식이 참인 경우에만 코드를 반복해서 실행
초기값 선언;
do {
반복할 코드;
초기값 증가;
} while (조건식);
일단 한 번은 코드를 실행하고, 그 후에 조건식을 체크하여 반복 여부를 결정
break;
반복문을 종료continue;
해야할 명령문을 실행하지 않고 그 다음 명령문을 실행 (if문 안에 주로 쓰임)let person = {
name: "김코딩",
age: 30,
gender: "남자"
};
객체를 만들 때는 중괄호({}
)를 사용하고, 속성과 값을 콜론(:
)으로 구분하여 작성한다.
각 속성과 값은 쉼표(,)로 구분한다.
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
let person1 = new Person("김코딩", 30, "남자");
let person2 = new Person("박해커", 40, "여자");
생성자 함수 Person()을 사용해 객체 person1과 person2를 생성했다.
생성자 함수를 사용하면 객체를 일괄적으로 생성할 수 있다.
객체의 속성에 접근할 때는 .
이나 [""]
를 사용하여 속성 이름을 입력해 접근하여 값을 출력한다.
let person = {
name: "김코딩",
age: 30,
gender: "남자"
};
let keys = Object.keys(person);
console.log(keys); // ["name", "age", "gender"]
Object.keys()
메소드는 객체의 속성(key) 이름을 배열로 반환한다.
let person = {
name: "김코딩",
age: 30,
gender: "남자"
};
let values = Object.values(person);
console.log(values); // ["김코딩", 30, "남자"]
Object.values()
메소드는 객체의 속성 값(valus)들을 배열로 반환한다.
let person = {
name: "김코딩",
age: 30,
gender: "남자"
};
let entries = Object.entries(person);
console.log(entries); // [ ['name', '김코딩'], ['age', 30], ['gender', '남자'] ]
Object.entries()
메소드는 객체의 속성 이름(key)과 속성 값(value)들을 2차원 배열로 반환한다.
let person = {
name: "김코딩",
age: 30,
gender: "남자"
};
let newPerson = Object.assign({}, person, {age: 35});
console.log(newPerson); // {name: "김코딩", age: 35, gender: "남자"}
Object.assign() 메소드는 기존 객체를 복사하여 새로운 객체를 만든다.
let person1 = {
name: "김코딩",
age: 30,
gender: "남자"
};
let person2 = {
name: "김코딩",
age: 30,
gender: "남자"
};
console.log(person1 === person2) // false
console.log(JSON.stringify(person1) === JSON.stringify(person2)) // true
객체를 비교할 때는 일반적으로 ===
연산자를 사용할 수 없다.
대신 JSON.stringify()
함수를 사용해 객체를 문자열로 변환한 후('{"name":"김코딩",...}'
), 문자열 비교를 할 수 있다.
let person = {
name: "김코딩",
age: 30,
};
let gender = {
gender: "남자"
};
let mergedPerson = {...person1, ...gender};
console.log(mergedPerson); // {name: "김코딩", age: 30, gender: "남자"}
객체 병합을 할 때는 전개 연산자(...
)를 사용한다.
let fruits = ["사과", "바나나", "오렌지"];
let numbers = new Array(5);
new Array()
를 사용하여 배열의 크기를 지정할 수 있다.
배열[인덱스]
로 접근한다.
push("")
배열의 끝에 요소 추가
pop()
배열의 마지막 요소 삭제
shift()
배열의 첫번째 요소 삭제
unshift("")
배열의 맨 앞에 요소를 추가
splice(index, number, "option")
배열의 index 요소를 number개 삭제하고, "option"을 그 자리에 넣음
slice(index1, index2)
index1 요소부터 index2 요소까지 잘라 새로운 배열로 만듦
forEach(func())
배열의 각 요소에 대해 콜백 함수를 실행
map(func())
배열의 각 요소에 대해 콜백 함수를 실행하고, 그 결과를 새로운 배열로 반환
filter(func())
배열의 각 요소에 대해 콜백 함수를 실행하고, 그 결과가 true인 요소만 새로운 배열로 반환
reduce(func(acc, cur), number)
find(func())
배열의 각 요소에 대해 콜백 함수를 실행하고, 그 결과가 true인 첫 번째 요소를 반환
some(func())
배열의 각 요소에 대해 콜백 함수를 실행하고, 그 결과가 true인 요소가 하나라도 있는지 확인
Boolean 리턴
every(func())
배열의 각 요소에 대해 콜백 함수를 실행하고, 그 결과가 true인 요소가 모든 요소인지 확인
sort(func(a, b) => a - b)
배열의 요소를 정렬
reverse()
배열의 요소를 역순으로 정렬