TIL 0403

먼지·2024년 4월 3일

Today I Learned

목록 보기
33/89
post-thumbnail

JavaScript

자바스크립트의 정의

클라이언트쪽에서 독립적으로 실행되는 프로그램을 작성하기 위한 스크립트 언어

자바스크립트의 특징

  • 웹 문서(HTML)에 삽입해서 사용하는 스크립트 언어
  • 웹 브라우저에서 웹 문서를 실행할 때 프로그램 코드가 해석됨
  • 컴파일 과정을 거치지 않는 인터프리터 언어의 형태이기 때문에 비교적 자료형 조사를 철저하게 하지 않음
  • 객체 지향적 특성을 모두 가지고 있다고 말할 수는 없지만 객체를 정의하여 사용할 수는 있음.

자바스크립트의 장점 및 단점

장점

  • 자바스크립트는 HTML 파일 내에서 작성할 수 있으므로 개발 속도가 빠름
  • 운영체제의 제한을 받지 않음

단점

  • 소스 코드가 노출됨. 컴파일하지 않는 언어이므로 복사하여 사용할 수 있음
  • 한정된 객체와 객체 함수 제공

실행 위치

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>실행 위치</title>
    <script type="text/javascript">
        // 웹 브라우저는 head 태그를 먼저 읽은 후 body 태그를 읽으므로 
        // script 태그를 head 태그에 넣으면  body 태그를 읽기 전에 실행한다. 
        // 반대로 body 태그에 넣으면 head 태그에 script를 먼저 실행하고 body 태그의 script를 실행한다.
        document.write("head에서 실행");
    </script>
</head>
<body>
    <script>
        document.write("body에서 실행");
    </script>
</body>
</html>

JS 외부 파일에 명시 후 링크

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>실행코드를 외부 파일에 명시하고 링크하기</title>
    <script src="script.js" type="text/javascript">
        
    </script>
</head>
<body>
    
</body>
</html>
document.write("script.js 파일에서 호출");

태그 내장 - inline 형태

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>태그 내장 - inline 형태</title>

</head>
<body>
    <input type="button" value="확인" onclick="alert('태그에 자바스크립트 표시');">
</body>
</html>

주석 및 출력하기

"를 일반 문자로 사용하려면 출력되는 내용을 담는 따옴표를 작은 따옴표로 작성해야 한다.
그러면 자동으로 일반 문자로 변환되기 때문에 오류가 발생하지 않는다.
그러나 둘 다 큰 따옴표 " 로 입력을 한다면 일반 문자로 나타내고 싶은 " 앞에 \ 역슬래쉬를 작성해주면 오류가 발생하지 않는다.

반대로 '를 일반 문자를 사용할 때도 똑같다.
출력문을 담는 따옴표를 "로 작성하고 사용해주면 오류 없이 자동으로 일반 문자로 변환 된다.
둘 다 작은 따옴표'로 입력을 한다면 일반 문자로 나타내고 싶은 ' 앞에 \ 역슬래쉬를 작성해주면 오류가 발생하지 않는다.

정수, 실수, 논리값을 출력하는데 작은 따옴표 ' 나 큰 따옴표 " 를 사용하여 출력하면 문자로 인식하게 된다.

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

<head>
    <meta charset="UTF-8">
    <title>주석 및 출력</title>
</head>

<body>
    <script type="text/javascript">
        // 주석
        // 한줄 주석
        /*
        여러 줄 주석
        */
        // document.write('주석 처리');
        /*document.write('여러줄');
        document.write('주석 처리');*/

        //문자 표시
        document.write('Hello World!!<br>');
        document.write("Hello World~~<br>");

        //일반 데이터를 "를 사용할 경우
        document.write('오늘은 "수요일"<br>'); 
        document.write("내일은 \"목요일\"<br>");

        //일반 데이터를 '를 사용할 경우
        document.write('여기는 \'서울\'<br>');
        document.write("저기는 '부산'<br>");

        //정수
        document.write(567);
        document.write('<br>');

        //실수
        document.write(454.343);
        document.write('<br>');

        //논리값
        document.write(true);
        document.write('<br>');

        //브라우저의 검사 항목을 클릭해서 콘솔에 출력된 내용 보기
        console.log('콘솔에 내용 출력');
    </script>
