1.  Ajax ; Asynchronous JavaScript And XML

자바스크립트를 사용하여 브라우저가 비동기 방식으로 데이터를 요청하고, 서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식. (ex. 구글 지도)


  👾  Ajax는 브라우저에서 제공하는 Web API인 XMLHttpRequest 객체를 기반을 동작
  👾  XMLHttpRequest : HTTP 비동기 통신을 위한 메서드와 프로퍼티를 제공

  👾  이전의 웹페이지는 완전한 HTML을 서버로부터 전송받아 웹페이지 전체를 처음부터 다시 렌더링하는 방식으로 동작
          ➡️  화면이 전환되면 서버로부터 새로운 HTML을 전송받아 웹페이지 전체를 처음부터 다시 렌더링

 

전통적 방식의 단점 


    a. 이전 웹페이지와 차이가 없어서 변경할 필요가 없는 부분까지 포함된 완전한 HTML을 서버로부터

        매번 다시 전송받기 때문에 불필요한 데이터 통신이 발생
    b. 변경할 필요가 없는 부분까지 처음부터 다시 렌더링 한다. 이로 인해 화면 전환이 일어나면 화면이 순간적으로

         깜빡이는 현상이 발생한다.
    c. 클라이언트와 서버와의 통신이 동기 방식으로 동작하기 때문에 서버로부터 응답이 있을 때까지 다음 처리는 블로킹 된다.


Ajax의 장점


   a. 변경할 부분을 갱신하는 데 필요한 데이터만 서버로부터 전송받기 때문에 불필요한 데이터 통신 발생 x
   b. 변경할 필요가 없는 부분은 다시 렌더링하지 않는다. 따라서 화면이 순간적으로 깜빡이는 현상이 발생하지 않는다.
   c. 클라이언트와 서버와의 통신이 비동기 방식으로 동작하기 때문에 서버에게 요청을 보낸 이후 블로킹이 발생하지 않는다.

 

Ajax의 단점


    a. 즐겨찾기나 검색엔진에 불리
    b. 개발이 상대적으로 어려움

 

💡  '동기(synchronous)'란       
     -  직렬적으로 태스크를 수행  ▶️  요청을 보낸 후 응답을 받아야지만 다음 동작이 이루어지는 방식 (순차 진행)
💡  '비동기 (asynchronous)'란       
     -  병렬적으로 태스크를 수행  ▶️  요청을 보낸 후 응답의 수락 여부와는 상관없이 다음 태스크가 동작 (멀티 진행)
     
   * 출처 : https://velog.io/@khy226

 


2.  JSON ; JavaScript Object Notation

클라이언트와 서버간의 HTTP 통신을 위한 텍스트 데이터 포맷
자바스크립트에 종속되지 않은 언어 독립형 데이터 포맷으로, 대부분의 프로그래밍 언어에서 사용할 수 있음

  👾  JSON은 자바스크립트의 객체 리터럴과 유사하게 키와 값으로 구성된 순수한 테스트
  👾  JSON의 키는 반드시 큰 따옴표(작은 따옴표 사용 불가)로 묶여야 함
  👾  값은 문자열은 큰 따옴표(작은 따옴표 사용 불가)로 묶여야 함 나머지는 그대로 쓰여도 무관


 

1) JSON.stringify()


     ⚡️ 객체를 JSON 포맷의 문자열로 변환
     ⚡️ 클라이언트가 서버로 객체를 전송하려면 객체를 문자열화해야 하는 데 이를 직렬화 serializing 라고 함

// 기본 형식
JSON.stringify(value, replacer, space)
    1. value : 변환할 객체
    2. replacer : 함수. 값의 타입이 Number이면 필터링이되어 반환되지 않는다.

    3. space : 들여쓰기 몇 칸 할지 Int 형으로 기입
<head>
    <script>
    
        const obj = {
            name: 'Lee',
            age: 20,
            alive: true,
            hobby: ['traveling', 'tennis'],
        };
        console.log(typeof obj); // object

        // 객체를 JSON 포맷의 문자열로 변환.
        const prettyJson = JSON.stringify(obj, null, 2); 
        console.log(typeof prettyJson, prettyJson);
        /*
        string {
           "name": "Lee",
           "age": 20,
           "alive": true,
           "hobby": [
               "traveling",
               "tennis"
           ]
         }
        */
        
         function filter(key, value) {
            //undefined: 반환되지 않음
            return typeof value === 'number' ? undefined : value;
        }
        
        const strFilteredObject = JSON.stringify(obj, filter, 2);
        console.log(typeof strFilteredObject, strFilteredObject);
        /*
        string {
            "name": "Lee",
            "alive": true,
            "hobby": [
                "traveling",
                "tennis"
             ]
        */
}
    </script>
</head>

