데이터융합 JAVA응용 SW개발자 기업 채용연계 연수과정 51일차 강의 정리

misung·2022년 6월 2일
0

JavaScript

1. core-js

9. 함수

parameters.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // begin 부터 end 까지의 총합을 구해주는 함수
        function calcRangeTotal(begin, end) {
            var total = 0;

            console.log(arguments);
            console.log('길이 : ' + arguments.length);
            for (var n = begin; n <= end; n++) {
                total += n;
            }
            return total;
        }

        function multiply(n1, n2) {
            if (typeof n1 !== 'number' || typeof n2 !== 'number') {
                console.log('숫자로 전달하세요.');
                return;
            }
            return n1 * n2;
        }

        // 만약 위 함수에서 if문으로 방지를 하지 않았다면, NaN 출력됨
        var res = multiply(3, '메롱');
        console.log(res);

        function selectRandomFood() {
            var rn = Math.random();
            return rn > 0.5 ? '짜장면' : '짬뽕';
        }

        console.log('랜덤 음식 : ' + selectRandomFood());

        // 매개 값을 두 개만 받기로 정했어도, 그 이상 넣더라도 에러가 안 난다.
        // 그래도 좋은 코드는 아니니까 지양하도록 하자.
        var totalNumber = calcRangeTotal(10, 100, 40, 20, 500);
        console.log('실행 결과값 : ' + totalNumber);

        
        // 매개 변수의 default값 지정
        function sayHello(language='한국어') {
            if (language === '한국어') {
                console.log('안녕하세요~');
            } else if (language === '영어') {
                console.log('hello~');
            } else if (language === '일본어') {
                console.log('こんにちは~');
            }
        }

        console.log(sayHello());            // 기본값 잘 출력됨
        console.log(sayHello('일본어'));
    </script>
</body>
</html>

return.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /*
            void 함수 : 리턴값이 없는 함수
            void 함수는 단독 호출해서 사용.
            다른 함수의 인자(매개값)로 전달이 불가능.
        */
        function greetings(nickname) {
            var bad_nick = ['멍충이', '바보', '쓰레기']
            if (bad_nick.includes(nickname)) {
                console.log('나쁜 말 금지!');
                return;
            }
            console.log(nickname + '님 안녕하세요~');
        }

        var result = greetings('야옹이');
        console.log(result);                // undefined
        greetings('바보');

        /*
            여러 개의 값을 객체로 리턴해줄 수 있음.
            리턴할 때 객체 안에 값을 프로퍼티로 각각 담아
            최종적으로 객체로 포장하여 보내주는 것.
        */
        function operateAll(n1, n2) {
            return {
                plus : n1 + n2,
                minus : n1 - n2,
                multi : n1 * n2,
                divide : n1 / n2
            };
        }

        // 그리고 그 객체의 값은 아래와 같이 불러올 수 있음.
        var results = operateAll(10, 2);
        console.log(results.plus);
        console.log(results['multi']);
    </script>
</body>
</html>

여러 개의 리턴값을 객체 안의 프로퍼티로 넣고, 리턴 시 객체로 포장하여 한 번에 여러 개의 값을 반환하는 테크닉도 가능하다!

multi-param.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 매개값 2개
        function add(n1, n2) {
            return n1 + n2;
        }

        // 매개 변수가 늘어나는 경우 함수를 또 선언해야만 할까?
        function add3(n1, n2, n3) {
            return n1 + n2 + n3;
        }

        // n개의 정수의 합을 구하는 함수
        // spread : ES6 배열 문법
        /*
            ... 을 쓰면 전달되는 모든 값을
            배열로 묶어서 전달받는다.
        */
        function addAll(name, ...numbers) {
            console.log(name + '님 안녕하세요!');
            console.log(numbers);
            var total = 0;

            for (var num of numbers) {
                total += num;
            }
            return total;
        }

        var result = addAll('홍길동', 10, 20, 30, 40, 50, 60, 70, 80, 90, 100);
        console.log(result);
    </script>
</body>
</html>