</body>

</html>

변수

변수명 정의

  1. 키워드 (예약어)를 사용하면 안 된다.
  2. 숫자로 시작하면 안 된다.
  3. 특수문자는 언더바와 달러사인만 허용한다.
  4. 공백 문자를 포함할 수 없다.

식별자를 잘못 지정한 예

  • break : 키워드 사용
  • 10alpha : 숫자로 시작
  • #num : 특수문자 사용
  • has space : 공백 사용

Java와 마찬가지로+ 연산자는 문자열을 연결시켜주기도 하지만 더하기 연산도 가능하다.

변수의 선언 없이 출력문을 작성하게 되면 오류가 발생하는데, 해당 오류문장은 콘솔에서 확인할 수 있다.

변수를 선언 했는데 할당한 값이 없을 때는 오류가 발생하지 않는다.
대신 출력했을 때 값이 undefined로 출력된다.

변수명을 한글로 입력이 가능하지만 사용하지 않는 것이 좋다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Variable 변수</title>
</head>
<body>
    <script>
        // 변수의 선언
        var num;

        //변수에 값을 할당
        num = 123; 

        //출력
        document.write('num = ' + num);
        document.write('<br>');

        //변수의 선언 없이 출력
        //document.write('num2 = ' + num2); 

        //변수 선언 후 값 할당 없이 출력
        var num3; 
        document.write('num3 = ' + num3);
        document.write('<br>');
   
        //두개 이상의 변수를 한 번에 선언
        var a, b;
        a = 10;
        b = 5;
      
        // document.write('a+b = ' + a + b);
        // 소괄호를 안 해주면 연산 실행이 안 된다.
        document.write('a + b = ' + (a + b));
        document.write('<br>');

        //변수 선언과 초기화 동시 진행
        var c = 10, d = 3.5;
        document.write('c + d = ' + (c+d));
        document.write('<br>');

        // 한글 사용 가능 (사용은 가능하나 쓰지 않는 것이 좋음)
        var 번호 = 3;
        document.write('번호 =' + 번호);
   </script>
</body>
</html>

변수 사용시 주의사항

JavaScript는 같은 변수명을 사용하는 것을 막지 않기 때문에 같은 변수명을 또 선언해도 문제 없이 출력된다.
그러나 이전의 데이터는 없어지기 때문에 주의하여 사용해야한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>변수 사용시 주의사항</title>
</head>
<body>
    <script>
        var food = '김치찌개';  //변수 선언 및 초기화
        document.write('food = ' + food + '<br>');

        food = '라면';              // 데이터 변경
        document.write('food = ' + food + '<br>');

        document.write('----------------------<br>');

        //변수명을 같게 선언해도 오류가 발생하지 않음
        var food = '냉면';
        document.write('food = ' + food + '<br>');
    </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>변수 호이스팅 Variable Hoisting</title>
</head>
<body>
    <script>
        document.write(score);

        var score; //변수 선언
    </script>
</body>
</html>

자료형

Java Script 자료형

  • 숫자형(Number) : 정수형과 실수형으로 나눌 수 있음
  • 문자형(String) : 작은 따옴표 '' , 큰 따옴표 "" 를 양 끝에 두고, 그 안에 한 글자 이상의 문자, 기호 또는 숫자가 있는 자료형
  • 불린형(Boolean): 참(true)와 거짓(false)를 표현
  • null : 값이 없다는 의미
  • undefined : 존재하지 않는 값을 의미
  • symbol: ES6에서 추가된 원시 자료형, 유일하게 고유하고 변경할 수 없는 값

typeof 변수명
* 해당 변수에 저장된 데이터의 타입을 알아내는 연산자

NULL
null 은 존재하지 않는 값을 의미한다. 원시 자료형 null로 분류가 된다.
단, typeof로 자료형을 확인할 때 object를 반환하는데, 이는 자바스크립트 기존 이슈로 인한 결과이다.
이를 통해 null이 객체형이라 오해하지 않도록 주의해야 한다.

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

<head>
    <meta charset="UTF-8">
    <title>JavaScript의 자료형</title>
</head>