JSON.stringify() 메서드는 객체뿐만 아니라 배열도 JSON 포맷의 문자열로 변환
<script>
        const todos = [
            { id: 1, content: 'HTML', completed: false },
            { id: 2, content: 'CSS', completed: true },
            { id: 3, content: 'JavaScript', completed: false },
        ];
        // 배열을 JSON 포맷의 문자열로 변환
        const jsonArray = JSON.stringify(todos, null, 2);
        console.log(typeof jsonArray, jsonArray);
        /*
        string [
            {
                "id": 1,
                "content": "HTML",
                "completed": false
             },
            {
                "id": 2,
                "content": "CSS",
                "completed": true
             },
            {
                "id": 3,
                "content": "JavaScript",
                "completed": false
            }
         ]
         */
</script>

 


2)  JSON.parse()


    ⚡️  JSON 포맷의 문자열을 객체로 변환  ▶️  역직렬화 deserializing
    ⚡️  서버로부터 클라이언트에게 전송된 JSON 데이터는 문자열이고, 이 문자열을 객체로 변환

<script>

    const obj = {
        name: "Lee",
        age: 20,
        alive: true,
        hobby: ["traveling", "tennis"],
    };
    console.log(typeof obj); // obj

    // 객체를 JSON 포맷의 문자열로 변환.
    const json = JSON.stringify(obj);
    console.log(typeof json); // string

    // JSON 포맷의 문자열을 객체로 변환.
    const parsed = JSON.parse(json);
    console.log(typeof parsed, parsed); // object

</script>

 


3.  Ajax를 이용해 데이터 가져오기

 

<script>
    
    document.addEventListener('DOMContentLoaded', function () {
   
       // 1. XMLHttpRequest 객체 생성
       const xhr = new XMLHttpRequest();

       // 2. HTTP 요청 초기화
        xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
        // HTTP 요청 방식(GET, POST), 클라이언트가 HTTP 요청을 보낼 서버의 URL 주소

       // 3. 이벤트 등록. XMLHttpRequest 객체의 readyState 프로퍼티 값이 변할 때마다 자동으로 호출
        xhr.onreadystatechange = () => {
            // readyState 프로퍼티의 값이 DONE : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨.
            if(xhr.readyState !== XMLHttpRequest.DONE) return;

            if(xhr.status === 200) { // 서버(url)에 문서가 존재함
                console.log(JSON.parse(xhr.response));
                /*
                {
                    "userId": 1,
                    "id": 1,
                    "title": "delectus aut autem",
                    "completed": false
                }
                */
                
                const obj = JSON.parse(xhr.response);
                console.log(obj.title); // delectus aut autem
            } else {
                console.error('Error', xhr.status, xhr.statusText);
            }
        }
        xhr.send(); // 4. url에 요청을 보냄.
    });
</script>

 


💡 onreadystatechange
서버로 부터 응답이 오게 되어 XMLHttpRequest 객체의 값이 변하게 되면 이를 감지해 자동으로 호출되는 함수를 설정한다.
함수를 등록하게 되면 서버에 요청한 데이터가 존재하고, 서버로부터 응답이 도착하는 순간을 특정할 수 있게 된다.

💡  status
서버의 문서 상태를 표현한다(200 : 존재 / 404 : 미존재)

💡 xhr.send()

send() 메서드를 통해 서버로 객체를 전달한다. 이때 send() 메서드 매개변수를 쓰냐 안쓰냐에 따라 GET / POST 방식으로 다르게 보내게 된다.

💡  readyState 프로퍼티

XMLHttpRequest 객체의 현재 상태를 나타낸다. 이 프로퍼티의 값은 객체의 현재 상태에 따라 다음과 같은 주기로 순서대로 변화한다.

  1. UNSENT (숫자 0) : XMLHttpRequest 객체가 생성됨.
  2. OPENED (숫자 1) : open() 메소드가 성공적으로 실행됨.
  3. HEADERS_RECEIVED (숫자 2) : 모든 요청에 대한 응답이 도착함.
  4. LOADING (숫자 3) : 요청한 데이터를 처리 중임.
  5. DONE (숫자 4) : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨.
 

출처: https://inpa.tistory.com/entry/JS-📚-AJAX-서버-요청-및-응답-XMLHttpRequest-방식 [Inpa Dev 👨‍💻:티스토리] 


출처: https://inpa.tistory.com/entry/JS-📚-AJAX-서버-요청-및-응답-XMLHttpRequest-방식
         [Inpa Dev 👨‍💻:티스토리]