quiz1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /*
            n개의 정수 전달하면 해당 정수들의
            총합과 평균을 반환하는 함수
            calcTotAvg를 정의
        */

        /*
        function calcTotAvg(...numbers) {
            var total = 0;
            for (var num in numbers) {
                total += numbers[num];
            }

            return {
                total:total,
                avg:total/numbers.length
            };
        }
        */

        // 또 다른 방법
        var calcTotAvg = (...nums) => {
            var total = 0;
            for (var n of nums) {
                total += n;
            }
            var avg = total / nums.length;
            return {total, avg};    // ES6
        }

        var result = calcTotAvg(10, 20, 30);
        console.log(result.total);
        console.log(result.avg);
    </script>
</body>
</html>

quiz2.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        /*
            1. 정수 n을 전달받아 n의 약수들을 출력하고
            약수의 개수를 리턴하는 함수
            calcDivisor를 정의하세요.
            2. 약수의 출력은 함수 내에서 이루어지고
            개수를 리턴받아 출력하시면 되겠습니다.
        */
        function calcDivisor(num) {
            var divisor = [];

            for (var i = 1; i <= num; i++) {
                if (num % i === 0) {
                    divisor.push(i);
                }
            }
            console.log(`${num}의 약수: ${divisor}`);
            return divisor.length;
        }

        var divCount = calcDivisor(72);
        console.log(`72의 약수의 개수 : ${divCount}`);
    </script>
</body>

</html>

다양한 함수.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 즉시 실행 함수 (정의와 동시에 실행되는 함수)
        (function(x, y) {
            console.log(`x + y = ${x + y}`);
        }(50, 60)); // 선언부 바로 뒤에 매개값을 넘겨서 호출

        // 재귀 함수 
        console.log('====================');

        function countdown(n) {
            if (n < 0) return;  // 재귀함수는 종료조건이 반드시 있어야 한다.
            console.log(n);
            countdown(n - 1);
        }

        countdown(5);

        console.log('====================');

        function factorial(n) {
            if (n <= 1) return 1;
            return n * factorial(n - 1);
        }

        console.log(factorial(6));


        // 중첩 함수
        function outer() {
            var x = 1;

            function inner() {
                var y = 2;
                console.log(x + y);
            }

            inner();
        }

        // inner();  <- outer() 호출이 안 되면 inner()자체가 존재 불가.
        outer();
    </script>
</body>
</html>

callback.html

웹 프로그래밍을 진행할 때 정말 많이 사용할 함수의 형태.
이벤트 처리할 때 엄청 많이 쓸 것이고, 비동기 방식으로 DB와 데이터 통신을 할 때도 자주 사용할 것.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        function temp(i) {
            if (i % 2 === 0) {
                console.log(i);
            }
        }

        // 콜백 함수 (callback = 나중에 호출이 된다는 뜻)
        function showNumbers(n, func) {
            for (var i = 1; i <= n; i++) {
                func(i);
            }
        }

        showNumbers(10, temp);

        /*
        showNumbers(10, i => {
            if (i % 2 === 0) {
                console.log(i);
            }
        })
        */

        var plusMinus = function(a, b, callback) {
            callback(a + b, a - b);
        }

        plusMinus(10, 20, function(res1, res2) {
            console.log(res1);
            console.log(res2);
        });
    </script>
</body>
</html>

10. 스코프

basic.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function foo(y) {
            var x = 'local';
            console.log('x : ' + x);
            console.log('y : ' + y);
        }

        foo('parameter');
        console.log('x : ' + x);
        console.log('y : ' + y);
    </script>
</body>
</html>

x 는 지역변수라 function을 나오면 소멸된다.

local-global.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var x = 'global x';

        function outer(x) {
            var y = 'outer local y';
            console.log('x : ' + x);
            console.log('y : ' + y);

            function inner() {
                var x = 'inner local x';
                var z = 'inner local z';
                console.log(x);
                console.log(y);
                console.log(z);
            }
            inner();
        }

        outer('outer local x');
        console.log(x);
    </script>
</body>
</html>

11. let, const