<body>
    <script>
        // 변수 선언 및 초기화
        var numberVar = 273;        //숫자
        var stringVar = 'Seoul';      //문자 (문자와 문자열의 구분이 없다)
        var booleanVar = true;      //논리형
        var nullVar = null;
        var undefinedVar;
        var sym = Symbol('me');

        // typeof  변수명 : 해당 변수에 저장된 데이터의 타입을 알아내는 연산자
        document.write('numberVar : ' + typeof numberVar + '<br>');
        document.write('stringVar : ' + typeof stringVar + '<br>');
        document.write('booleanVar : ' + typeof booleanVar + '<br>');
        document.write('nullVar : ' + typeof nullVar + '<br>');     
        document.write('undefinedVar : ' + typeof undefinedVar + '<br>');
        document.write('sym : ' + typeof Symbol + '<br>');

        var functionVar = function () { }; //함수
        var objectVar = {}; //객체
        var arrayVar = []; //배열
        document.write('functionVar : ' + typeof functionVar + '<br>');
        document.write('objectVar : ' + typeof objectVar + '<br>');
        document.write('arrayVar : ' + typeof arrayVar + '<br>');


    </script>
</body>

</html>

형변환

promt : 사용자에게 입력 받는 함수 사용
입력 받은 데이터는 string 타입으로 반환
-> * 곱셈의 경우 데이터가 숫자면 자동적으로 형변환이 되어 곱셈 연산을 실행하지만, + 덧셈의 경우 연산자의 역할 외에도 문자(열) 연결을 해주기 때문에 입력받은 값이 string 타입이기 때문에 문자 연결을 실행한다.

이런 경우 명시적 형변환을 실행해야 한다.

명시적 형변환

  • 문자 -> 숫자 형변환
    Number 함수 사용

  • 숫자 -> 문자 형변환
    String 함수 사용

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>형변환</title>
</head>
<body>
    <script>
        //입력한 데이터를 string 타입으로 반환
        var input = prompt('숫자를 입력하세요', '숫자');
        document.write(typeof(input) + ' : ' + input);
        document.write('<br>');

        //데이터가 숫자일 경우 자동적으로 형변환됨
        document.write(input * 10);
        document.write('<br>');
        // + 연산의 경우 문자열이 있으면 연결
        // 연산시 명시적 형변환
        document.write(input + 10);

        //명시적 형변환
        //문자(열)을 숫자로 변환
        var numberInput = Number(input);  //문자 -> 숫자 
        document.write('<br>형변환 이후<br>');
        document.write(typeof(numberInput) + ' : ' + numberInput);
        document.write('<br>');
        document.write(numberInput + 10);
    </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>산술연산자</title>
</head>
<body>
    <script>
        var a=5, b=3, result;

        document.write('------산술연산자----<br>');

        result = a + b;
        document.write('a + b = ' +result+'<br>');

        result = a - b;
        document.write('a - b = ' +result+'<br>');

        result = a * b;
        document.write('a * b = ' +result+'<br>');

        result = a/b; // 1.66666666666667 정수 / 정수 해도 실수가 나올 수 있다
        document.write('a / b = ' +result+'<br>');

        result = a % b;
        document.write('a % b = ' +result+'<br>');
    </script>
</body>
</html>

비교연산자

x === y : x와 y의 값과 타입이 같으면 true
x !== y : x와 y의 값 또는 타입이 다르면 true

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>비교연산자</title>
</head>
<body>
    <script>
        var a = 20, b = '20', result;

        result = a == b; //값만 비교
        document.write('a == b : ' + result + '<br>');

        result = a === b; //값, 타입 비교
        document.write('a === b : ' + result + '<br>');

        result = a!=b; //값만 비교
        document.write('a != b : ' + result + '<br>');

        result = a!==b; //값과 타입 비교
        document.write('a !== b : ' + result + '<br>');

        result = a > b;
        document.write('a > b : ' + result + '<br>');

        result = a < b;
        document.write('a < b : ' + result + '<br>');
    </script>
</body>
</html>

논리 연산자

! 논리 부정 연산자 : true -> false , false -> true
&& 논리곱 연산자 : 둘 다 true 면 true
|| 논리합 연산자 : 하나가 true면 true

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>논리연산자</title>
</head>
<body>
    <script>
var a = true && false;
document.write('true && false = ' + a + '<br>');

var b = true || false;
document.write('true || false = ' + b + '<br>');