응용 예제 - 현재 날씨 가져오기
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>

        document.addEventListener('DOMContentLoaded', function () {
            // url 인코딩된 키 사용
            const serviceKey = 'uAhO32pV0qa7BDOmkJLhw2ZyOB9i5bGj7cMN8cuuHmKIwyyf29lHLjym8hBXdIaXyvAI1IyLvQZopk5HW233qQ==';

            // 위치 값
            const nx = 89
            const ny = 90

            // 현재 시간 구함
            const today = new Date();

            const baseDate = `${today.getFullYear()}${('0' + (today.getMonth() + 1)).slice(-2)}${('0' + today.getDate()).slice(-2)}`;
            // 현재 분이 30분 이전이면 이전 시간(정시)을 설정.
            let baseTime = today.getMinutes() <= 30 ? `${today.getHours() -1}00` : `${today.getHours()}00`;
            baseTime = (baseTime.length === 3) ? `0${baseTime}` : baseTime; // 10시 전이면 0을 하나 붙임.

            const parameter = `?serviceKey=${serviceKey}&base_date=${baseDate}&base_time=${baseTime}&nx=${nx}&ny=${ny}&dataType=JSON`
            const url = 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst' + parameter
            console.log(url+parameter);


            const xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.onreadystatechange = () => {
                // readyState 프로퍼티의 값이 DONE : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨.
                if(xhr.readyState !== XMLHttpRequest.DONE) return;

                if(xhr.status === 200) { // 서버(url)에 문서가 존재함
                    console.log(xhr.response);
                    jsonData = JSON.parse(xhr.response);
                    console.log(jsonData);

                    const weatherItems = jsonData.response.body.items.item;
                    let jsonStr = `[발표 날짜: ${weatherItems[0]["baseDate"]}]\n`;
                    jsonStr += `[발표 시간: ${weatherItems[0]["baseTime"]}]\n`;
                    for (let k in weatherItems) {
                        let weatherItem = weatherItems[k];
                        obsrValue = weatherItem['obsrValue']
                        // T1H: 기온, RN1: 1시간 강수량, REH: 습도 %
                        if (weatherItem['category'] === 'T1H') {
                            jsonStr += ` * 기온: ${obsrValue}[℃]\n`;
                        } else if (weatherItem['category'] === 'REH') {
                            jsonStr += ` * 습도: ${obsrValue} [%]\n`;
                        } else if (weatherItem['category'] === 'RN1') {
                            jsonStr += `* 1시간 강수량: ${obsrValue} [mm]\n`;
                        }
                    }

                    document.querySelector('div').innerText = jsonStr;


                } else {
                    console.error('Error', xhr.status, xhr.statusText);
                }
            }
            xhr.send();
        });

    </script>
</head>
<body>
<div>


</div>

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 inpa_dev 티스토리 ]


1.  함수  function

🐰  함수는 fun으로 정의하고 반환값이 있는 함수는 내부에서 return으로 값을 반환
🐰  함수를 정의할 때 입력값을 기술한 것을 '파라미터'

    fun 함수이름 (파라미터 이름 : 타입) : 반환타입 {
        return 값
    }


  🥕  함수의 괄호 안에 입력되는 '파라미터 이름 : 타입'에 따라, 함수를 호출할 때 괄호 안에 값을 넣어서 전달하는데
        이 때 입력되는 값의 타입은 함수에 정의된 파라미터 타입과 동일하게 입력해야 함

 

1) 함수의 정의

 

 반환값과 입력값이 있는 함수의 정의


    ✏️  Int 타입의 x라는 입력 파라미터를 갖는 함수 square()를 정의

fun square(x: Int): Int {
    return x * x
}
// square() 함수가 호출되면 입력값을 제곱해서 호출한 측으로 반환하고 실행이 종류.

반환값이 없는 함수의 정의 

 

    ✏️  반환값 없이 입력값을 받아서 출력하는 함수 printSum() 함수를 정의. 함수가 호출되면 결과값을 출력하고 실행이 종료

fun printSum(x: Int, y: Int) {
    println("x + y = ${x + y}")
}

입력값 없이 반환값만 있는 함수의 정의
fun getPi(): Double {
    return 3.14
}


 2) 함수의 사용(호출)


🐰  함수의 사용은 이름 뒤에 괄호를 붙여서 명령어를 실행하는 형태

함수명(값)    

 

    🥕  괄호를 붙이지 않으면 함수의 코드가 실행되지 않고 마치 값처럼 인식

 

반환값과 입력값이 있는 함수의 호출


   ✏️  파라미터에 전달할 값을 입력하고 반환값은 대입 연산자(=)로 변수에 담은 후 사용

fun main() {
    var squareResult = square(30)
    println("30의 제곱은 ${squareResult}입니다.") // 30의 제곱은 900입니다.
    println("40의 제곱은 ${square(40)}입니다.") // 40의 제곱은 1600입니다.
}

반환값이 없는 함수의 호출


    ✏️  반환값이 없으면 대입 연산자(=)를 사용하지 않고 바로 호출해서 실행

fun main() {
    printSum(3, 5) // x + y = 8
}

입력값이 없는 함수의 호출


    ✏️  입력값이 없다면 괄호만으로 실행하고 결과값을 받을 수 있음

fun main() {

    val PI = getPi()
    println("지름이 10인 원의 둘레는 ${PI}입니다.") // 지름이 10인 원의 둘레는 3.14입니다.

}

 2.  함수 파라미터의 정의