var의 문제점

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /*
            1. 중복 선언 허용
            동일 이름 변수가 선언된 지 모르고 변수를 중복 선언하면
            의도치 않게 변수의 값이 변경되는 부작용이 발생할 수 있다.
        */
        var x = 1;
        var x = 100;
        console.log(x);

        /*
            2. 블록 레벨 스코프를 지원하지 않음. (함수만 블록으로 인정)
            var 키워드는 오로지 함수의 영역만을 지역 스코프로 인식.
            따라서, 함수 외의 블록들에서는 모두 전역변수로 일괄 적용됨.
            전혀 관련없는 변수의 값이 사용될 수도 있고,
            전역 변수가 남용될 가능성이 있다.
        */

        var i = 1;

        for (var i = 0; i < 10; i++) {

        }

        console.log('i : ' + i);

        // ---------------------
        var flag = true;

        if (flag) {
            var temp = '메롱';
        }
        
        console.log(temp);

        /*
            3. 변수 호이스팅
            var 키워드로 변수를 선언하면 호이스팅에 의해
            변수 선언문이 자동으로 맨 위로 끌어올려진 것 처럼 동작한다.
            이러면 흐름 해석에 방해되고 가독성과 유지보수성이 현격하게 떨어진다.
        */
        y = 100;
        console.log('y : ' + y);
        var y;

    </script>
</body>
</html>

let.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1. 변수 중복 선언 불가능.
        let x = 100;
        // let x = 200;

        // 2. 블록 레벨 스코프를 인정.
        if (true) {
            let y = 100;
            console.log('if문 내부 : ' + y);
        }
        // console.log('if문 외부 : ' + y);

        // 3. 변수 호이스팅이 발생하지 않음.
        z = 10;
        console.log(z);

        let z;
        
    </script>
</body>
</html>

const.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const x = '메롱';
        console.log(x);

        // x = '안메롱'; (값의 변경 불가)

        // const와 객체 (객체, 배열, 함수)
        // 객체 주소만 안 바뀌면 되고, 객체 내용은 변경 가능
        const person = {
            name : 'park',
            age : 20
        };

        person.name = 'kim';
        console.log(person.name);

        // 안되는 코드 (객체 자체를 변경하는 행위)
        person = {
            name : 'lee',
            age : 30
        }
    </script>
</body>
</html>

up_down.js / index.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="up_down.js"></script>
</body>
</html>
// 필요한 데이터 : 랜덤 숫자, 횟수 카운트, 카운트다운, 최소값, 최대값

// 최대 범위는 저장할 변수
const MAX = 100;

// 게임에 필요한 데이터 객체
const gameData = {
    secret_num : Math.floor(Math.random() * MAX) + 1,
    count : 0,
    countdown : 6,
    min : 1,
    max : MAX
};

// 함수 정의부

// 사용자의 입력을 수행하는 함수
function inputNumber() {
    // 객체에서 min과 max의 값을 뽑아서 메세지를 완성.
    // const min = gameData.min;
    // const max = gameData.max;

    // 객체 디스트럭쳐링(ES6) : 데이터 참조시에만 사용 가능
    // 수정, 추가 시에는 사용 불가.
    const {min, max} = gameData;

    // 사용자의 입력값을 객체에 추가
    gameData.answer = +prompt(`숫자를 입력하세요! [${min} ~ ${max}]`);

    gameData.count++;
    gameData.countdown--;

    return checkNumber();
}

// 사용자의 입력값을 검증하는 함수
function checkNumber() {
    const {secret_num, count, answer, countdown} = gameData;

    if (secret_num === answer) {
        alert('정답입니다!!' + count + '번 만에 맞추셨군요!!');
        checkCountDown(countdown);
        return true;
    } else if (secret_num > answer) {
        alert('UP!!');
        gameData.min = answer + 1;
    } else {
        alert('DOWN!!');
        gameData.max = answer - 1;
    }
    alertCountDown(countdown);

    return false;
}

