상세 컨텐츠

본문 제목

JavaScript 5일차

카테고리 없음

by teminam 2023. 4. 14. 16:38

본문

wrapper object

Primitive Types(기본타입 == 원시타입)
- string, number, bigint, boolean, undefined, symbol, null  ## 객체가 아닌 기본타입이다.
- 기본 타입은 객체가 아님
- 기본 타입은 프로퍼티와 메서드를 정의할 수 없음
- new 키워드를 사용하여 원시 타입을 래퍼 객체로 생성할 수 있지만, 주로 사용하는 방법은 아님

    let a = 'apple'
    let a = new String('apple')

    string -> String
    number -> Number
    bigint -> Bigint
    boolean -> Bollean
    symbol -> Symbol

URL, URI(Uniform Resource Identifier)
- 아스키 문자로만 구성되어야 함
- 한글이나 특수문자는 이스키케이프 처리
    cosnt URL = 'https://코리아아이티아카데미.com'
    const encoded = encodeURI(URL)  // 이스케이프 처리
    cosnt URL = 'https://코리아아이티아카데미.com'
    const decoded = decodeURI(encoded)  // 디코드 처리(원래대로)

동등 연산자( === )
- 기본 타입으로 생성된 변수와 new 키워드를 사용하여 명시적으로 생성된 래퍼객체는 서로 다른 타입
    'JavaScipt' === 'JavaScipt'             // true
    'JavaScipt' === new Sring('JavaScipt')  // false
    10 == new Number(10)                    // false

    let num1 = 10
    let num2 = new Number(10)
    num1 === num2 // false

 

 

<!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>함수 작성법</title>
</head>
<body>
    <h2>함수 작성법</h2>
    <script>
        // 함수의 기본
        function sum(num1, num2){
            console.log('sum() 호출!')
            return num1+num2
        }

        const result = sum(10, 3)
        console.log(result)
        console.log('--------------')
       
        // 함수와 메모리
        const add = sum
        console.log(sum(10, 3)) // 같은 메모리를 사용하므로, 같은 값이 나옴
        console.log(add(10, 3))
        console.log('--------------')
       
        // 함수 작성팁
        // 조건식이 있을 때, 조건을 만족하지 않는 경우 함수 도입부분에서 함수를 미리 종료
        function print(num){
            if(num <= 0 ) return
            console.log(num)
        }
       
        print(10)
        print(-5)   // 그냥 리턴만시키고, 찍히는 건 없음
        console.log('--------------')
       
        // 매개변수의 기본값
        // 매개변수의 기본값은 무조건 undefined
        // undefined와의 연산은 NaN
        // arguments: 함수의 전달된 인수에 해당하는 Array 형태의 객체
        function total(num1=0, num2=0){
            console.log(num1)   // 0
            console.log(num2)   // 0
            console.log('arguments: ', arguments)
            console.log('arguments[1]: ', arguments[1]) // arguments[1]:  undefined
            return num1+num2
           
        }
       
        console.log(total())    // NaN
        console.log(total(10, 3))  
        console.log('--------------')
       
        // 콜백 함수
        const calc_add = (a, b) => a+b
        const calc_multiply = (a, b) => a*b
        console.log(calc_add(10, 5))
        console.log(calc_multiply(10, 5))
       
        function calculater(num1, num2, action){    // action은 함수를 받을 곳
            if(num1 < 0 || num2 < 0) return // 걸러낼거 있으면 먼저 걸러내라
           
            const result = action(num1, num2)
            console.log(result)
            return result
        }
       
        calculater(4, 2, calc_add)  // calc_add의 메모리 주소만 보내면 됨
        calculater(4, 2, calc_multiply)  // calc_multiply 메모리 주소만 보내면 됨
        console.log('--------------')

        // 문제.
        // 특정 숫자를 입력하면 해당 숫자까지를 출력 함수
        // 예) 5를 입력하면 1 2 3 4 5를 출력
        // 특정 숫자를 입력하면 해당 숫자의 제곱을 출력 함수
        // 예) 4를 입력하면 16이 출력
        // 위 두개의 식을 함수로 만들고 두 함수의 기능을 모두 사용할 수 있는 iterate() 콜백함수를 만들어보자

        // const calc_list.sort(a,b) => {
        //     if(a>b) return 1
        //     if(a==b) return 0
        //     if(a<b) return -1

        // }
        // const calc_multiply = (a) => a*a
        // console.log(calc_list(10, 5))
        // console.log(calc_multiply(10, 5))
       
        // function iterate(num1, num2, action){    // action은 함수를 받을 곳
        //     if(num1 < 0 || num2 < 0) return // 걸러낼거 있으면 먼저 걸러내라
           
        //     const result = action(num1, num2)
        //     console.log(result)
        //     return result
        // }
       
        // calculater(4, 2, calc_list)  // calc_add의 메모리 주소만 보내면 됨
        // calculater(4, 2, calc_multiply)  // calc_multiply 메모리 주소만 보내면 됨

        function list(num){
            for(let i=1; i<=num; i++){
                console.log(i)
            }
        }

        function square(num){
            console.log(num**2)
        }

        function iterate(num, action){
            action(num)
        }

        iterate(5, list)
        iterate(3, square)
        console.log('--------------')
       
        // 원시값과 객체값의 비교
        // 원시값: 값에 의한 복사
        // 객체값: 참조에 의한 복사(메모리 주소)
        function display(num){
            num = 10
            console.log(num)
        }
       
        const value = 5
        display(value)      // 10
        console.log(value)  // 5
       
        function displayObj(obj){
            obj.age=13          // 객체의 값을 변경하는 것은 좋지 못함 🤢🤢
            console.log(obj)
        }
        console.log('--------------')
       

        const dog={name:'루시', age: 14}    // 원래 전체 메모리에 있는 값을 변경하는데에 사용하는 것은 비추천
        // displayObj(dog)    
        console.log(dog)    

        function changeAge(obj){
            return { ...obj, age: 13}        // ...은 obgect를 복사한다는 뜻
        }

        dog2 = changeAge(dog)
        console.log(dog2)
        </script>