🐰  함수에 입력되는 파라미터는 마치 변수를 정의하듯이 '이름 : 타입'의 형태로 정의
       ➡️  여러 개의 파라미터가 정의될 경우는 콤마로 구분
🐰  코틀린에서 함수 파라미터를 통해 입력되는 모든 값은 변하지 않는 immutable
🐰  코틀린에서의 함수 파라미터는 모두 읽기 전용 키워드 val이 생략된 형태

 fun 함수이름((val 생략) name1: String, name2: Int, name3: Double) {실행코드} 

 

 

1) 파라미터의 기본값 정의와 호출


    🥕  파라미터는 정의할 때 등호(=)를 사용해서 기본값을 설정할 수 있음

fun 함수이름 (name1: String, name2: Int = 157, name3: Double = 34.5) {실행코드}
fun newFun(name: String, age: Int = 29, weight: Double = 65.5) {
        // name = "tom"; // Val cannot be reassigned
        println("name의 값은 ${name}입니다.")
        println("age의 값은 ${age}입니다.")
        println("weight의 값은 ${weight}입니다.")
}

// 정의된 newFun() 함수를 호출할 때 기본값이 없는 첫 번째 파라미터에만 값을 입력하면
// 두 번째와 세 번째 파라미터에는 설정한 기본값이 자동으로 입력.
    
    newFun("Hello")
    /*
    name의 값은 Hello입니다.
    age의 값은 29입니다.
    weight의 값은 65.5입니다.
     */


2)  파라미터 이름으로 값을 입력하기


    🥕  함수에 정의된 파라미터가 많을 경우 입력하는 값의 의미가 명확하지 않을 때가 있음
    🥕  이럴 경우 순서와 상관 없이 정의된 파라미터 이름을 지정해서 직접 값을 입력할 수 있음

fun main() {

    newFun("Michael", weight=67.5)
    /*
     name의 값은 Michael입니다.
     age의 값은 29입니다.
     weight의 값은 67.5입니다.
     */

}

 


응용 예제

 

   📍 login() 메서드와 logout() 메서드를 선언
        login() 메서드를 호출할 때는 매개값으로 id와 passwd를 제공하고, logout() 메서드는 id만 매개값으로 제공

       1) login() 메서드는 매개값 id가 "admin", 매개값 password가 "1234"일 경우에만 true 로 리턴하고

           그외의 값일 경우에는 false를 리턴
       2) logout() 메서드는 "admin 아이디가 로그아웃 되었습니다"가 출력

fun main() {

    print("아이디를 입력해주세요. >> ")
    val id = readln()
    print("비밀번호를 입력해주세요. >> ")
    val password = readln()

    val result = login(id = id, password = password)
    if (result) {
        println("로그인 되었습니다.")
        logout(id)
    } else {
        println("id 또는 password가 올바르지 않습니다.")
    }

}

fun login(id:String, password: String): Boolean {
    return id == "admin" && password == "1234"
}

fun logout(id: String) {
    println("$id 아이디가 로그아웃 되었습니다.")
}

 


  📍  배열을 전달 받아 짝수만 출력하는 메서드 작업 

fun main() {
   
    val numbers = IntArray(10)
    for (i in numbers.indices) {
        numbers[i] = i + 1
    }
    print("main() : ")
    for (i in numbers.indices) {
        print(numbers[i])
        if (i < numbers.size - 1) {
            print(", ")
        }
    } // main() : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

    println()
    printOdd(numbers) // printOdd() : 2, 4, 6, 8, 10
}

fun printOdd(numbers: IntArray) {
    print("printOdd() : ")
    for (i in numbers.indices) {
        if (numbers[i] % 2 == 0) {
            print(numbers[i])
            if ( i < numbers.size - 1) {
                print(", ")
            }
        }
    }

    val odds = numbers.filter {result -> result % 2 == 0}
    println(odds)
}

 


  📍 키보드로 부터 학생 수와 각 학생들의 점수를 입력받아서, 최고 점수 및 평균 점수를 구하는 프로그램

fun main() {

    var run = true // 반복문의 조건으로 사용 -> 값이 false가 된다면 반복문이 종료

    var scoreList: IntArray = IntArray(0)
    while (run) {
        println("-----------------------------------------------------")
        println("1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료")
        println("-----------------------------------------------------")
        print("선택> ")
        val selectNo: Int = readln().trim().toInt()
        when (selectNo) {
           1 -> scoreList = inputStudentNum() // 학생수를 입력 받아서 배열 생성
           2 -> inputScores(scoreList) // 생성된 배열의 갯수 만큼 점수 입력
           3 -> printScores(scoreList) // 입력받은 배열의 값을 출력
           4 -> printAnalysis(scoreList) // 최고 점수, 평균 점수 출력
           5 -> run = setRun() // run 값 변경
        }
    }
    println("프로그램 종료")
}