var c = !true;
document.write('!true = ' + c + '<br>')

document.write('----------------<br>')

//1이면 true 0이면 false
var d = 1, e = 0, f;
f = d && e;
document.write('d && e = ' + f + '<br>');

f = d||e;
document.write('d || e = ' + f + '<br>');

f = !d;
document.write('!d = ' + f + '<br>');
    </script>
</body>
</html>

조건 삼항 연산자

var 변수명 = 조건 ? '참값' : '거짓값' ;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>조건연산자(삼항연산자)</title>
</head>
<body>
    <script>
        var input = prompt('숫자를 입력해주세요' , '');
        var result = input > 0 ? '자연수입니다.' : '자연수가 아닙니다.'
        document.write(result);


    </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>조건연산자(삼항연산자)</title>
</head>
<body>
    <script>
        var temp1 = 5 , temp2 = 10;
        var max, min;

        // 두 숫자의 크기를 비교하여 max와 min 변수에 저장한다
        // 조건         ?       참일때 수행문   :   거짓일때 수행문
        temp1 >= temp2 ? (max=temp1,min=temp2) : (max=temp2,min=temp1);

        document.write('큰 값 = ' + max + '<br>');
        document.write('작은 값 = ' + min + '<br>');
    </script>
</body>
</html>

실습

연산자 실습 1

[실습]
국어, 영어, 수학 성적을 입력 받아서 총점과 평균을 구한다.

[입력 예시]
prompt 사용 - 국어 입력, 영어 입력, 수학 입력

[출력 예시]
국어 : 99
영어 : 98
수학 : 97
총점 : 294
평균 : 98

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Operator 실습</title>
</head>
<body>
    <script>
        var kor = prompt('국어 성적을 입력해주세요.', '국어 점수의 범위는 0~100입니다.');
        var eng = prompt('영어 성적을 입력해주세요.', '영어 점수의 범위는 0~100입니다.');
        var math = prompt('수학 성적을 입력해주세요.', '수학 점수의 범위는 0~100입니다.');
        
        var sum;
        sum = Number(kor) + Number(eng) + Number(math);

        var avg;
        avg = sum / 3;

        document.write('국어 : ' +kor + '<br>');
        document.write('영어 : ' + eng+ '<br>');
        document.write('수학 : ' + math + '<br>');
        document.write('총점 : ' + sum + '<br>');
        document.write('평균 : ' + avg + '<br>');

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

연산자 실습 2

[실습]
음식점에서 국수를 주문하는데 할인 행사를 해서 한 그릇에 20% 할인해준다
국수값은 3500원이고 국수값과 주문할 수량을 입력해서 지불 금액을 출력하세요

[입력 예시]
국수값, 국수 수량 입력

[출력 예시]
지불 금액 : 14000원

<!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>
    <script>
		var price = prompt('국수값을 입력해주세요.',''); //국수 값
        var num = prompt('국수 수량을 입력해주세요.',''); // 국수 수량
        var disprice = price * 0.8;        // 국수 한 그릇 할인 가격
        var payment = disprice * num;     // 지불해야 하는 금액

        document.write('지불 금액 : ' + payment + '원');

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

연산자 실습 3

[실습]
신장에 따른 적정 체중 구하기
신장 및 몸무게를 입력 받아서 적정 몸무게 이상일 경우에는 '적정 몸무게 이상',
미만일 경우에는 '적정 몸무게 미달' 출력.
적정 몸무게 공식 : '적정 몸무게 = (신장 - 100) * 0.9'

[입력 예시]
당신의 키를 입력하세요
당신의 몸무게를 입력하세요

[출력 예시]
당신의 키는 ??cm
당신의 몸무게는 ??kg
당신의 적정 몸무게는 ??kg이다.
당신의 몸무게와 적정 몸무게 차이는 ??kg이다.
당신은 '적정 몸무게 이상'이다. or 당신은'적정 몸무게 미달'이다.