// 사용자의 카운트다운을 체크하여 승리여부를 알려주는 함수
function checkCountDown(countdown) {
    if (countdown > 0) {
        alert('You Win!!');
    } else {
        alert('You Lose!!');
    }
}

// 사용자의 남은 카운트다운을 알려주는 함수
function alertCountDown(countdown) {
    if (countdown > 0) {
        alert('정답 기회 ' + countdown + '번 남음!');
    } else {
        alert('정답 기회 모두 소진! 문제를 계속 풀어주세요!');
    }
}

// 핵심 실행부 (main의 역할을 하는 함수)
// 즉시 실행 함수로 선언하여 따로 호출하지 않아도
// 바로 실행될 수 있도록 작성.
(function() {
    alert(`[UP & DOWN 게임 - 1 ~ ${MAX} 사이의 숫자를 맞춰보세요!]`);

    while (!inputNumber()) {    // false가 리턴되면 게임 계속 진행

    }
}());

여태 배운 것을 어느 정도 조합하여 게임 완성

DOM (Document Object Model)

  • 브라우저의 렌더링 엔진은 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조인 DOM을 생성한다.
  • DOM이란 HTML문서의 계층적 구조와 정보를 표현하며, 이를 제어할 수 있는 API를 제공하는 트리 형태의 자료구조이다.

  1. 문서 노드(document node)
  • 문서 노드는 DOM 트리의 최상위에 존재하는 루트 노드로, document 객체로 표현됨.
  • 즉, document 객체는 다른 노드들에게 접근하기 위한 진입점 역할을 담당한다.
  1. 요소 노드(element node)
  • 요소 노드는 각 html요소들을 가리키는 객체이다.
  • 중첩된 태그에 의해 부모 자식 상속관계를 형성한다.
  1. 어트리뷰트 노트(attribute node)
  • 어트리뷰트 노드는 속성에 해당하는 요소 노드와 형제 관계를 형성한다.
  1. 텍스트 노드(text node)
  • 텍스트 노드는 요소 노드의 자식 노드로 형성된다.

텍스트로만 설명을 봐서 그런가 대체 무슨 소리인지를 모르겠다 =_=; 한번 작성해봐야 알 것 같은데

2. Web-api / 2-1. DOM

byid.html

getElementById() 라는 id를 통해 요소를 반환받는 함수에 대해 짤막하게 사용해보고 어떤 결과값이 오는지 알아보는 부분. 자세한 용례 등은 나중에 배울 것이므로 일단은 이렇게 동작하는구나~ 하고 넘어갈 것.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li id="apple">APPLE</li>
        <li id="banana">BANANA</li>
        <li id="grape">GRAPE</li>
        <li id="pine">PINEAPPLE</li>
    </ul>

    <script>
        // 관례적으로 노드변수는 이름 앞에 $기호를 붙인다.
        const $apple = document.getElementById('apple');
        console.log($apple.attributes[0]);

        $apple.style.fontSize = '40px';
        document.body.style.background = 'tomato';

        // 없는 아이디로 취득 : null이 반환
        const $item = document.getElementById('banana');
        console.log($item);

        // 42에서 했던 널방어 등을 해 주는게 좋음.
        if ($item !== null) {
            $item.style.color = 'yellow';
        }

        // 요소에 id를 부여 시 아이디값으로 자동 전역변수가 생성됨.
        grape.style.color = 'violet';
    </script>
</body>
</html>

byTagName.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="fruits">
        <li id="apple">APPLE</li>
        <li id="banana">BANANA</li>
        <li id="grape">GRAPE</li>
        <li id="pine">PINEAPPLE</li>
    </ul>

    <ol>
        <li>야야야</li>
        <li>왜왜왜</li>
        <li>뭐뭐뭐</li>
    </ol>

    <script>
        const $ul = document.getElementById('fruits');

        // 유사 배열
        // key가 인덱스처럼 구성되어 있고, length 프로퍼티가 있음.
        const $test = document.getElementsByTagName('li');
        console.log($test); // 문서 내의 <li> 들을 싹 뜯어올 것

        // 대부분의 경우에는 문서 노드부터 접근하지만
        // 이미 취득한 요소가 있는 경우에도 함수를 이용해서
        // 요소 내의 요소를 취득할 수 있다.
        const $liArray = $ul.getElementsByTagName('li');
        console.log($liArray);
        console.log($liArray[0]);
        console.log($liArray.length);
        console.log($liArray.banana);
        // ↑ 얘는 앞서 $ul에 'fruits'라는 id를 가진 ul 안의 li만 가져오게 했으므로
        // fruits 내의 li만 확보될 것임.

        for (let $ele of $liArray) {
            $ele.style.fontStyle = 'italic';
        }

        for (let i = 0; i < $liArray.length; i++) {
            $liArray[i].style.color = 'red';
        }
    </script>
