개발자입니다
[비트캠프] 24일차(5주차4일) - Javascript(함수: 정의, closure, arrow function) 본문
[비트캠프] 24일차(5주차4일) - Javascript(함수: 정의, closure, arrow function)
끈기JK 2022. 12. 8. 10:30
function
function 함수명 (파라미터, 파라미터, ...) 와 같이 함수를 선언한다.
중괄호 부분을 function body라 한다.
return 있는 것을 표현식이라 한다. (문장(statement) 내에 표현식이 포함된다. 표현식(expression)은 값을 리턴하는 문장이라 한다.)
첫 문장을 function prototype (C/C++) 라 한다.
method signature (java)
함수 호출은 함수 실행시키는 명령이라 한다. 이때 함수명 내부 값들을 아규먼트(argument)라 한다.
함수 - 정의
자바스크립트 함수
1) 데이터 타입이 없기 때문에 함수의 리턴 타입을 지정하지 않는다.
2) function 키워드로 시작한다.
3) 파라미터는 괄호 안에 선언한다.
파라미터는 var을 붙이지 않는다. 붙이면 안된다.
파라미터가 없어도 빈 괄호를 지정해야 한다.
4) 값을 리턴할 때는 return 키워드를 사용한다.
문법:
function 함수명(파라미터, 파라미터, ...) {함수몸체}
function f1() { // 파라미터가 없는 함수
console.log("안녕!");
}
function f2() { // 값을 리턴하는 함수
return "안녕2!";
}
function f3(a, b) { // 파라미터 있는 함수
// 물론 파라미터도 로컬 변수이기 때문에 함수 호출이 끝나면 제거된다.
console.log(a, "+", b, "=", (a + b));
}
function f4(a, b) { // 파라미터도 있고, 리턴 값도 있는 함수
return a + b;
}
함수 - 정의2
자바스크립트 함수 정의
function 함수명(파라미터, 파라미터, ...) {함수몸체}
function f1() { // 파라미터가 없는 함수
console.log("안녕!");
}
// 자바스크립트 함수 호출
// 문법1)
// 함수명(아규먼트, 아규먼트, ...);
f1();
console.log("---------------------------");
// 문법2)
// 함수명(객체주소, 아규먼트, 아규먼트, ...);
//
f1.call();
아규먼트와 파라미터
함수 정의에서 파라미터가 2개라도 사용시 1개만 입력하면 1개만 사용한다.
arguments
- 모든 함수에 들어있는 Built-in 배열
- 아규먼트 모두를 배열에 보관
함수 정의에서 파라미터 2개이고 사용시 2개 입력하면 2개를 모두 다 사용한다.
함수 정의에서 파라미터 2개를 받는데 사용시 4개 입력하면 2개만 사용한다.
4개 입력한 것 모두 arguments라는 built-in 배열에 저장된다.
함수 - 함수의 파라미터와 아규먼트
자바스크립트 함수를 호출할 때 아규먼트의 개수는 함수에 정의된 파라미터 개수와 일치하지 않아도 된다.
아규먼트(argument)? 함수를 호출할 때 전달하는 값.
파라미터(parameter)? 함수를 호출할 때 전달한 값을 보관하는 함수의 로컬 변수.
function f1(a) {
console.log(a);
}
f1(100); // 한 개의 파라미터에 저장할 값을 한 개 전달한다.
// 그런데 자바스크립트는 파라미터의 개수와 상관없이 값을 마음대로 전달할 수 있다.
f1();
// 파라미터 개수보다 더 많은 값을 전달해도 된다.
f1(100, 200, 300, 400);
// 그러면 파라미터 개수를 초과하여 전달한 값은 어디로?
// => 다음 예제를 보라!
함수 - 함수 오버로딩?
같은 이름의 함수를 여러 개 선언
=> 문법 오류가 아니다.
=> 단지 기존 함수를 대체한다.
=> 따라서 자바스크립트는 자바 또는 C++ 언어에서 제공하는 "메서드 오버로딩"을 지원하지 않는다.
function f1(a) {
console.log("f1(a)==>", a);
}
function f1() {
console.log("f1()==>", "호출됨!")
}
function f1(a, b, c) {
console.log("f1(a,b,c)==>", a, b, c)
}
f1(100);
f1();
f1(200, 300, 400);
함수 - 함수 아규먼트와 함수 내장 변수 arguments
자바스크립트의 함수는 함수를 호출할 때 전달한 값들을 보관하는 배열과 유사한 변수를 내장하고 있다.
=> 그 내장 변수의 이름은 "arguments" 이다.
function f1(a) {
console.log("a =", a);
console.log(arguments); // arguments 에는 넘어 오는 모든 값이 저장되어 있다.
}
f1();
console.log("----------------");
f1(100);
console.log("----------------");
f1(100, 200, 300, 400);
console.log("----------------");
function f2(a) {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
f2(100, 200, 300, 400);
console.log("----------------");
function f3(a) {
for (var value of arguments) {
console.log(value);
}
}
f3(100, 200, 300, 400);
console.log("----------------");
function f4(a) {
for (var i in arguments) {
console.log(arguments[i]);
}
}
f4(100, 200, 300, 400);
console.log("----------------");
function f5(a) {
// arguments 내장 변수는 Array() 초기화시킨 배열 객체가 아니기 때문에
// forEach()라는 함수가 없다.
arguments.forEach(function (value) {
console.log(value);
});
}
f5(100, 200, 300, 400);
console.log("----------------");
주의!
=> 자바스크립트는 파라미터의 개수와 상관없이 아규먼트를 넘길 수 있기 때문에
자바의 오버로딩 문법이 자바스크립트에서는 없다.
=> 자바는 메서드를 찾을 때 값의 타입과 개수를 이용하여 찾는다.
그러나 자바스크립트는 값의 타입이 없고 아규먼트의 개수도 의미가 없다.
그래서 자바스크립트는 같은 이름을 가진 함수를 여러 개 만들 수 없다.
함수 - 함수와 window 객체
함수도 변수와 같이 자동으로 window 객체에 소속된다.
함수나 변수나 객체 입장에서는 그냥 프로퍼티이다.
따라서 프로퍼티 값을 가리키는 다음 문법을 그대로 사용할 수 있다.
=> 객체["프로퍼티명"]
=> 객체['프로퍼티명']
함수의 주소를 값처럼 다룰 수 있다.
즉 다른 변수에 저장하여 사용할 수 있다.
var ohora = window.f1;
ohora("안녕4"); // 함수 주소를 갖고 있는 변수는 함수처럼 사용할 수 있다.
함수 - 함수와 레퍼런스
함수는 그 자체로 객체이다.
=> 즉 프로퍼티와 코드를 포함하고 있는 객체이다.
object = properties(값, 함수, 객체)
function = object + function body(함수 코드)
=> 객체는 주소가 있다.
따라서 함수도 주소가 있다.
=> 함수의 주소는 함수 이름을 가진 변수에 저장된다.
function f1() {
console.log("안녕!");
}
var f2;
f2 = f1; // f1에 저장된 함수 주소를 f2에 복사한다.
// 복사한 함수 주소를 가지고 원래의 함수처럼 사용할 수 있다.
f2();
window.f2();
// 함수도 객체이기 때문에 객체처럼 사용할 수 있다.
f1.age = 20;
f1.working = true;
f1.plus = function (a, b) { return a + b; }
console.log(f1.age, f1.working); // OK!
console.log(f1.plus(100, 200)); // OK!
함수와 레퍼런스
function f1() { - } 을 선언하면 메모리에 함수가 저장되고 f1에 이 함수의 주소 값 200이 들어간다.
f1.age, f1. working 이런식으로 함수 안에 value를 저장할 수 있다.
f1.plus = function(a, b) { - } 를 하면 ① 함수 객체 생성하고 ② 함수 객체 주소 리턴 한다. 즉, plus에 함수 주소가 들어간다.
var f2 = f1; 하면 f1 의 주소가 f2 에 들어가서 같은 함수를 가리키게 된다.
함수 - 익명 함수
함수 이름없이 함수를 정의할 수 있다.
=> 이름없는 함수를 정의한 후 사용하려면 그 함수의 주소를 어딘가에 저장해야 한다.
일반적인 문법으로 함수를 정의할 때는 함수의 주소를 저장할 수 있는 변수가 미리 지정된다.
function f0(a) {
console.log(a + "님, 안녕!");
}
f0("임꺽정");
console.log("---------------------");
var f1;
f1 = function (a) {
console.log(a + "님, 안녕!");
};
// 함수 주소가 저장되어 있는 변수는 함수처럼 사용하면 된다.
f1("홍길동"); // 정의한 함수를 실행시키는 명령 => "함수 호출(call)"
window.f1("홍길동");
주의!
=> 자바스크립트 변수의 타입은 고정형이 아니다.
=> 변수에 담는 값에 따라 용도가 결정된다.
=> 문자열을 담으면 문자열과 관련된 프로퍼티와 메서드를 사용할 수 있고,
=> 숫자를 담으면 숫자와 관련된 프로퍼티와 메서드를 사용할 수 있다.
=> 객체를 담으면 객체처럼 쓸 수 있다.
=> 함수를 담으면 함수처럼 쓸 수 있다.
=> 그래서 dynamic type binding 이라고 한다.
// 예) a 변수에 문자열을 저장하면 문자열을 다루는 함수를 사용할 수 있다.
let a = "가나다";
console.log(a.indexOf("나"));
// 예) a 변수에 배열을 저장하면 배열을 다루는 함수를 사용할 수 있다.
a = ["100", "200", "300", "400", "500"];
let a2 = a.slice(1, 3)
console.log(a2)
// 즉 변수에 어떤 타입의 값을 저장하느냐에 따라 그 변수에 묶이는 함수가 달라진다.
// => dynamic type binding
함수 - 함수 호이스팅(hoisting)
함수도 변수처럼 함수 정의를 맨 먼저 실행한다.
=> 즉 script 태그를 실행할 때 함수 정의가 있으면 제일 먼저 실행한다.
=> 이렇게 함수를 정의한 코드를 맨 위로 끌어올린다 하여 "함수 호이스팅(hoisting)"이라 한다.
함수를 정의하기 전에 사용한다.
그런데도 오류가 발생하지 않는 이유는 함수 정의가 먼저 실행되기 때문이다.
이전 스크립트 태그에서 정의한 함수나 변수가 window 객체에 보관되는 글로벌 함수나 변수라면,
그 이후의 스크립트 태그 안에서 그대로 사용할 수 있다.
현재 스크립트 태그가 아닌 다음 스크립트 태그에서 정의한 함수는
호이스팅 대상이 아니다.
호이스팅은 그 script 태그를 실행할 때 수행된다.
따라서 아래에 f2() 함수는 아직 정의된 상태가 아니기 때문에 호출할 수 없다.
함수 - 함수 호이스팅(hoisting)과 익명 함수
변수 선언과 그 변수의 값을 초기화시키는 할당문이 함께 있을 경우
호이스팅 대상은 변수 선언만이 그 대상이 된다.
var v1 = "홍길동"; // 변수 선언은 호이스팅 규칙에 따라 먼저 실행된다.
// 그러나 값을 할당하는 = 연산자는 현재 위치에 도달할 때 실행된다.
함수 - 아규먼트로 함수를 전달하기
함수는 객체이기 때문에 주소를 주고 받을 수 있다.
함수 객체를 아규먼트로 넘길 때
보통 파라미터 이름을 fn 또는 cb(callback)로 한다.
"콜백(callback) 함수"
=> 직접 호출하는 것이 아니라 다른 함수에게 파라미터 값으로 전달하여
호출되도록 만드는 함수.
function play(cb) {
console.log("계산 결과 =", cb(100, 200)); // 콜백 함수
}
function plus(a, b) { return a + b; }
function minus(a, b) { return a - b; }
play(plus); // 호출될 함수를 파라미터로 넘긴다. 그러면 play()가 호출해 줄 것이다.
play(minus);
// 생각해 볼 문제?
// 다음은 콜백 메서드인가? 아닌가?
function play2(v1, v2, op) {
if (op == "+") {
console.log(plus(v1, v2)); // 파라미터로 받은 함수를 호출하는 것이 아니기 때문에 콜백 함수가 아니다.
} else if (op == "-") {
console.log(minus(v1, v2)); // 파라미터로 받은 함수를 호출하는 것이 아니기 때문에 콜백 함수가 아니다.
} else {
console.log("해당 연산을 지원하지 않습니다.");
}
}
play2(100, 200, "+");
play2(100, 200, "-");
함수 - 함수 리턴하기
함수는 객체이기 때문에 주소를 주고 받을 수 있다.
함수 안에서 함수를 만들어 리턴할 수 있다.
function createInterestCalculator(type) {
switch (type) {
case "보통예금":
return function(money, month) {return money + (money * 0.0011 * month);};
case "정기예금":
return function(money, month) {return money + (money * 0.0014 * month);};
default:
return function(money, month) {return money;};
}
}
// createInterestCalculator() 함수가 리턴하는 것은 내부에서 정의한 함수의 주소이다.
// => 이렇게 함수 안에서 정의한 함수를 '클로저(closure)'라 부른다.
var fn = createInterestCalculator("정기예금");
console.log("100억 7달 =", fn(10000000000, 7));
closure
원래는 함수 호출이 끝나면 함수를 실행하는 동안 만든 모든 로컬 변수는 폐기된다.
var test1 = createGreeting("홍길동"); 하면 test1에 함수 주소 200이 들어간다.
메모리에 함수가 저장되고 몸체에 console.log(message); 문장이 입력된다.
여기서 문제 발생! message는 바깥 함수의 로컬 변수다. 그러나 현재 이 변수는 없다! 그럼 어떻게 할 것인가?
closure : 바깥 함수의 로컬 변수를 사용할 때 발생하는 문제 해결법!
closure를 만들때 클로저가 사용하는 바깥 함수의 로컬 변수가 있다면, 클로저의 별도 메모리에 복제해 준다.
test1() 가 실행될때 message는 복제해준 변수를 가리킨다. 그래서 바깥 함수의 message 변수가 없어도 상관없다!
함수 - 클로저(closure)와 바깥 함수의 로컬 변수
함수 안에 정의된 함수를 보통 클로저(closure)라 부른다.
=> inner function, nested function 이라고도 표현한다.
=> 클로저의 핵심 개념
closure에서 바깥 함수의 로컬 변수를 사용할 때, 바깥 함수의 호출이 끝나면 해당 로컬 변수가 제거되기 때문에 클로저는 존재하지 않는 변수를 사용하는 상황이 발생한다. 그래서 이런 경우를 방지하고자, 클로저에서 사용하는 바깥 함수의 로컬 변수는 클로저의 별도 메모리에 복제된다.
function createGreeting(name) {
var message = name + "님 반갑습니다!";
// 클로저 만들기
var f = function () { // function f() 이렇게는 안된다.
console.log(message); // 클로저에서 바깥 함수의 변수를 사용하기
// 클로저가 바깥 함수의 로컬 변수를 사용하면,
// 내부적으로 클로저 메모리에 같은 이름으로 그 값을 복제해 둔다.
// 따라서 바깥 함수의 호출이 끝나 로컬 변수가 사라지더라도 영향을 받지 않는다.
};
return f;
}
var test1 = createGreeting("홍길동");
var test2 = createGreeting("임꺽정");
test1();
test2();
function closureMaker(fnType, count) { // 잊지말라 파라미터도 로컬 변수이다.
switch (fnType) {
case "sum":
return function() {
// 이렇게 클로저를 정의하는 순간 클로저가 사용하는 바깥 함수의 로컬 변수 count는
// 클로저가 관리하는 별도의 메모리에 복제된다.
// 따라서 바깥 함수의 실행이 끝나 그 로컬 변수가 사라지더라도
// 클로저는 복제된 변수를 계속 사용할 수 있다.
var sum = 0;
for (var i = 1; i <= count; i++) {
sum += i;
}
console.log("합계 =", sum);
};
case "factorial":
return function() {
var sum = 1;
for (var i = 1; i <= count; i++) {
sum *= i;
}
console.log("팩토리얼 =", sum);
};
default:
return function() {
console.log("해당 연산을 지원하지 않습니다.");
};
}
}
var fn1 = closureMaker("sum", 10);
var fn2 = closureMaker("factorial", 5);
fn1();
fn2();
closure 사용
var test1 = createGreeting("홍길동"); 하게 되면 익명 함수가 생성되고 test1 변수는 그 주소를 가리킨다.
이때 closure가 복제한 바깥함수의 로컬 변수를 두는 곳이 생성된다.
test1 함수 몸체에 console.log(message) 가 들어있고 이 message가 사용하는 것은 별도 복제한 곳을 가리킨다.
test1을 호출하게 되면 함수 몸체의 console.log(message) 에 있는 message가 별도 복제한 closure의 message를 가리킨다.
test2도 마찬가지다.
closure 사용 II
① "sum", 10 을 인자로 closureMaker() 에 넘기게 되면 fnType = "sum", count = 10 이 들어간다.
② return 으로 합계 계산 closure의 주소 200이 반환 되고 fn1에 200이 들어간다. 바깥 함수의 로컬 변수를 복제한 것인 count에 10이 들어간다.
함수 - 클로저(closure)를 객체에 담아 리턴하기
function createBox() {
var value;
var box = new Object();
box.setValue = function (v) {
// 이 클로저가 사용하는 value 변수는 바깥 함수의 로컬 변수이기 때문에
// 클로저 메모리로 복사해둔다.
value = v;
};
box.getValue = function () {
// 함수가 호출될 때 함께 생성된 클로저는 메모리를 공유한다.
// 따라서 setValue()와 getValue()가 사용하는 value 변수는
// 같은 변수이다.
return value;
};
return box;
}
var box1 = createBox();
var box2 = createBox();
box1.setValue(100);
box2.setValue(200);
console.log(box1.getValue());
console.log(box2.getValue());
console.log(box1.value); // 클로저가 복제한 변수는 클로저를 통해서만 접근할 수 있다.
console.log(box2.value); // 클로저가 복제한 변수는 클로저를 통해서만 접근할 수 있다.
closure 사용 III
① "factorial", 5 를 인자로 closureMaker() 에 전달하면 fnType = "factorial", count = 5 가 들어간다.
② return 으로 팩토리얼 계산 closure의 주소 300 이 반환되고 fn2에 300이 들어간다. 바깥 함수의 로컬 변수를 복제한 것인 count에 5 가 들어간다.
① call 로 createBox() 를 호출하고 var value; 가 정의된다.
② 객체 생성을 하고 7230 주소에 setValue(주소 200), getValue(주소 300) 함수가 저장된다. box1 에 주소 7230 가 저장된다. closure로 주소 200에 value = v 가 저장되고 closure 주소 300에 return value; 가 저장된다. 이로 인해 메모리에 value : 100이 저장된다.
한 번 호출에 생성된 closure 들은 메모리를 공유한다.
① call 로 createBox() 를 호출하고 var value; 가 정의된다.
② 객체 생성을 하고 8030 주소에 setValue(주소 730), getValue(주소 430) 함수가 저장된다. box2 에 주소 8030 가 저장된다. closure로 주소 730에 value = v 가 저장되고 closure 주소 430에 return value; 가 저장된다. 이로 인해 메모리에 value : 200이 저장된다.
한 번 호출에 생성된 closure 들은 메모리를 공유한다.
함수 - 애로우(arrow) 함수
익명 함수를 정의할 때 arrow function 문법을 사용할 수 있다.
문법:
(파라미터,파라미터,...) => 문장
(파라미터,파라미터,...) => {문장1; 문장2;}
console.log( ) 괄호에 함수 주소가 들어가고 이는 function() {return "안녕"} 를 가리킨다. 여기에 () 를 붙여 함수를 호출한다.
arrow function도 동일하게 함수 주소가 들어가고 이는 () => "안녕" 를 가리킨다. 여기에 () 를 붙여 함수를 호출한다.
// 일반 함수 정의
function f0() {
return "안녕";
}
console.log(f0());
// 익명 함수 정의
var f1 = function () {
return "안녕";
};
console.log(f1());
애로우(arrow ) 함수 : 초간단 함수 정의 문법
1) function 키워드를 제거한다.
2) 대신 파라미터 블록과 코드 블록 사이에 화살표를 추가한다.
3) 다른 언어에서는 람다(lambda)라고 부른다.
var f2 = () => {
return "안녕";
};
console.log(f2());
4) 한 문장만 있을 때는 중괄호를 제거할 수 있다.
5) 그 한 문장이 리턴 문장일 경우 return을 반드시 생략해야 한다.
그리고 문장의 끝을 나타내는 세미콜론을 제거한다.
(한 문장 밖에 없으니까 가능한 한 줄로 표현하라!)
var f3 = () => "안녕";
console.log(f3());
console.log("-----------------");
// 익명 함수 정의 후 바로 호출하는 방법
console.log((function () {
return "안녕";
})());
// 애로우 함수 정의 후 바로 호출하는 방법
console.log((() => "안녕")());
console.log("-----------------");
console.log((function (a, b) {
return a + b;
})(100, 200));
console.log(((a, b) => a + b)(111, 222));
console.log("-----------------");
(function (name) {
console.log(name + "님 반가워요!")
})("홍길동");
console.log("-----------------");
((name) => console.log(name + "님 반가워요!"))("홍길동");
var x = function (name) {
console.log(name + "님 반가워요!")
}
x("홍길동");
function x2(name) {
console.log(name + "님 반가워요!")
}
x2("홍길동");
console.log("-----------------");
function f0() {
console.log("값을 리턴하지 않는다.");
}
f0();
var f1 = function() {
console.log("값을 리턴하지 않는다.");
};
f1();
var f2 = () => {
console.log("값을 리턴하지 않는다.");
};
f2();
var f3 = () => console.log("값을 리턴하지 않는다.");
f3(); // OK
// 만약에 arrow 함수가 값을 리턴하지 않는다면?
console.log(f3()); // 값을 리턴하지 않는 함수에 대해 리턴 값을 출력하려고 한다면 undefined가 된다.
function f0(a, b) {
return a + b;
}
console.log(f0(1, 2));
var f1 = function(a, b) {
return a + b;
};
console.log(f1(10, 20));
var f2 = (a, b) => {
return a + b;
};
console.log(f2(100, 200));
var f3 = (a, b) => a + b;
console.log(f3(1000, 2000));
함수 - 애로우(arrow) 함수를 아규먼트로 전달하기
arrow 함수이든 일반 함수이든 결국 같은 함수이다.
function play(fn) {
console.log("함수가 리턴한 값 =", fn(100, 200));
}
function plus(a, b) {
return a + b;
}
//이렇게 정식으로 정의된 함수의 주소를 아규먼트로 넘길 수 있다.
//그러면 play()는 그 함수를 호출하여 리턴 값을 출력할 것이다.
play(plus);
//또는 다음과 같이 익명 함수를 정의하여 바로 아규먼트로 넘길 수 있을 것이다.
play(function(a, b) {return a - b;});
//또한 arrow function을 정의하여 바로 아규먼트로 넘길 수 있다.
play((a, b) => a * b);
//물론 arrow function이 여러 문장으로 구성된 경우도 있을 것이다.
play((a, b) => {
var sum = 0;
for (var i = a; i <= b; i++) {
sum += i;
}
return sum;
});
[Quiz]
- forEach() 함수 정의를 보고,
- 실행 결과가 다음과 같게 출력하도록 나머지 코드를 작성하시오.
0: 100
1: 홍길동
2: 3.14
3: 임꺽정
4: true
let arr = [100, "홍길동", 3.14, "임꺽정", true];
function forEach(a, cb) {
for (let i = 0; i < a.length; i++) {
cb(i, a[i]);
}
}
// 방법 1
function prnt(index, value) {
console.log(`${index}: ${value}`);
}
forEach(arr, prnt)
console.log("---------------------")
// 방법 2
forEach(arr, function (index, value) { console.log(`${index}: ${value}`) });
console.log("---------------------")
// 방법 3
forEach(arr, (index, value) => console.log(`${index}: ${value}`));
console.log("---------------------")
// 방법 4
forEach([100, "홍길동", 3.14, "임꺽정", true],
(index, value) => console.log(`${index}: ${value}`));
배열의 forEach() 사용하기
let arr = [100, "홍길동", 3.14, "임꺽정", true];
// 배열에서 값 꺼내기
// 방법 1
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
console.log("------------------------");
// 방법 2
arr.forEach(myFunc)
function myFunc() {
console.log("okok!!");
}
console.log("------------------------");
arr.forEach(myFunc2)
function myFunc2(value, index) {
console.log("==>", value, index);
}
console.log("------------------------");
arr.forEach(function (value, index) {
console.log("--->", value, index);
})
console.log("------------------------");
arr.forEach((value, index) => console.log("====>", value, index))
조언
*이해되지 않으면 그냥 치고 익숙해질 때까지 반복하라.
과제
오늘 배운것 처음부터 끝까지 쳐보기. 익숙해질 때까지
'네이버클라우드 AIaaS 개발자 양성과정 1기 > Javascript' 카테고리의 다른 글
[비트캠프] 26일차(6주차1일) - Javascript(객체, 프로퍼티, 생성자) (0) | 2022.12.12 |
---|---|
[비트캠프] 25일차(5주차5일) - Javascript(함수, 비동기, 주요함수, JSON) (0) | 2022.12.09 |
[비트캠프] 23일차(5주차3일) - Javascript(배열, 반복문, destructuring) (0) | 2022.12.07 |
[비트캠프] 22일차(5주차2일) - Javascript(연산자, 조건문) (0) | 2022.12.06 |
[비트캠프] 21일차(5주차1일) - Javascript(변수, 배열) (0) | 2022.12.05 |