fun inputStudentNum():IntArray {
    print("학생수> ")
    var studentNum = readln().toInt()
    return IntArray(studentNum)
}

fun inputScores(scores:IntArray) {
    for (i in scores.indices) {
        print("scores[$i] > ")
        scores[i] = readln().toInt()
    }
}

fun printScores(scores:IntArray) {
    for (i in scores.indices) {
        println("scores[$i] : " + scores[i])
    }
}

fun printAnalysis(scores: IntArray) {
    var max = scores[0]
    var sum = scores[0]
    var avg: Double

    for (i in 1 until scores.size) {
        if (scores[i] > max) {
            max = scores[i]
        }
        sum += scores[i]
    }

    avg = (sum / scores.size).toDouble()
    println("최고 점수: " + max)
    println("평균 점수: " + avg)

}

fun setRun(): Boolean {
    return false
}

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1.  배열  Array

🐝  여러 개의 값을 담을 수 있는 대표적인 자료형인 배열은 값을 담기 전에 먼저 배열 공간의 개수를 할당하거나
      초기화 시에 데이터를 저장해 두면 데이터의 개수만큼 배열을 크기가 결정
🐝  먼저 개수를 정해 놓고 사용해야 하며 중간에 개수를 추가하거나 제거할 수 없음

💡  배열은 다른 데이터 타입과 마찬가지로 변수로 저장해서 사용할 수 있으며 다음과 같은 형태로 선언
      var 변수 = Array(개수)
fun main() {
    // 배열 객체는 Int, Long, Char 등과 같은 기본 타입 뒤에 Array를 붙여서 만듦.
    var students: IntArray = IntArray(10) // 변수 student에 Int(정수형) 공간을 10개 할당하라는 의미
    var longArray = LongArray(10)
    var charArray = CharArray(10)
    var floatArray = FloatArray(10)
    var doubleArray = DoubleArray(10)

    println(students[0]) // 0 -> 따로 초기화 하지 않으면 0으로 초기화.
}

1) 문자열 배열에 빈 공간 할당하기


🍯  String은 기본 타입이 아니기 때문에 StringArray는 없지만 다음과 같이 사용할 수 있음

var stringArray = Array(10, {item -> "" })


🍯  괄호 안의 첫 번째 숫자인 10만 변경해서 사용하면 그 숫자만큼 빈 문자열로 된 배열 공간을 할당
       ➡️  자바에서는 문자열 배열을 생성하면서 초기화 하지 않으면 null이 초기값이 됨
       ➡️  하지만 코틀린은 기본적으로 Null 사용을 허용하지 않기 때문에 빈 문자열을 이용해서 따로 초기화해야 함


2) 값으로 배열 공간 할당하기


🍯  arrayOf() 함수를 사용해서 String 값을 직접 할당할 수도 있음

fun main() {
    var dayArray: Array<String> = arrayOf("MON", "TUE", "WED", "THU", "FRI", "SAT", "SUM")

    var intArray: IntArray = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    var intArray2: Array<Int> = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
}

3) 배열에 값 입력하기

 

🍯  다음은 배열의 인덱스에 있는 값을 바꾸는 방법을 다른 방식으로 표현한 것

 

💡 이 두 방식은 표현식만 다를 뿐 동일한 코드

    1. 배열을 선언한 변수명 옆에 대괄호([])를 사용하고, 대괄호 안에 값을 저장할 위치의 인덱스 번호를 작성
        그리고 등호(=)를 사용해서 값을 입력
       배열명[인덱스] = 값

    2. set 메서드를 사용할 수 있음. 배열이 제공하는 set()메서드에 인덱스와 값을 파라미터로 넘겨주면 됨
       배열명.set(인덱스, 값)
fun main() {
    students[0] = 90
    students.set(1, 91)
}

 4) 배열에 있는 값 꺼내기


🍯  값을 입력할 때와 같은 방식으로 인덱스로 값을 가져올 수 있음

 

💡 대괄호 안에 인덱스를 입력해서 가져올 수 있으며 값을 꺼내는 배열의 메서드는 get()
     배열명[인덱스]
     배열명.get(인덱스)
fun main() {

    // 배열 students의 일곱번째 값을 seventhValue 변수에 저장
    var seventhValue = students[6]

    // 배열 students의 열번째 값을 tenthValue 변수에 저장
    var tenthValue = students.get(9)

}

 


응용 예제
fun main() {
    /* for문을 이용해서 arr 배열의 합을 구하세요 */
    val arr = intArrayOf(10, 20, 30, 40, 50)
    var sum = 0

    // 작성 위치
    // 1. until 사용
    for (i in 0 until arr.size) {
        sum += arr[i]
    }
    println("arr 배열의 합은 $sum")

    // 2. for in 사용
    sum = 0
    for (item in arr) {
        sum += item
    }
    println("arr 배열의 합은 $sum")

    // 3. indices 사용
    println(arr.indices) // 0..4
    sum = 0
    for (i in arr.indices) {
        sum += arr[i]
    }
    println("sum = $sum")
}

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1. while 문

