npm - node package manager
DOM
가상 DOM
Content가 데이터!
MPA는 페이지가 그때그때 바뀐다.
SPA는 페이지가 한 번 내려온다. 그 이후에는 JS로 데이터만 가져와서 그때그때 뿌려주는 것이다.
→ 동작이 더욱 빠르고 부드럽게 느껴진다.
읽고, 해석하고, 보여주고, 반복한다
node.js 내부에 탑재된 프로그램.
명령 프롬프트에 node 라고 입력하면 REPL 이 실행된다.
c:\javascript> node ⇐ REPL 실행
Welcome to Node.js v22.12.0.
Type ".help" for more information.
>
> let i = 100
undefined
> let j = 200
undefined
> i + j
300
> .exit ⇐ REPL 종료
sample.html 파일을 생성하고, inline, internal, external 방식으로 스크립트 코드를 추가 ⬇️
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- external JS -->
<script src="helloJavaScript.js"></script>
</head>
<body>
<!-- inline JS -->
<button onClick="javascript: alert('button clicked')">버튼</button>
<!-- internal JS -->
<script>
let s = "abc";
console.log(s);
</script>
</body>
</html>
웹 서버 기동(live server) 후 해당 페이지를 요청하면 응답 전달된 페이지의 스크립트 코드가 실행된다.
값을 생성하거나 반환하는 코드
// 리터럴 : 값 그자체
5
"hello"
true
[1, 2, 3]
{a: 1}
var a = 5;
var b = 5 + 3;
var c = true && false;
function add(a, b) {
return a + b;
}
add(10, 20);
프로그램이 수행할 동작을 정의하는 코드
하나 이상의 표현식으로 구성될 수 있으며, 대부분의 경우 세미콜론(;)으로 끝난다.
ex) 선언문, 조건문, 반환문, 반복문, ...
let x = 6;
// 조건문
if (x > 10) {
console.log("크다");
} else {
console.log("작다");
}
// 반복문
for (let i = 0; i < 10; i++) {
console.log(i);
}
특정 동작을 정의하거나 예약어로 사용되어 특정 기능을 수행하는 단어들
변수 이름이나 함수 이름으로 사용할 수 없다.
변수, 함수, 클래스, 모듈 등의 이름을 정의하는 데 사용
관례)
cf) Case Style
snake_case: C
kebab-case: AWS S3 버킷 이름, url
camelCase: javascript
PascalCase: pascal
BigInt ⬇️
> i = 1234567890
1234567890
> console.log(typeof(i))
number
> i = 1234567890n
1234567890n
> console.log(typeof(i))
bigint
뒤에 n을 붙이면 BigInt type이 된다.
Symbol ⬇️
> a = "abc"
'abc'
> b = "abc"
'abc'
> a == b
true
> a === b
true
> a = Symbol("abc")
Symbol(abc)
> b = Symbol("abc")
Symbol(abc)
> a == b
false
> a === b
false
user defined objects
const person = { name: "홍길동", age: 23 };
built-in objects
: 미리 정의되어 있는 객체 타입
ex) objects, arrays, dates, map, sets, intarrays, floatarrays, promises, ...
> a = new Map()
Map(0) {}
> a.set("name", "홍길동")
Map(1) { 'name' => '홍길동' }
> a.set("age", 23)
Map(2) { 'name' => '홍길동', 'age' => 23 }
😇 map이 object보다 더 빠르고 유연하기 때문에 반복적인 데이터는 map 사용 권장!!
> a = new Set([1, 2, 3, 4, 1, 2, 3])
Set(4) { 1, 2, 3, 4 } ⇐ 중복되지 않은 값을 가짐
변수에 데이터가 대입되는 시점에 변수의 자료형이 결정된다.
자바에서는 int i = 10; 와 같이 변수를 선언할 때 변수가 가질 수 있는 데이터 타입을 지정
자바스크립트에서는 var i = 10; 와 같이 변수를 선언할 때 데이터 타입을 지정하지 않고,
변수에 값이 할당되는 시점에 할당되는 값에 따라 변수의 데이터 타입이 결정
자바에서는 int i = "abc"; 변수의 데이터 타입과 할당되는 값의 데이터 타입이 일치하지 않아서 오류가 발생하는 반면, 자바스크립트에서는 var i = "abc"; 변수가 할당되는 시점에 데이터 타입이 결정되므로 정상적으로 동작한다.
정리
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>자바 스크립트 자료형</h1>
<script>
// number type
let n1 = 1234;
let n2 = 56.78;
console.log(n1, typeof(n1)); // 1234 number
console.log(n2, typeof(n2)); // 56.78 number
// string type
let s1 = 'Hello';
let s2 = "World";
// 이스케이프 처리
let s3 = 'Hello, \'Inho\'';
let s4 = "Hello, \"Inho\"";
// 템플릿 문자열(template literal)
let name = 'Inho';
let age = 23;
let hello1 = '이름은 "' + name + '"이고, 나이는 ' + age + '세 입니다.';
console.log(hello1);
let hello2 = `이름은 "${name}"이고, 나이는 ${age}세 입니다. 내년에는 ${age + 1}세가 됩니다.`;
console.log(hello2);
// boolean type
let b1 = true;
let b2 = false;
console.log(b1, typeof(b1)); // true boolean
console.log(b2, typeof(b2)); // false boolean
// falsy value
console.log(Boolean('')); // false
console.log(Boolean(0)); // false
console.log(Boolean(-0)); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(false)); // false
if (undefined) {
console.log('undefined는 true');
} else {
console.log('undefined는 false'); // undefined는 false 출력
}
if (-1) {
console.log('-1은 true'); // -1은 true 출력
} else {
console.log('-1은 false')
}
// null type
let nullValue = null;
// undefined type
let u1;
let u2 = undefined;
// array type = 다양한 데이터 타입을 순서(index)대로 모아놓은 것
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [1, 2.3, 'hello', true, null, undefined, [1, 2, 3]];
console.log(arr1[3]); // 4
console.log(arr2[5]); // undefined
arr1[3] = 100;
console.log(arr3); // [1, 2, 3, 100, 5]
// object type = key와 value로 이루어진 데이터 타입
// key는 문자열 또는 심볼이어야 하고, 값은 모든 데이터 타입이 가능
let obj1 = { a: 'apple', b: 'banana', c: 'cherry'};
let obj2 = { name: 'Inho', age: 23, 'favorite colors': ['red', 'blue', 'green']};
console.log(obj1['a']) // apple
console.log(obj1.a) // apple
console.log(obj2['favorite colors']); // ['red', 'orange', 'green']
</script>
</body>
</html>
⭐️⭐️⭐️⭐️⭐️호이스팅: 어떤 변수의 선언이 그 문서의 가장 위로 올라가는 현상
<script>
console.log(x1); // undefined => x1 변수가 hoisting되어 선언된 것으로 처리
var x1;
console.log(x1); // undefined
</script>
내부적으로 아래와 같이 해석되어 실행
<script>
var x1;
console.log(x1); // undefined => x1 변수가 hoisting되어 선언된 것으로 처리
console.log(x1); // undefined
</script>
<script>
console.log(x1); // undefined => x1 변수가 hoisting되어 선언된 것으로 처리
var x1;
console.log(x1); // undefined
x1 = 100;
console.log(x1, typeof(x1)); // 100 'number'
</script>
선언부와 할당부가 나뉘고, 선언부가 맨 위로 호이스팅 된다.
<script>
console.log(x2); // undefined
var x2 = 100;
console.log(x2); // 100
</script>
내부적으로는 선언부만 위쪽으로 올라간다.
<script>
var x2;
console.log(x2); // undefined
x2 = 100;
console.log(x2); // 100
</script>
<script>
console.log(x3); // Cannot acces 'x3' before initialization
let x3 = 100;
console.log(x3); // 100
</script>
let, const 를 사용하면 내부적으로는 선언부가 호이스팅돼서 올라가긴 하는데
초기화 되기 전까지 변수는 TDZ(Temporal Dead Zone) 라는 공간에 머물러있다.
이러한 변수는 초기화 전까지는 참조(사용)를 할 수 없다.
→ 초기화되고 쓸 수 있다는 것을 보장해주므로 명확하게 사용할 수 있다!!! var 쓰지 말고 let, const 쓰자 😍
<script>
console.log(x3); // Cannot acces 'x3' before initialization
let x3 = 100;
console.log(x3); // 100
</script>
<script>
let x3; // 변수 선언이 호이스팅되지만 초기화되지 않음
// ⇒ TDZ 본관 ⇒ 초기화되기 전에 참조할 수 없음
console.log(x3); // Cannot access 'x3' before initialization
x3 = 100;
console.log(x3); // 100
</script>
const로 선언한 변수는 값을 변경할 수 없다.
<script>
const a = 100;
a = 200; // Uncaught TypeError: Assignment to constant variable.
</script>
함수 자체가 scope로 호이스팅 되어 어디서든지 읽을 수 있다.
<script>
hello(); // Hello, JavaScript 이것도 가능하다! 함수 호이스팅 때문에
// 함수 선언문 형식으로 정의. 함수 정의 부분이 scope로 호이스팅 되어 가장 높은 곳으로 올라간다.
function hello() {
console.log("Hello, JavaScript");
}
hello(); // Hello, JavaScript
</script>
선언부만 올라가므로 undefined로 보인다.
<script>
hello(); // hello is not a function
var hello = function() {
console.log("Hello, JavaScript");
};
hello(); // Hello, JavaScript
</script>
위 코드는 아래와 같이 해석된다.
<script>
var hello; // undefined 상태
hello(); // hello is not a function
hello = function() {
console.log("Hello, JavaScript");
};
hello(); // Hello, JavaScript
</script>
var 대신 let으로 선언하면
참조할 수 없어서 reference error 가 뜬다.
<script>
hello(); // Uncaught ReferenceError: Cannot access 'hello' before initialization
let hello = function() {
console.log("Hello, JavaScript");
};
hello(); // Hello, JavaScript
</script>
위 코드는 아래와 같이 해석된다.
<script>
let hello; // 초기화되기 전까지 TDZ(Temporal Dead Zone)에 머물러 있다.
hello(); // Uncaught ReferenceError: Cannot access 'hello' before initialization
hello = function() {
console.log("Hello, JavaScript");
};
hello(); // Hello, JavaScript
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>연산자</h1>
<script>
// 나눗셈, 나머지 연산자
console.log(`7 / 5 = ${7 / 5}`); // 1.4
console.log(`7 % 5 = ${7 % 5}`); // 7 % 5 = 2 <= 나머지
// 나머지 연산의 부호는 왼쪽 피연산자의 부호를 따른다.
console.log(`7 % 5 = ${7 % 5}`); // 7 % 5 = 2 <= 나머지
console.log(`7 % -5 = ${7 % -5}`); // 7 % -5 = 2 <= 나머지
console.log(`-7 % 5 = ${-7 % 5}`); // -7 % 5 = -2 <= 나머지
console.log(`-7 % -5 = ${-7 % -5}`); // -7 % -5 = -2 <= 나머지
// 문자열 결합
console.log("Hello, " + 'JavaScript' + `!!!!`);
// 문자열의 일부를 선택 => 문자열[인덱스]
// 0 1 2
// 012345678901234567890
const message = "Hello, JavaScript!";
console.log(message[0]); // H <= 첫 번째 글자
console.log(message[17]); // !
console.log(message[message.length - 1]); // <= 마지막 글자
console.log(message[18]); // undefined
// prefix(전위 연산자) 방식, postfix(후위 연산자) 방식
let x = 100;
console.log(x); // 100
if (x++ > 100) { // 후위 연산자
console.log("100 초과");
} else {
console.log("100 이하"); // 100 이하 (100)
}
console.log(x); // 101
let y = 100;
console.log(y); // 100
if (++y > 100) { // 전위 연산자
console.log("100 초과"); // 100 초과 (101)
} else {
console.log("100 이하");
}
console.log(y); // 101
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>연산자</h1>
<script>
// 동등 연산자(equality operator), 일치 연산자(strict equality operator)
let n = 100;
let s = "100";
console.log(n, s); // 100 "100"
console.log(typeof n, typeof s); // number string
// 동등 연산자 <= 두 변수의 값을 비교
if (n == s) {
console.log("동등 연산자: 같다"); // 같다
} else {
console.log("동등 연산자: 다르다");
}
// 일치 연산자 <= 두 변수의 타입과 값을 함께 비교
if (n === s) { // if (typeof n == typeof s && n == s)
console.log("일치 연산자: 같다");
} else {
console.log("일치 연산자: 다르다"); // 다르다
}
// Object.is() 메서드
console.log(-0 === +0); // true (모호하다ㅜㅜ)
console.log(Object.is(-0, +0)); // false (더욱 정확하다)
console.log(typeof NaN); // number
console.log(Number.NaN === NaN); // false (모호하다ㅜㅜ NaN는 Number 타입인데..)
console.log(Object.is(Number.NaN, NaN)) // true
// 삼항 연산자 => (조건식) ? 참일 때 : 거짓일 때
let x = 100;
// if - else 구문으로 조건식을 구현
if (x > 100) {
console.log("100 초과");
} else {
console.log("100 이하");
}
// 동일한 로직을 삼항 연산자로 표현
console.log(x > 100 ? "100 초과" : "100 이하");
</script>
</body>
</html>
일치연산자 보다는 object ~ is 쓰는 게 더 정확하다!!
삼항 연산자는 조건부 렌더링할 때 많이 쓰인다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>자료형 변환</h1>
<script>
// 문자열로 변환
console.log(String(52));
console.log(String(true));
// 숫자로 변환
console.log(Number('52'));
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number("숫자")); // NaN
// 숫자로 변환 가능 여부를 확인할 때 NaN 로 확인하면 안 된다.
console.log(Number("52") == NaN); // false -> 숫자로 바꿀 수 있다!
console.log(Number("오십이") == NaN); // false -> 이상하다..
console.log(NaN == NaN); // false NaN 끼리는 무조건 다르다고 나온다. OMG
// isNaN으로 확인해야 한다.
console.log(isNaN(Number("52"))); // false
console.log(isNaN(Number("오십이"))); // true
console.log(isNaN(NaN)); // true
// boolean 으로 변환
// 0, -0, null, false, NaN, undefined, '' => false
// 그 외의 값은 true
</script>
</body>
</html>
number인지 확인하려면 isNaN으로 체크해보자.
falsy 한 값 외엔 true 로 반환된다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>자료형 변환</h1>
<script>
// 숫자와 문자열에 + 연산자를 사용하면 숫자를 문자열로 자동 변환
// + 연산자는 문자열 결합 연산자로 사용된다.
console.log(10 + 20); // 30
console.log("10" + 20); // 1020
console.log(10 + "20"); // 1020
console.log("10" + "20"); // 1020
// 숫자와 문자열에 + 가 아닌 다른 연산자를 사용하면 문자열을 숫자로 자동 변환
console.log(20 - 10); // 10
console.log("20" - 10); // 10
console.log(20 - "10"); // 10
console.log("20" - "10"); // 10
console.log("20" * 10); // 200
console.log("20" / 10); // 2
console.log("20" % 10); // 0
// 부정 연산자를 두 번 사용(!!)하면 Boolean() 함수를 사용하는 것과 동일해진다.
console.log(Boolean(0), !!0); // false false
console.log(Boolean(1), !!1); // true true
</script>
</body>
</html>
1. 함수 선언문
function add(x, y) { <= 반드시 함수 이름이 정의되어야 한다. x, y는 매개변수
return x + y;
}
console.log(add(10, 20)); <= 함수 이름으로 호출. 10, 20은 인자
2. 함수 표현식
변수는 값을 주고 받을 수 있다.
함수 표현식을 이용하면 함수를 변수처럼 사용할 수 있다.
변수 ⬇️
let a = 100;
let b = a;
console.log(a); // 100
console.log(b); // 100
(익명) 함수 표현식 ⬇️ ← 보통 이렇게 많이 쓴다.
let add = function (x, y) { return x + y; };
~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| <- 익명 함수 표현식
<- 함수 변수
let sum = add;
console.log(add(10, 20)); // 30
console.log(sum(10, 20)); // 30
기명 함수 표현식 ⬇️
let sum1 = function add(x, y) { return x + y };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
기명 함수 표현식 => **함수 외부에서는 함수 이름으로 사용할 수 없으나**,
함수 내부에서 자기 호출할 때(=재귀 호출) 사용할 수 있다.
let sum2 = sum1;
console.log(sum1(10, 20)); // 30
console.log(sum2(10, 20)); // 30
console.log(**add(10, 20)**); // **add is not defined**
→ 재귀 호출 예시 - 기명 함수 표현식을 쓴다.
let myFactorial = function **factorial**(n) {
if (n === 1) {
return 1;
}
return n * **factorial**(n - 1);
};
console.log(myFactorial(10));
함수 선언문으로 정의한 함수는
function add (x, y) { return x + y };
자바스크립트 내부에서 함수 이름과 함수 변수 이름이 동일한 함수 표현식으로 자동 변경
__________________________________________
let _add_ = function **add** (x, y) {return x + y; };
3. Function() 생성자 함수를 이용 ← 잘 안 쓴다.
let add = new Function('x', 'y', 'return x + y');
4. 함수를 활용
함수를 다른 함수의 인자로 전달
<script>
let click = function(fname) {
fname();
};
let loginButtonClick = function() {
console.log("로그인 되었습니다.");
};
let logoutButtonClick = function() {
console.log("로그아웃 되었습니다.");
};
click(loginButtonClick);
click(logoutButtonClick);
</script>
click이라는 똑같은 interface를 이용하고 있음에도 불구하고 넣는 함수에 따라 동작이 달라진다.
인터페이스는 미리 정의되어 있는데 구체적인 동작은 실행시점에 결정된다!!
ex2) calculator
let calculator = function(f, x, y) {
f(x, y);
};
let add = function(x, y) {
console.log(\`x + y = ${x + y}\`);
};
let sub = function(x, y) {
console.log(\`x - y = ${x - y}\`);
};
let mul = function(x, y) {
console.log(\`x * y = ${x * y}\`);
};
let div = function(x, y) {
console.log(\`x / y = ${x / y}\`);
};
calculator(add, 10, 20);
calculator(sub, 10, 20);
calculator(mul, 10, 20);
calculator(div, 10, 20);
외부에 있는 함수만 고치면 된다. 인터페이스 내부를 고칠 필요가 없다! 굳. 코드가 아름다워진다!!! ⭐️
비교) 변화가 생기면 내부에 변화가 생겨야 한다,,, 다음과 같이.. 😭
let cal = function(f, x, y) {
switch(f) {
case "add": console.log(`x + y = ${x + y}`); break;
case "sub": console.log(`x - y = ${x - y}`); break;
case "mul": console.log(`x * y = ${x * y}`); break;
case "div": console.log(`x / y = ${x / y}`); break;
}
};
5. 함수를 다른 함수의 리턴값으로 활용
변수처럼 움직일 수 있다 - 1급 객체
일급 객체(first-class object): 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
let foo = function() {
return function() {
console.log("반환함수");
};
};
let bar = foo();
bar(); // 반환함수
특정 함수가 어떻게 동작해야하는지 미리 규정해놓고 이를 사용하도록 강제할 때 사용한다.
함수의 실행결과가 함수가 됨.
multiplier는 함수를 반환하여 동작을 규정한다.
factor에 어떤 수가 들어오면 그 수를 곱한다.
ex2)
function twoTimes() {
return function(number){
return number * 2;
};
}
const no3 = twoTimes();
console.log(no3(3)); // 6
const no4 = twoTimes();
console.log(no4(4)); // 8
-----
function multiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplier(2);
console.log(double(3)); // 6
console.log(double(4)); // 8
const triple = multiplier(3);
console.log(triple(3)); // 9
console.log(triple(4)); //12
내부에서 정의해놓고 외부에서 쓰도록 한다. 4. 함수를 활용과 반대 개념
ex)
// 방법1. 반복문을 이용
function factorial_loop(n) {
let result = 1;
for (let i = 1; i <= n; i++) {
result *= i;
}
return result;
}
// 방법2. 재귀함수를 이용
function factorial_recursive(n) {
if (n == 1) {
return 1;
}
return n * factorial_recursive(n - 1);
}
console.log(factorial_loop(10));
console.log(factorial_recursive(10));
// 함수 실행에 소요된 시간을 측정
// 방법1. 함수 내부에 시작과 끝에 시간을 측정하는 코드를 추가
// => 루프 방식은 구현이 가능한데, 재귀함수는 구현이 불가(어려움)
// 방법2. 함수를 호출하는 부분에 시간을 측정하는 코드를 추가
let start = performance.now();
console.log(factorial_loop(10));
let end = performance.now();
console.log(`실행시간: ${(end - start).toFixed(10)}ms`);
start = performance.now();
console.log(factorial_recursive(10));
end = performance.now();
console.log(`실행시간: ${(end - start).toFixed(10)}ms`);
시간을 측정하고, 계산하고, 출력하는 부분이 중복되어 있다.
반복되는 공통 기능 부분을 콜백함수를 이용하면 좋다!
// 함수를 반환하는 함수를 이용해서 실행 시간을 측정
function performance_checker(func) {
return function(n) {
let start = performance.now();
console.log(func(n));
let end = performance.now();
console.log(`실행시간: ${(end - start).toFixed(10)}ms`);
}
}
performance_checker(factorial_loop)(10);
performance_checker(factorial_recursive)(10);
→ 기존 함수의 동작을 확장하거나 새로운 동작을 정의 (기존 함수를 변경하지 않고)
closer(p59) : 바깥쪽 변수(func)는 performance_checker가 종료되면 사라져야 하는데 내부의 함수(function(n)에 의해서 상태가 유지되는 현상 -> 이 함수가 실행되어야 사라진다-!
→변수의 상태를 계속해서 지속시키는 역할을 한다.
AoP(관심사의 분리) 개념
// 함수 실행에 필요한 인자값과 결과값을 출력하는 함수
const add = (a, b) => a + b;
add(10, 20);
const sub = (a, b) => a - b;
function logger(func) {
return function(...args) {
console.log(`인자값: ${args}`);
const result = func(...args);
console.log(`결과값: ${result}`);
return result;
}
}
logger(add)(10, 20);
logger(sub)(20, 10);
개발자가 코드를 이용해서 명시적으로 호출하는 함수가 아니고,
개발자는 단지 함수를 등록하기만 하고,
어떤 이벤트가 발생하거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수
💡 콜백 함수 예시 : 이벤트 핸들러 !!!
이벤트 핸들러 => 특정 이벤트가 발생했을 때 실행되는 함수
\<input type="button" onClick="function() {....}" />
함수 정의와 동시에 바로 실행하는 함수
익명 함수 표현식을 괄호로 둘러싼 후 바로 호출(실행)할 수 있도록 괄호 쌍을 추가
( function (name) { console.log(`${name}는 즉시 실행됩니다.`)} )('이 함수');
name : 매개변수
('이 함수') : 함수 실행에 필요한 인자값을 전달
// 익명 함수 표현식을 이용해서 함수를 정의
const add1 = function (x, y) { return x + y; };
console.log(add1(2, 3)); // 5
// 화살표 함수
// function 키워드를 제거하고, 함수 파라미터와 본문 사이에 화살표(=>)를 추가
const add2 = (x, y) => { return x + y; };
console.log(add2(2, 3)); // 5
// 화살표 함수 본문이 결과를 반환하는 구문으로 되어 있는 경우, 중괄호와 return 키워드를 생략할 수 있다.
const add3 = (x, y) => x + y;
console.log(add3(2, 3)); // 5
// 매개변수가 하나인 경우, 매개변수를 감싸고 있는 소괄호도 생략이 가능하다.
const add4 = x => x + 4;
console.log(add4(2)); // 6
// 객체를 반환하는 경우에는 반환 객체를 소괄호로 감싸야 한다.
const add5 = (x, y) => { return { result: x + y }; };
console.log(add5(2, 3)); // { result: 5 }
const add6 = (x, y) => ({ result: x + y });
console.log(add6(2, 3)); // { result: 5 }
😍 장점 : 읽기가 좋다. 마치 자연어를 읽듯이 코드를 만들고 해석할 수 있다.
프로그램 내에서 데이터를 처리하는 데 필요한 기술 ⬇️
문자열, 배열, 객체 등으로 데이터를 표현한다.
// 배열 선언
let values = [ "빨강", "노랑", "파랑", true, 20 ];
console.log(values);
console.dir(values);
// 배열 길이는 배열 객체의 length 속성(property)을 이용하여 확인할 수 있다.
console.log(values.length);
console.log(values["length"]);
// 배열 데이터를 추가
values.push("검정");
values[values.length] = "하양"; // 마지막 인덱스 + 1에 새로운 것 추가
console.log(values); // ['빨강', '노랑', '파랑', true, 20, '검정', '하양']
values[values.length + 10] = "보라";
console.log(values); // ['빨강', '노랑', '파랑', true, 20, '검정', '하양', <10 empty items>, '보라']
console.dir(values);
console.log(values[10]); // undefined
// 배열의 모든 요소를 순차적으로 가져와서 출력
let values = [ "빨강", "노랑", "파랑", "초록" ];
console.log("방법1. 개별 요소를 직접 참조해서 출력");
console.log(values[0]);
console.log(values[1]);
console.log(values[2]);
console.log(values[3]);
console.log("방법2. for loop를 이용");
for (let i = 0; i < values.length; i++) {
console.log(values[i]);
}
console.log("방법3. for - in를 이용 => 개별 요소의 인덱스를 반환");
for (let index in values) {
console.log(index, values[index]); // index를 사용
}
console.log("방법4. for - of를 이용 => 개별 요소의 값을 반환");
let idx = 0;
for (let value of values) {
console.log(idx++, value); // 값 자체 그대로 사용
}
console.log("방법5-1. forEach => 개별 요소를 콜백 함수로 전달"); // 배열 내장 메서드 사용
// 함수 선언문 형태로 콜백 함수를 정의
function printData(data) {
console.log(data);
}
values.forEach(printData);
console.log("방법5-2. forEach ---");
// 함수 표현식 형태로 콜백 함수를 정의
let printData2 = function (data) {
console.log(data);
}
values.forEach(printData2);
console.log("방법5-3. forEach ---");
// 콜백 함수를 직접 정의
values.forEach(function(data) {
console.log(data);
});
console.log("방법5-4. forEach ---");
// 화살표 함수로 콜백 함수를 정의
values.forEach((data) => {
console.log(data);
});
console.log("방법5-5. forEach ---");
// 화살표 함수로 콜백 함수를 정의 => 화살표 함수 축약
values.forEach(data => console.log(data)); // 가장 간단하다 !
console.log("인덱스와 값을 함께 출력");
values.forEach((data, index) => {
console.log(index, data);
});
console.log("인덱스와 값을 함께 출력 => 화살표 함수 축약");
values.forEach((data, index) => console.log(index, data));
// 객체 선언
let person = {
"name": "홍길동",
'age': 23,
isMarried: false, // 따옴표 생략 시 문자열로 인식. but, JSON에서는 따옴표 생략하면 안 된다.
"favorited colors": [ "red", "blue" ],
hello: function() {
console.log(`안녕하세요, 나는 ${this.name}입니다.`);
}
};
// 객체 항목을 참조 => 객체이름.키이름 또는 객체이름["키이름"]
console.log(person.name);
console.log(person["name"]);
console.log(person["favorite colors"]); // 공백이 있으면 따옴표로 감싸야 한다.
person.hello();
// 객체 항목의 값을 변경
person.name = "김철수";
person.hello(); // 이름 부분이 김철수로 바뀌었다 !
// 객체 속성 추가
person.email = "chulsu@test.com";
person["address"] = "서울시 강남구";
console.log(person); // email, address 추가되었다.
// 객체 선언
let person = {
"name": "홍길동",
'age': 23,
isMarried: false, // 따옴표 생략 시 문자열로 인식. but, JSON에서는 따옴표 생략하면 안 된다.
"favorited colors": [ "red", "blue" ],
hello: function() {
console.log(`안녕하세요, 나는 ${this.name}입니다.`);
}
};
// 객체의 모든 항목을 가져와서 출력
console.log("for-in 구문을 이용 => 객체의 key를 반환")
for (let key in person) {
console.log(key, person[key]);
}
// for-of 구문은 값을 반환하는데 iterable 해야하므로 사용 불가능하다. (순서라는 개념이 있어야 함)
// Uncaught TypeError: person is not iterable
/*
for (let value of person) {
console.log(value);
}
*/
// 객체의 키를 배열로 만들어서 반환
// key들을 배열로 가져와서 순회하면서 추출
for (let key of Object.keys(person)) {
console.log(key, person[key]);
}
function print(key, value) {
console.log(key, value);
}
Object.keys(person).forEach(key => print(key, person[key]));
Object.keys(person).forEach(function(key) {
console.log(key, person[key]);
})
Object.keys(person).forEach(key => {
console.log(key, person[key]);
})
Object.keys(person).forEach(key => console.log(key, person[key]));
객체는 배열과 달리 index가 없기 때문에 key 값을 가져와서 작업해야한다.
하루만에 자바스크립트 A to Z 다 배운 것 같다. 와 너무 빠르다 ㅜ.ㅜ 그래도 예시가 많아서 + 깊게 이해부터 하는 느낌으로 배워서 화살표 함수가 어떻게 줄여지는 지 등등 소름돋는 포인트가 많아서 좋았다.!!!!