</body>
</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>객체 활용법</title>
</head>
<body>
    <h2>객체 활용법</h2>
    <script>
        let dog = {
            name: '루시',
            age: 14,
            'dog-weight': 3.5,  // 특수문자로 지정하고 싶으면 따움표를 사용해서 지정하자
            ['dog-height']: 0.8 // 혹은 대괄호를 사용하자
        }

        console.log(dog.name)
        console.log(dog['age'])

        dog.family = '포메라니안' //프러퍼티를 추가
        console.log(dog.family)
        console.log(dog['family1'])
       
        delete dog['dog-height']        // undefined
        console.log(dog['dog-height'])  // undefined
        console.log('---------------')
       
        // 동적으로 속성에 접근하기
        function getValue(obj, key){
            // dog.name
            return obj[key]
        }
        console.log(getValue(dog, 'name'))  // 루시
       
        function addKey(obj, key, value){
            obj[key] = value
        }
        addKey(dog, 'dog-height', 0.7)
        console.log(dog)        // {name: '루시', age: 14, dog-weight: 3.5, family: '포메라니안', dog-height: 0.7}
       
        function deleteKey(obj, key){
            delete obj[key]
        }
        deleteKey(dog, 'dog-height')
        console.log(dog)        // {name: '루시', age: 14, dog-weight: 3.5, family: '포메라니안'}  # dog-height: 0.7이 날라감
        console.log('---------------')
       
        // 객체 생성 함수 만들기
        const x=0
        const y=0
        const coord = {x, y}
        console.log(coord)      // {x: 0, y: 0}     # [[Prototype]]:Object
       
        function makeObj(name, age){
            return {name, age}
        }
        console.log(makeObj('apple', 20))       // {name: 'apple', age: 20}     name, age는 key이고 apple 20은 값
        console.log('---------------')
       
       
        const apple = {
            name: 'apple',
            display: function(){
                console.log(`${this.name}: 🍓`)
            }
        }
       
        const lemon = {
            name: 'lemon',
            display: function(){
                console.log(`${this.name}: 🍋`)
            }
        }
       
        console.log(apple)      // {name: 'apple', display: ƒ}
        apple.display()         // apple: 🍓
        console.log(lemon)      // {name: 'lemon', display: ƒ}
        lemon.display()         // lemon: 🍋
        console.log('---------------')
       
        // Fruit 생성자를 만들고 위와 같은 결과를 동일하게 출력할 수 있는 객체를 만들어 출력해보자.
        // 단, Fruit(name, emoji) 형태로 만든다.


        // const Fruit(name, emoji) = {
        //     Fruit.name: (`${this.name}`),
        //     Fruit.display: function(){
        //         console.log(`${this.name}: 🍓`)
        //     }
        // }

        // const lemon = {
        //     name: 'lemon',
        //     display: function(){
        //         console.log(`${this.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 lemon2 = new Fruit('lemon', '🍋')

        console.log(apple2)      // Fruit {name: 'aple', emoji: '🍓', display: ƒ}
        apple2.display()         // apple: 🍓
        console.log(lemon2)      // Fruit {name: 'lemon', emoji: '🍋', display: ƒ}
        lemon2.display()         // lemon: 🍋
       
        </script>