1) 일반적인 while 반복문


👩🏻‍💻  for문과는 다르게 증감되는 인덱스가 있으면 코드에서 직접 처리해야 함

fun main() {
    // current 변수가 인덱스의 역할
    var current = 1
    val until = 12
    while (current < until) {
        println("현재 값은 ${current}입니다.")
        current++
    }
}
/*
현재 값은 1입니다.
현재 값은 2입니다.
현재 값은 3입니다.
...
현재 값은 9입니다.
현재 값은 10입니다.
현재 값은 11입니다.
*/


2) do와 함께 사용하기


👩🏻‍💻  do와 함께 사용하면 while 문의 조건식과 관계없이 do 블록 안의 코드를 한 번 실행

fun main() {
    var game = 1
    val match = 6
    do {
        println("${game}게임 이겼습니다. 우승까지 ${match - game}게임 남았습니다.")
        game++
    } while (game < match)
}    
/*
1게임 이겼습니다. 우승까지 5게임 남았습니다.
2게임 이겼습니다. 우승까지 4게임 남았습니다.
3게임 이겼습니다. 우승까지 3게임 남았습니다.
4게임 이겼습니다. 우승까지 2게임 남았습니다.
5게임 이겼습니다. 우승까지 1게임 남았습니다.
*/


3) while과 do ~ while의 차이점


👩🏻‍💻  가장 큰 차이점은 최초 값이 조건식을 만족하지 않았을 경우 실행 코드가 달라지는 것
👩🏻‍💻  do ~ while 은 조건과 상관없이 처음 한 번 로그가 출력

fun main() {
    game = 6
    while (game < match) {
        println("while 테스트입니다.")
        game++
    }

    // do ~ while 테스트
    game = 6
    do {
        println("do ~ while 테스트 입니다.")
        game++
    } while (game < match)
}
/*
do ~ while 테스트 입니다.
*/

 


2. 반복문 제어하기


👩🏻‍🚀  반복문이 실행되는 도중에 특정 조건에서 반복문을 벗어나거나 다음 반복문으로 넘어가야 하는 상황에서 사용

1) break : 반복문 탈출하기


    👾  반복문 안에서 break를 만나면 반복문을 탈출할 수 있음
    👾  특정 조건에서 무조건 반복문 블록에서 벗어날 때 사용

fun main() {    
    for (index in 1..10) {
        println("현재 index는 ${index}입니다.")
        if (index > 5) { // index가 5보다 크면 break 명령어로 현재 반복문을 벗어남
            break
        }
    }
}

/*
현재 index는 1입니다.
현재 index는 2입니다.
현재 index는 3입니다.
현재 index는 4입니다.
현재 index는 5입니다.
현재 index는 6입니다.
*/

 



2)  continue : 다음 반복문으로


    👾  반복문 내에서 continue를 만나면 continue 다음 코드는 실행하지 않고  반복문의 코드의 처음으로 돌아감

fun main() {

    for (except in 1..10) {
        // except가 3보다 크고 8보다 작으면 continue 명령으로 로그를 찍지 않고 다음 반복문으로 이동
        if (except > 3 && except < 8) {
            continue
        }
        println("현재 index는 ${except}입니다.")
    }
}
/*
현재 index는 1입니다.
현재 index는 2입니다.
현재 index는 3입니다.
현재 index는 8입니다.
현재 index는 9입니다.
현재 index는 10입니다.
*/

 


응용 예제


   📌  while문과 Range.random() 메소드를 이용해서 2개의 주사위를 던졌을 때 나오는 눈을 (눈1, 눈2) 형태로 출력하고,
         눈의 합이 5가 아니면 계속 주사위를 던지고, 눈의 합이 5이면 실행을 멈추는 코드를 작성해 보세요.
         눈의 합이 5가 되는 조합은 (1, 4), (4, 1), (2, 3), (3, 2)입니다.
       예 ) (5, 1)
              (4, 4)
              (6, 5)
              (5, 2)
              (3, 6)
              (1, 2)
              (2, 3)

💡  Range.random() : 어떤 숫자 범위가 정의된 Range 객체의 random() 메소드를 호출하면 그 범위의 무작위 숫자가 리턴
fun main() {

    while (true) {
        val num1 = (1..6).random()
        val num2 = (1..6).random()
        println("($num1, $num2)")

        if (num1 + num2 == 5) {
            break;
        }
    }
    println()

    do {
        val num1 = (1..6).random()
        val num2 = (1..6).random()
        println("($num1, $num2)")

    } while (num1 + num2 != 5)

}

 


 
    📌  음수가 입력될 때까지, 사용자가 입력한 정수의 합계를 계산하여 출력하는 프로그램을 작성하세요.
          while문을 사용, break 사용하지 말 것
          1) while문으로 작업
          2) do while문으로 작업