<!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>
   <script>
       var height = prompt('당신의 키를 입력하세요.', '');
       var weight = prompt('당신의 몸무게를 입력하세요.', '');
       var properweight = (Number(height) - 100) * 0.9;
       var result = Number(weight) >= properweight ? '적정 몸무게 이상' : '적정 몸무게 미달'

       document.write('당신의 키는 ' + height + 'cm <br>');
       document.write('당신의 몸무게는 ' + weight + 'kg <br>');
       document.write('당신의 적정 몸무게는 ' + properweight + 'kg <br>');
       document.write('당신의 몸무게와 적정 몸무게의 차이는 ' + (Number(weight) - properweight) + 'kg <br>');
       document.write('당신은 ' + result + '이다.');
   </script>
</body>

</html>

조건문

IF 문

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>IF 문</title>
</head>
<body>
    <script>
        var score = prompt('당신의 점수를 입력하세요' , '');
        var grade;
        if(score >= 90 && score <= 100){
            grade = 'A';
        } else if(score >= 80 && score < 90){
            grade = 'B';
        } else if(score >= 70 && score < 80){
            grade = 'C';
        } else if(score >= 60 && score < 70){
            grade = 'D';
        } else if(score >= 0 && score < 60){
            grade = 'F';
        } else {
            grade = '?';
        }
        
        document.write('점수 : ' + score + '<br>');
        document.write('등급 : ' + grade + '<br>');

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

Switch 문

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Switch</title>
</head>
<body>
    <script>
        var score = prompt('당신의 점수를 입력하세요' , '');
        var grade;

        if(score < 0 || score > 100) {
            document.write('잘못 입력하셨습니다.');
        }
        else{
            //Math.floor() ->  소수점 자리 이하 절삭
            switch(Math.floor(score/10)){
                case 10:
                    case 9:
                        grade = 'A';
                        break;
                case 8:
                    grade ='B';
                    break;
                case 7:
                    grade = 'C';
                    break;
                case 6:
                    grade = 'D'; 
                    break;
                default : 
                grade = 'F';
            }
            document.write('점수 : ' + score +'<br>');
            document.write('등급 : ' + grade + '<br>');
        }




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

For 문 1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>for</title>
</head>
<body>
    <script>
        var dan = prompt('단을 입력하세요','');
        document.write(dan+ ' 단' + '<br>');
        document.write('---------------------<br>');

        for( var i = 1; i <= 9; i++){
            document.write(dan + ' * ' + i + ' = ' + dan * i + '<br>');
        }
    </script>
</body>
</html>

For 문 2

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>구구단</title>
</head>

<body>
    <h1>구구단</h1>
    <script>
        document.write('<table border="1">');

        for (var i = 2; i <= 9; i++) {
            document.write('<tr>');
            for (var j = 1; j <= 9; j++) {
                document.write('<td>');
                document.write(i + ' * ' + j + ' = ' + i * j);
                document.write('</td>');
            }
            document.write('</tr>');
        }
        document.write('</table>');

        document.write('<p>');

        document.write('<table border="1">');

        for (var i = 1; i <= 9; i++) { // 곱해지는 숫자
            document.write('<tr>');
            for (var j = 2; j <= 9; j++) { //단
                document.write('<td>');
                document.write(j + ' * ' + i + ' = ' + j * i);
                document.write('</td>');
            }
            document.write('</tr>');
        }
        document.write('</table>');


    </script>
</body>

</html>

While 문

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>while</title>
</head>

<body>
    <script>
        var i = 20;
        while (i >= 10) {
            if (i % 2 == 0) { // 짝수
                document.write('<span style ="color : blue;">' + i + '</span><br>');
            } else { //홀수
                document.write('<span style = "color : red;">' + i + '</span><br>');
            }
            i--;
        }
    </script>
</body>

</html>

Break 문

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Break</title>
</head>

<body>

    <script>
        for (var i = 0; i < 5; i++) {
            for (var j = 0; j < 5; j++) {
                //break가 포함된 반복문만 빠져나감
                if (j == 3) break;
                document.write(i + ',' + j + '<br>');
            }
        }

        document.write('-------------------<br>');

        //레이블을 사용하여 중첩 루프를 동시에 빠져나가는 코드
        outer_loop:
        for (var i = 0; i < 5; i++) {
            for (var j = 0; j < 5; j++) {
                //레이블이 명시된 반복문을 빠져나간다.
                if (j == 3) break outer_loop;
                document.write(i + ',' + j + '<br>');
            }
        }
    </script>
</body>

</html>

Function 함수

함수 선언

profile
Lucky Things🍀

0개의 댓글