19-1. 함수의 기본
19-2. 매개변수의 기본값
19-3. 콜백 함수 (callback function)
19-4. 원시값과 객체값
20-1. 객체의 추가
20-2. 객체의 삭제
20-3. 동적으로 속성에 접근
20-4. 객체 생성 함수 만들기
21-1. static
21-2. private (#)
23-1. Number 타입 관련 내용
23-2. String 타입 관련 내용
19. 함수 작성법
19-1. 함수의 기본
function sum(num1, num2) { console.log('sum() 호출!'); return num1 + num2 } const result = sum(10, 3); console.log(result); // 13 |
const add = sum; console.log(sum(10,3)); // 13 console.log(add(10,3)); // 13 |
조건식이 조건을 만족하지 않는 경우, 도입부분에서 함수를 미리 종료(return)시키는 것이 효율적.
function print(num){ if(num <= 0) return; console.log(num); } print(10); // 콘솔에 정상적으로 출력. print(-5); // 콘솔에 출력되지 않음. |
19-2. 매개변수의 기본값
매개변수의 기본값 : undefined.
undefined와의 연산 → NaN이 출력.
arguments 함수에 전달된 인수에 해당하는 Array형태의 객체. 함수를 호출할 때 전달된 모든 인수를 담고 있는 객체. 배열과 유사한 형태를 가지고 있지만, 배열은 아님. 따라서 배열에서 사용 가능한 메소드나 속성은 사용할 수 없음. 하지만 arguments 객체를 배열로 변환하면 배열에서 사용 가능한 메소드와 속성을 사용할 수 있음. |
function total (num1=0, num2=0) { console.log(num1); // 0 console.log(num2); // 0 console.log('arguments: ', arguments); // arguments: Arguments(0) 출력. console.log('arguments[1]: ', arguments[1]); // arguments[1]: undefined 출력. return num1 + num2; } console.log(total()); console.log(total(10,3)); |
19-3. 콜백 함수 (callback function)
다른 함수의 인자로 전달되어 실행되는 함수.
const calc_add=(a,b) => a+b; const calc_multiply=(a,b) => a*b; console.log(calc_add(10,5)); // 15 console.log(calc_multiply(10,5)); // 50 function calculator(num1, num2, action) { if (num1 < 0 || num2 < 0) return; // num1이 0보다 작거나(|| : or), num2가 0보다 작은 경우 return const result = action(num1, num2); console.log(result); return result; } calculator(4, 2, calc_add); // 6 //calc_add()로 표현하지 않음. '메모리주소'만 가져오는 경우이기 떄문. calculator(4, 2, calc_multiply); // 8 |
19-4. 원시값과 객체값
원시값: 값에 의한 복사
객체값: 참조에 의한 복사(메모리 주소)
function display(num) { num = 10; console.log(num); } const value = 5; display(value); // 10 // 110줄의 5가 105로 넘어가지만, num=10이 덮어씌워져서 출력. console.log(value); // 5 // 110줄의 5가 그대로 내려와서 출력. function displayObj(obj){ obj.age = 13; // 객체의 값을 변경하는 것은 좋지 못한 코드. 123줄이 대안이 될 수 있음. console.log(obj); } const dog = {name:'루시', age:14}; // displayObj(dog); // {name:'루시', age:13} 119줄의 dog이 114로 넘어가지만, obj.age=13이 덮어씌워져서 출력. console.log(dog); // {name:'루시', age:14} function changeAge(obj){ // 객체의 값을 변경하는 것은 좋지 못한 코드. 해당 함수를 작성하는 것이 대안이 될 수 있음. return {...obj, age:13} // 원본 코드를 수정하지 않고, 따로 함수를 만들어서 덮어씌우는 것을 아는 것이 중요함. } dog2 = changeAge(dog); console.log(dog2); |
20. 객체 활용법
let dog = { name:'루시', age:14, 'dog-weight':3.5, // 객체의 이름에 특수문자를 넣고 싶은 경우, 이름에 따옴표를 삽입해야 함. ['dog-height']:0.8 // (따옴표+대괄호도 상관없음.) } console.log(dog.name); console.log(dog['age']); |
20-1. 객체의 추가
dog.family = '포메라니안'; console.log(dog); |
20-2. 객체의 삭제
delete dog['dog-height'] console.log(dog['dog-height']) // 삭제 후 확인 시 undefined가 출력. |
20-3. 동적으로 속성에 접근
function getValue(obj, key) { // dog, name return obj[key]; } console.log(getValue(dog, 'name')); // '루시' 출력. // dog 객체의 name key를 가져오고 싶은 경우 사용. function addKey(obj, key, value) { // 새로운 property를 만드는 함수를 생성. obj[key] = value; } // 삭제했던 dog-height를 다시 추가하려는 경우. addKey(dog, 'dog-height', 0.7); console.log(dog); // object에서 key를 삭제하려는 경우. function deleteKey(obj, key) { delete obj[key]; } // dog-height를 다시 삭제하려는 경우. deleteKey(dog, 'dog-height'); console.log(dog); |
20-4. 객체 생성 함수 만들기
const x = 0; const y = 0; const coord = {x, y}; // 중괄호로 묶어버리면 객체가 됨. console.log(coord); function makeObj(name, age){ return {name, age} // 중괄호로 객체를 만들어 반환해주는 함수. } console.log(makeObj('apple', 20)); // 생성된 객체의 확인. const apple = { name: 'apple', display: function(){ // display 메소드를 이용해서 이모지가 찍히도록 함. console.log(`${this.name}:🍎`); } } const orange = { name: 'orange', display: function(){ // display 메소드를 이용해서 이모지가 찍히도록 함. console.log(`${this.name}:🍊`); } } console.log(apple); // name: "apple" apple.display(); // apple:🍎 console.log(orange); // name: "orange" orange.display(); // orange:🍊 |
21. 클래스 심화
21-1. static
클래스의 인스턴스가 아닌 클래스 자체에 속하는 정적 속성. 즉, 클래스의 모든 인스턴스가 공유하는 속성.
property 및 method의 생성이 가능.
class 레벨의 method(static)에서는 this를 참조할 수 없음.
(class 자체에 바인딩되어 있기 때문에 class 인스턴스와 관련된 데이터를 참조할 수 없음.)
class Fruit { static count_fruits = 10; // static property의 생성 constructor(name, emoji){ // constructor: 생성자 this.name = name; this.emoji = emoji; } display = () => { console.log(`${this.name}: ${this.emoji}`); } static makeBanana(){ // static으로 객체도 새로 생성할 수 있음. return new Fruit('banana', '🍌'); } } const apple = new Fruit('apple','🍎'); // apple이라는 객체를 생성 const orange = new Fruit('orange','🍊'); // orange라는 객체를 생성 console.log(apple); // Fruit 객체의 apple data(name, emoji)가 출력 console.log(apple.name); console.log(orange); // Fruit 객체의 orange data(name, emoji)가 출력 console.log(orange.name); console.log(Fruit.count_fruits); // 객체를 생성하지 않아도 정적 property의 출력이 가능함. const banana = Fruit.makeBanana(); // static을 이용하여 객체를 생성. console.log(banana); // Fruit 객체의 banana data(name, emoji)가 출력 |
21-2. private (#)
class Dog { #name; #color; |
#name과 #color은 비공개(private) 필드로 선언되어 있음. → 클래스 내부에서만 접근이 가능함.
이것은 클래스 외부에서는 Rucy.#name과 같이 접근이 불가능하다는 것을 의미함.
constructor(name, color){ this.#name = name; this.#color = color; } // setter 메서드는 set 키워드를 사용하여 정의되며, 해당 클래스의 인스턴스에 새로운 값을 할당할 때 사용됨. // property명과 꼭 일치할 필요는 없음 (name =/= #name) set name(value){ console.log('set', value); this.#name = value; } get name(){ return `이름:${this.#name}`; } run = () => { console.log(`${this.#color} 색상의 강아지인 ${this.#name}이 달립니다.`) } #eat = () => { console.log(`${this.#name}은 먹습니다.`); // 이대로 작성한 후 Rucy.eat();을 실행하면 오류가 발생. } colorEat = () => { // #eat 메소드를 정상적으로 사용하기 위해서는 colorEat이라는 새로운 메소드를 작성하여 안에 포함시켜서 사용해야 함. this.#eat(); } } const Rucy = new Dog('루시', 'white'); console.log(Rucy); // Rucy.#name = '루시' // private (#)로 접근을 막아둔 상황. console.log(Rucy); Rucy.name = '류씨'; // set 류씨 출력. console.log(Rucy); console.log(Rucy.name); // getter 메소드를 이용. '이름:류씨' 출력 Rucy.run(); // 화살표함수를 사용한 run 메소드 이용. 'white 색상의 강아지인 류씨이 달립니다.' 출력 // Rucy.eat(); Rucy.colorEat(); // '류씨은 먹습니다.'' 출력 |
22. 상속의 활용
B class를 상속받는 A class class A extends B |
예) Animal class를 상속받는 Dog class와 Cat class 및 함수 작성.
class Animal { // 부모 class인 Animal class constructor (color) { // 'color'의 생성자 생성. this.color = color; } eat() { console.log('먹는다.'); // eat()함수는 '먹는다' 출력. } sleep() { console.log('잔다.'); // sleep()함수는 '잔다' 출력. } } class Dog extends Animal { // Animal class를 상속받는 Dog class. play() { console.log('논다.'); // play()함수는 '논다' 출력. } } const Rucy = new Dog('white'); console.log(Rucy); // Dog [color : 'white'] Rucy.eat(); // '먹는다' Rucy.sleep(); // '잔다' Rucy.play(); // '논다' class Cat extends Animal { // Animal class를 상속받는 Cat class. constructor(color, name) { // 'color', 'name'의 생성자 생성. super(color); this.name = name; } eat() { // Animal class의 eat()을 오버라이딩 console.log('맛있게 먹는다.') } } const Horang = new Cat('black', '호랑'); console.log(Horang); // Cat [color: 'black', name: '호랑'] Horang.eat(); // 맛있게 먹는다. 자식요소의 eat()이 부모요소의 eat() 보다 우선순위가 높기 때문. |
super() 하위 클래스에서 '상위 클래스의 생성자 함수를 호출' 하는 특별한 키워드. 클래스 상속에서 하위 클래스는 상위 클래스의 속성과 메소드를 상속받음. 하지만 하위 클래스에서 생성자 함수를 정의할 때, 상위 클래스의 생성자 함수는 자동으로 호출되지 않음. 이 때, super() 키워드를 사용하여 상위 클래스의 생성자 함수를 명시적으로 호출할 수 있음. |
오버라이딩(overriding) 하위 클래스에서 상위 클래스에 이미 정의된 메소드를 재정의하는 것 |
23. Wrapper 클래스
원시 타입(Primitive Types)을 객체처럼 다룰 수 있도록 해주는 객체.
원시타입(Primitive Types) number, bigint, string, boolean, null, undefined, symbol 각각 값이 불변(immutable)하며 객체가 아닌 값 자체. method와 property가 존재하지 않는 데이터. 원시 타입의 변수를 다른 변수에 할당하면 값이 복사되어 전달됨. new 키워드를 이용하여 원시 타입을 wrapper 객체로 생성할 수 있으나, 주로 사용하는 방법은 아님. |
Wrapper 클래스의 종류와 해당하는 원시 타입.
Number(): 숫자(Number) 타입의 값
String(): 문자열(String) 타입의 값
Boolean(): 불리언(Boolean) 타입의 값
Symbol(): 심볼(Symbol) 타입의 값 (ES6부터 추가됨)
예) let a = new String('apple');
동등 연산자 (===)
'기본 타입으로 생성된 변수'와 'new 키워드를 사용하여 명시적으로 생성된 Wrapper 객체'는 서로 다른 타입.
예)
'JavaScript' === 'JavaScript' // true 'JavaScript' === new String('JavaScript') // false 10 === new Number(10) // false let num1 = 10; let num2 = new Number(10); num1 === num2; // false |
23-1. Number 타입 관련 내용
toString()
number type을 string type으로 변환해주는 메서드.
예)
const num = 10; // 원시타입의 number. console.log(typeof(num)); // number console.log(num.toString()); // 10 console.log(typeof(num.toString())); // string console.log(typeof(num)); // number |
toExponential()
num을 10의 n승으로 변환해주는 메서드.
예)
const x = 102; console.log(x.toExponential()); // 1.02e+2 |
toFixed()
num을 반올림한 후 문자열로 바꾸어주는 메서드.
예)
const x2 = 1234.12; console.log(x2.toFixed()); // 1234 |
toLocaleString()
num을 특정 국가의 문자형으로 바꾸어주는 메서드.(로컬형식의 문자형으로 변환)
예)
console.log(x2.toLocaleString('ar-EG')); |
globalThis
전역 객체(여기서는 Window)를 출력할 수 있는 키워드.
console.log(globalThis); // Window 객체가 출력 |
엡실론(epsilon) 값 컴퓨터에서 부동소수점을 다룰 때 발생하는 근사 오차(approximation error)를 나타내는 값. 예) const x3 = 0.1+0.2-0.2; console.log(x3); // 0.1이 아니라, 근사오차인 엡실론값이 반영되어 '0.10000000000000003'이 출력. |
23-2. String 타입 관련 내용
URI (Uniform Resource Identifier) 인터넷에서 특정 자원을 식별하고 위치를 지정하는 표준화된 방식을 의미. 아스키 문자로만 구성. 한글이나 특수문자는 이스케이프 처리(인코딩)가 필요. URI는 URL (Uniform Resource Locator)과 URN (Uniform Resource Name) 두 가지 형태로 구성됨. URL: 인터넷 상에서 특정 자원의 위치를 나타내며, "http://example.com" 과 같은 형식으로 표현. URN: 인터넷 상에서 특정 자원의 이름을 나타내며, "urn:example:document" 와 같은 형식으로 표현. |
encoded
일련의 문자열을 다른 형태나 인코딩으로 변환하는 작업
decoded
인코딩의 반대 작업이며, 인코딩된 문자열을 원래의 형태로 돌리는 것
예)
const URL = 'https://코리아아이티아카데미.com'; const encoded = encodeURI(URL) // 이스케이프 처리(인코딩) const decoded = decodeURI(encoded) // 이스케이프 처리 해제(디코딩) |
encodeURI()
URI의 인코딩을 도와주는 메서드
decodeURI()
URI의 디코딩을 도와주는 메서드
encodeURIComponent()
URI에서 ' : ' , ' / ' 등의 특수문자까지의 인코딩을 도와주는 메서드
const URL = 'https://코리아아이티아카데미.com'; const encoded = encodeURI(URL); console.log(encoded); // https://%EC%BD%...C%B9%B4%EB%8D%B0%EB%AF%B8.com const decoded = decodeURI(encoded); console.log(decoded); // https://코리아아이티아카데미.com const encodedCom = 'https://코리아아이티아카데미.com'; console.log(encodeURIComponent(encodedCom)); // https%3A%2F%2..%B0%EB%AF%B8.com |
예제
예제1
특정 숫자를 입력하면 해당 숫자까지를 출력. [예) 5를 입력하면 1 2 3 4 5를 출력] 특정 숫자를 입력하면 해당 숫자의 제곱을 출력 [예) 4를 입력하면 16을 출력] 위 두개의 식을 함수로 만들고 두 함수의 기능을 모두 사용할 수 있는 iterate() 콜백함수를 만들어보자. |
function func1(num) { for (let i=1; i<=num; i++) { console.log(i); } } function func2(num){ console.log(num**2); } function iterate(num, callback) { callback(num); } iterate(5, func1); // iterate함수의 두번째 매개변수 callback위치는 func1을 가져옴. iterate(4, func2); // iterate함수의 두번째 매개변수 callback위치는 func2을 가져옴. |
예제2
Fruit이라는 생성자를 만들고 20-4와 같은 결과를 동일하게 출력할 수 있는 객체를 만들어보자. 단, Fruit(name, 이모지) 형태로 만든다. |
function Fruit(name, emoji){ this.name = name; this.emoji = emoji; this.display = () => { console.log(`${this.name}: ${this.emoji}`); } } const apple2 = new Fruit('apple','🍎'); const orange2 = new Fruit('orange','🍊'); console.log(apple2); apple2.display(); console.log(orange2); orange2.display(); |
예제3
Counter의 값을 0으로 초기화 한 뒤, 하나씩 숫자가 증가하는 Counter 메소드를 구현해보자. |
class Counter { constructor(value) { // isNaN(): 숫자가 아닐경우 true인 함수. if (isNaN(value) || value<0) { this.#value = 0; } else { this.#value = value; } } get value(){ return this.#value; } increment = () => { this.value++; } } const cnt = new Counter(0); console.log(cnt.value); // 0 cnt.increment(); console.log(cnt.value); // 1 cnt.increment(); console.log(cnt.value); // 2 |
예제4
매달 직원들의 정보를 이용해서 한달 급여를 계산하는 메소드 calculatePay() 를 구현해보자. ---------------------------------------------------------------------------------------------------------------------------- 정직원, 아르바이트를 나타낼 수 있는 class를 생성 FullTimeEmployee, PartTimeEmployee (자식 class) 직원의 정보: 이름, 부서명, 한달 근무 시간 (부모 class) 급여: 정직원(20000원), 아르바이트(10000원) 예) kim.calculatePay() -> 한달 급여 |
class Employee { constructor(name, part, time) { // 전달받아서 저장할 수 있도록 생성자를 생성. this.name = name; this.part = part; this.time = time; } } class FullTimeEmployee extends Employee { constructor(name, part, time){ super(name, part, time); } calculatePay(){ return this.time*20000; } } class PartTimeEmployee extends Employee { constructor(name, part, time){ super(name, part, time); } calculatePay(){ return this.time*10000; } } const A = new FullTimeEmployee('A', 'Fulltime', 62); const B = new PartTimeEmployee('B', 'Parttime', 12); console.log(A.calculatePay()); console.log(B.calculatePay()); |