fun main() {

    var sum = 0
    var value = 0

    while (value >= 0) {
        sum += value
        print("정수를 입력하세요.")
        value = readln().toInt()
    }
    println("정수의 합계는 ${sum}입니다.")

    do {
        print("정수를 입력하세요.")
        val value = readln().toInt()
        if (value >= 0) {
            sum += value
        }
    } while (value >= 0)
    println("정수의 합계는 ${sum}입니다.")
}

 



    📌  컴퓨터가 주사위를 던지면 사용자가 주사위의 숫자를 맞히는 프로그램을 완성하세요.
          사용자가 맞힐 때까지 게임은 계속 됩니다.
          예)
          주사위 값은 얼마일까요? >>> 5
          오답입니다. 다시 시도하세요.
          주사위 값은 얼마일까요? >>> 1
          1! 정답입니다.
         

fun main() {

    // 1. break 사용
    val num = (1..6).random()
    while (true) {
        print("주사위 값은 얼마일까요? >>> ")
        var inputNum = readln().toInt();
        if (num == inputNum) {
            println("$inputNum! 정답입니다.")
            break
        } else {
            println("오답입니다. 다시 시도하세요.")
        }
    }

    println()

    // 2. break 사용 x
    val num2 = (1..6).random()
    do {
        print("주사위 값은 얼마일까요? >>> ")
        var inputNum = readln().toInt()
        if (num2 == inputNum) {
            println("$inputNum! 정답입니다.")
        } else {
            println("오답입니다. 다시 시도하세요.")
        }
    } while (num2 != inputNum)

}

 

 

 

[ 내용 참고 : IT 학원 강의 ]

'Programming Language > Kotlin' 카테고리의 다른 글

[Kotlin] 함수 function  (0) 2024.04.09
[Kotlin] 배열 Array  (0) 2024.04.08
[Kotlin] for 반복문  (0) 2024.04.05
[Kotlin] when 조건문, 범위 클래스  (1) 2024.04.05
[Kotlin] if 조건문  (0) 2024.04.05


 

1.  localStorage 객체

 

👾  웹 브라우저에 데이터를 저장하는 객체

👾  localStorage 객체 처럼 웹 브라우저가 제공해주는 기능을 웹 API 라고 부른다.

메소드 설명
localStorage.getItem(키) 저장된 값을 추출. 없으면 'null' 이 반환
localStorage.setItem(키, 값) 값을 저장
localStorage.removeItem(키) 특정 키의 값을 제거
localSorage.clear() 저장된 모든 값을 제거

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .hidden {
        display: none;
    }
</style>

<body>
<form id="login-form"> <!-- input 유효성 검사 작동 위해 form 안에 들어가 있어야 함 -->
    <input
            required
            maxlength="15"
            type="text"
            placeholder="What is your name?" />
    <input type="submit" value="Log In">
</form>
<h1 id="greeting" class="hidden"></h1>
<script src="app.js"></script>

</body>
</html>
const loginForm = document.querySelector('#login-form');
const loginInput = document.querySelector('#login-form input');
const greeting = document.querySelector("#greeting");

const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KYE = 'userName';
function onLoginSubmit(event) { // 방금 일어난 event에 대한 정보를 지닌 argument를 채워넣음
    // form을 submit 하면 브라우저는 기본적으로 페이지를 새로고침 함
    event.preventDefault(); // 브라우저 기본 동작 막음 (새로고침 x)
    const userName = loginInput.value; // 입력받은 값 변수에 저장
    loginForm.classList.add(HIDDEN_CLASSNAME); // 입력받은 후 폼 형태 숨기기
    localStorage.setItem(USERNAME_KYE, userName); // (키,값) 형태로 저장
    paintGreetings(userName); // h1 태그 안의 텍스트 불러옴
}

function paintGreetings (userName) { // h1 태그 안의 텍스트 불러오는 함수
    greeting.innerText = `Hello ${userName}`;
    greeting.classList.remove(HIDDEN_CLASSNAME); // 인사말 숨기는 속성 제거
}

const savedUsername = localStorage.getItem(USERNAME_KYE);

if (savedUsername === null) { // 이름이 저장되어 있지 않을 떄
    loginForm.classList.remove(HIDDEN_CLASSNAME); // 로그인 폼 숨기는 속성 제거
    loginForm.addEventListener('submit', onLoginSubmit);
} else { // 이름이 저장되어 있을 떄
    paintGreetings(savedUsername);
}

 

 

웹 API 관련 참고 사이트

https://developer.mozilla.org/ko/docs/Web/API 

 

Web API | MDN

웹 코드를 작성한다면 많은 API를 사용할 수 있습니다. 아래 목록은 웹 앱이나 웹 사이트를 만들 때 사용할 수 있는 모든 인터페이스(객체의 유형)입니다.

developer.mozilla.org

 

 

 