</body>
</html>

getElementsByTagName() 함수를 이용하여 페이지 내에 있는 특정 이름을 가진 태그를 싹 가져올 수 있다.
문제는 '싹 다 가져오는' 게 문제이지만, 먼저 id로 지정하여 태그 바깥에 감싼 태그를 불러온 다음, 그 안의 태그'들' 을 getElementsByTagName() 을 통해 유사 배열로 전달받아 일괄 스타일을 적용하는 등의 행동을 취할 수 있다.

byClassName.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="fruits">
        <li class="fruit apple">Apple</li>
        <li class="fruit banana">Banana</li>
        <li class="fruit grape">Grape</li>
    </ul>

    <script>
        const $elements = document.getElementsByClassName('fruit');
        console.log($elements);

        const $banana = document.getElementsByClassName('banana');
        console.log($banana);
        $banana[0].style.color = 'yellow';
    </script>
</body>
</html>

밑에 $banana 에 접근할 때 직접적으로 바로 접근하지 말고, getElementsByClassName() 함수가 컬렉션으로 반환을 하니까 [0] 꼭 이렇게 0번 인덱스를 지정해서 접근해야 한다.

querySelector.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="fruits">
        <li class="fruit apple">Apple</li>
        <li class="fruit banana">Banana</li>
        <li class="fruit grape">Grape</li>
    </ul>

    <script>
        // const $elem = document.querySelector('.banana');
        // const $elem = document.querySelector('#fruits > li:nth-child(2)');
        // const $elem = document.querySelector('li[class="fruit banana"]');       // 속성선택
        const $elem = document.querySelector('li.apple + li');  // 인접 형제선택 
        console.log($elem);
        $elem.style.color = 'yellow';

        // 여러 개 반환받기
        const $element = document.querySelectorAll('#fruits > li');
        console.log($element);

        for (let $ele of $element) {
            $ele.style.background = 'red';
        }

        // 없는 선택자 지목 시 null 이 올 것 같지만, 빈 NodeList[]가 전달된다.
        const $test = document.querySelectorAll('peach');
        console.log($test);
    </script>
</body>
</html>

유사배열주의점.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        ul > li {
            font-size: 30px;
        }
        .red {
            color: red;
        }
    </style>
</head>
<body>
    <ul id="fruits">
        <li class="red">Apple</li>
        <li class="red">Banana</li>
        <li class="red">Grape</li>
        <li class="red">Peach</li>
    </ul>
    <script>
        // 유사배열 NodeList 리턴
        // const $elements = document.querySelectorAll

        // 유사배열 HTMLCollection 리턴
        const $elements = document.getElementsByClassName('red');

        // 배열이 아님.
        // let $ele = $elements.pop();

        // 유사배열객체를 배열처럼 제어할 때는 순수 배열로 변경해서 써야 함.
        //const realArray = Array.from($elements);
        const realArray = [...$elements]; // ES6 문법
        let $ele = realArray.pop(); // 유사배열이면 안됐겠지만, 이제 배열이라 pop()이 먹힘.
        console.log(realArray);

        // 1~3번 요소들의 class 이름을 blue로 일괄 변경 (위에서 한개 pop했으니..)
        for (let i = 0; i < realArray.length; i++) {
            realArray[i].className = 'blue';
        }
    </script>
</body>
</html>

0개의 댓글