</body>
</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>클래스 심화</title>
</head>
<body>
    <h2>클래스 심화</h2>
    <script>
        // static
        // 정적 프로퍼티 및 메소드를 생성(new처럼 생성시기를 마음대로 조절 가능:동적, 시기를 정할 수 없고 미리 정해진 크기를 프로그램이 실행되면 올라가는 것)
        // 클래스 레벨 static을 사용한 메소드에서는 this를 참조할 수 업슴. 메모리를 먼저 올라가기 때문에 같이 올려놓을 수 없음
       
        class Fruit {
            static count_fruits = 10        // this를 쓰지 않음. 객체를 만들면 그 메모리 주소를 만듬 먼저 메모리에 올라갔기 때문에, this를 활용할 수 없음

            constructor(name, emoji){
            this.name = name
            this.emoji = emoji
        }
        display = () => {
                console.log(`${this.name}: ${this.emoji} `)
        }

        static makeBanana(){
            return new Fruit('banana', '🍌')
        }
    }

    const apple = new Fruit('apple', '🍓')
    const lemon = new Fruit('lemon', '🍋')
    console.log(apple)      // Fruit {name: 'apple', emoji: '🍓', display: ƒ}
    console.log(apple.name) // apple
    console.log(lemon)      // Fruit {name: 'lemon', emoji: '🍋', display: ƒ}
    console.log(lemon.name) // lemon

    console.log(Fruit.count_fruits)     // 10

    const banana = Fruit.makeBanana()
    console.log(banana)     // Fruit {name: 'banana', emoji: '🍌', display: ƒ}
    console.log('----------------------------')



    class Dog {                 // 객체 지향프로그램에서는 프러퍼티를 직접접근하면 문제가 생길 수 있음
        #name
        #color        // private되어 있는 변수들은 접근이 불가능하고,
        constructor(name, color){
            this.#name = name
            this.#color = color
        }
       
        // 프러퍼티명과 꼭 일치할 필요는 없음 // set을 이요해서, 해당값을 직접 넣는다.
        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}는 먹습니다.`)
        }

        myEat = () => {
            this.#eat()     // 프라이빗한 메소드는 내부에서 사용불가하므로, 다른 메소드에서 불러오고 출력
        }
    }

    const Rucy = new Dog('루시', 'white')
    console.log(Rucy)       // Dog {name: '루시', color: 'white'}
    // Rucy.name = '류씨'      // 여기의 name은 새로만들어져서 저장되고, 실제로 쓰는 변수는 아님
    // Uncaught SyntaxError: Private field '#name' must be declared in an enclosing class
    // Rucy.#name = '류씨'      
    console.log(Rucy)       // Dog {name: '류씨', color: 'white'}
    Rucy.name = '류씨'
    console.log(Rucy)       // Dog {#name: '류씨', #color: 'white'}
    console.log(Rucy.name)     // 이름:류씨  // 해당 프러퍼티명처럼 불러주면됨
    Rucy.run()      // white 색상의 강아지 류씨가 달립니다.
    // Rucy.eat()      // Uncaught TypeError: Rucy.eat is not a function
    Rucy.myEat()     // 류씨는 먹습니다.
    console.log('----------------------------')


    // 문제.
    // 카운터 만들기
    // 카운터를 0으로 값을 초기화 한 뒤 하나씩 숫자를 증가할 수 있는 메소드를 구현
    class Counter {
        #value
        constructor(value){
            if(isNaN(value) || value<0) {       // 숫자가 아니면 true
                this.#value = 0
            }else{
                this.#value = value
            }
        }
        get value(){
            return this.#value
        }
        increment = () => {
            this.#value++
        }
    }

    const cnt = new Counter(0)
    console.log(cnt.value)
    cnt.increment()    // 1
    cnt.increment()    // 2
    console.log(cnt.value)
    // 문제부분 다시 보기
    </script>
</body>
</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>상속의 활용</title>
</head>
<body>
    <h2>상속의 활용</h2>
    <script>
        class Animal {
            constructor(color){
                this.color = color
            }
            eat() {
                console.log('먹는다!')
            }
            sleep() {
                console.log('잔다!')
        }
    }

    class Dog extends Animal {
        play(){
            console.log('논다!')
        }
    }

    const Rucy = new Dog('white')
    console.log(Rucy)   // Dog
    Rucy.eat()          // 먹는다!
    Rucy.sleep()        // 잔다!    // 부모의 메소드를 그대로 활용할 수 있음, 상속받음
    Rucy.play()         // 논다!
    console.log('----------------------------')
   
    class Cat extends Animal{   // Animal 의 기능을 상속받자
        constructor(color, name){
            super(color)
            this.name = name
        }
        // 오버라이딩
        eat(){
            console.log('맛있게 먹는다!')
        }
    }
    const Horang = new Cat('black', '호랑이')
    console.log(Horang)     // Cat {color: 'balck', name: '호랑이'}
    Horang.eat()            // 맛있게 먹는다!
    console.log('----------------------------')

    // 문제.
    // 정직원, 알바를 나타낼 수 있는 클래스를 생성
    // FullTimeEmployee, PartTimeEmployee
    // 직원의 정보는: 이름, 부서명, 한달 근무 시간
    // 급여: 정직원(2만원), 알바(1만원)
    // 매달 직원들의 정보를 이용해서 한달 급여를 계산하는 메소드를 구현 (calculatePay())
    // 예) kim.calculatePay() -> 한달 급여

    class Employee {
        constructor(name, department, hoursPerMonth, payRate){
            this.name = name
            this.department = department
            this.hoursPerMonth = hoursPerMonth
            this.payRate = payRate
        }
        calculatepay(){
            return this.hoursPerMonth * this.payRate
        }
    }

    class FullTimeEmployee extends Employee{        // extends는 상속받다
        static PAY_RATE = 20000
        constructor(name, department, hoursPerMonth){
            super(name, department, hoursPerMonth,
            FullTimeEmployee.PAY_RATE)
        }
    }

    class PartTimeEmployee extends Employee{        // extends는 상속받다
        static PAY_RATE = 10000
        constructor(name, department, hoursPerMonth){
            super(name, department, hoursPerMonth,
            PartTimeEmployee.PAY_RATE)
        }
    }

    const Kim = new FullTimeEmployee('김사과', '개발자', 160)        
    const Oh = new PartTimeEmployee('김사과', '디자이너', 100)
    console.log(Kim.calculatepay())        
    console.log(Oh.calculatepay())        
    </script>  
</body>
</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>Wrapper</title>
</head>
<body>
    <h2>Wrapper</h2>
    <script>
        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

        // 지수 표기법(10의 n승으로 표기)
        const x = 102
        console.log(x.toExponential())  // 1.02e+2

        // 반올림하여 문자열로 변환
        const x2 = 1234.12
        console.log(x2.toFixed())   // 1234

        // 로컬형식의 문자형으로 변환
        console.log(x2.toLocaleString('ar-EG')) // ١٬٢٣٤٫١٢ 아랍어로 변환

        const x3 = 0.1 + 0.2 - 0.2
        console.log(x3)     // 0.10000000000000003

        console.log(globalThis)     // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
        // window객체가 찍히는 것은, 웹 에이피아이, javascript가 어는 환경에서 실행되는지 알려줌
       
        const encoded = encodeURI(URL)
        console.log(encoded) // https://%EC%BD%94%EB%A6%AC%EC%95%84%EC%95%84%EC%9D%B4%ED%8B%B0%EC%95%84%EC%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))

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