[ 내용 참고 : 책 '혼자 공부하는 자바스크립트' 및 노마드 코더 강의 ]


1.  회원가입 예제

body 태그
<body>
<div id="container">
    <h1>회원 가입</h1>
    <form action="#" id="register">
        <ul id="user-info">
            <li>
                <label for="user-id" class="field">아이디</label>
                <input type="text" name="user-id" id="user-id" placeholder="4~15자리로 입력" required>
            </li>
            <li>
                <label for="email" class="field">이메일</label>
                <input type="email" name="email" id="email" required>
            </li>
            <li>
                <label for="user-pw1" class="field">비밀번호</label>
                <input type="password" name="user-pw1" id="user-pw1" placeholder="8자리 이상" required>
                <span class="trans">문자로 변환</span>
            </li>
            <li>
                <label for="user-pw2" class="field">비밀번호 확인</label>
                <input type="password" name="user-pw2" id="user-pw2" required>
            </li>
            <li>
                <label class="field">메일링 수신</label>
                <label class="r"><input type="radio" value="yes" name="mailing">예</label>
                <label class="r"><input type="radio" value="no" name="mailing">아니오</label>
            </li>
        </ul>
        <ul id="buttons">
            <li>
                <input type="button" class="btn btnBlack" value="가입하기">
            </li>
            <li>
                <input type="reset" class="btn btnGray" value="취소">
            </li>
        </ul>
    </form>
</div>
</body>

 

stylesheet
#container{
    width:600px;
    margin:0 auto;
}
ul {
    list-style:none;
}
ul li {
    clear:both;
}
.field {
    float:left;
    width:100px;
    font-weight:bold;
    font-size:0.9em;
    line-height: 55px;
    text-align:right;
    margin-right:15px;
}
input[type="text"], input[type="password"], input[type="email"] {
    float:left;
    width:350px;
    height:35px;
    border:1px solid #aaa;
    border-radius:5px;
    padding:5px;
    margin:10px 0;
    float:left;
}

.r {
    line-height:55px;
}

#buttons > li {
    display:inline-block;
}
input[type="button"], input[type="reset"] {
    width:250px;
    height:50px;
    margin-right:10px;
    border:1px solid #ccc;
    background:#eee;
    font-size:0.9em;
}

 


 

script 코드 작성

 회원가입 페이지 입력 값 검증하기
         1. [가입하기] 버튼을 클릭하면 아이디 글자 수 확인하기

         2. 비밀번호 확인하기
           1) 비밀번호 필드에 입력한 내용의 글자 수가 8자리 이상인지 확인
           2) 비밀번호 확인 필드에 입력한 값이 비밀번호의 필드 값과 같은지 확인

         3. 비밀번호 패스워드 변환 <-> 문자 변환
<head>
    <link rel="stylesheet" href="css/register.css">
    <script>
        
        document.addEventListener('DOMContentLoaded', function () {
            const frmRegister = document.getElementById('register'); // 폼태그
            const btnSubmit = document.querySelector('.btnBlack'); // 가입 버튼
            const userName = document.getElementById('user-id'); // id태그
            const pw1 = document.querySelector('#user-pw1'); // 비밀번호1 필드
            const pw2 = document.querySelector('#user-pw2'); // 비밀번호2 필드

            btnSubmit.addEventListener('click', function () {
             // 가입하기 버튼 클릭했을 때
                if (userName.value.length > 15 || userName.value.length < 4) {
                    alert('4~15자리로 입력하세요.'); // 오류 메시지 출력

                    /*
                    select() : 사용자가 기존에 입력한 값을 선택
                    focus() : 사용자가 기존에 입력한 값을 지우고 새로운 값을 입력하도록 텍스트 필드에 커서를 가져다 놓음.
                     */
                    userName.select();
                    return;
                }
                frmRegister.submit();
            });

            pw1.addEventListener('change', function () { 
            // 비번1 입력했을 때 오류 확인
            
                if (pw1.value.length < 8) {
                    alert('비밀번호는 8자리 이상이어야 합니다.'); // 오류 메시지 표시
                    pw1.value='';
                    pw1.focus();
                }
            });

            pw2.addEventListener('change', function () {
             // 비번 2 입력했을 때 오류 확인
             
                if (pw1.value !== pw2.value) {
                    alert('암호가 다릅니다. 다시 입력하세요.'); // 오류 메시지 표시
                    pw2.value = '';
                    pw2.focus();
                }
            });

            const btnTrans = document.querySelector('span.trans'); 
            // 비밀번호 문자열 변환 태그
            
            btnTrans.addEventListener('click', function (e) {

                if (pw1.getAttribute('type') === 'password') {
                    pw1.setAttribute('type', 'text');
                    e.currentTarget.textContent = '패스워드로 변환';

                } else {
                    pw1.setAttribute('type', 'password');
                    e.currentTarget.textContent = '문자로 변환';
                }

            });
        });
    </script>
</head>

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts