국비학원 34일차 : JavaScript, TypeScript, Node.js

Digeut·2023년 4월 12일
0

국비학원

목록 보기
28/44
<!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>
    <link rel="stylesheet" href="./naver-sign-in.css" /> <!--스타일시트를 따로 css로빼서 적용--><script>
        const onSubmitHandler = (/*매개변수*/) => { /*구현부*/
            const id = document.getElementById('id').value; 
            /*아이디 요소를 가져올수있다*/
            /*console.log(id);
            console.log(id.trim());*/
            if(!id.trim/*문자열 앞뒤 공백 제거*/()){ 
            //id가 빈문자열이면?이라는 조건문
                /*js는 문자열로 논리연산자 쓸수있다?*/
                document.getElementById('sign-in-error').style.display = 'block';
                return;
            }
            document.getElementById('sign-in-error').style.display = 'none'; /*입력하면 다시 경고문구 사라지게 해준다*/

            const form = document.getElementById('form');
            form.submit(); //실제 네이버 로그인 화면으로 넘어가게된다
        }</script>
</head>
<body>
    <!--Header-->
    <div class="header">
        <!--header-inner-->
        <div class="header-inner">
            <a href="https://naver.com" class="logo">
                <h1 class="blind">NAVER</h1>
            </a>
            <div class="lang">
                <select class="select">
                    <option>한국어</option>
                    <option>English</option>
                </select>
            </div>
        </div>
    </div>

sign-in-wrapper 내에 form이라는 id를 추가하여 아이디 요소를 가져올 수 있다.

    
    <!--Main-->
    <div class="main">
        <div class="content">
            <!--로그인 wrapper-->
            <div class="sign-in-wrapper">
                <form ⭐id="form" action="https://nid.naver.com/nidlogin.login" method="POST">
                    <ul class="panel-wrapper">
                        <li class="panel-item"> <!--li가 뭐지-->
                            <div class="panel-inner">
                                <!--ID password wrapper-->
                                <div class="id-password-wrapper">
                                    <div class="input-row">
                                        <div class="icon-shell">
                                            <span class="icon-id">
                                                <span class="blind">아이디</span>
                                            </span>
                                        </div>
                                        <input type="text" class="input-text" maxlength="41" placeholder="아이디" name="id" id="id" />
                                    </div>
                                    <div class="input-row">
                                        <div class="icon-shell">
                                            <span class="icon-pw">
                                                <span class="blind">비밀번호</span>
                                            </span>
                                        </div>
                                        <input type="password" class="input-text" maxlength="16" placeholder="비밀번호" name="pw" id="pw" />
                                    </div>
                                </div>
                                <!--sign In Keep wrapper-->
                                <div class="sign-in-keep-wrapper">
                                    <div class="keep-check">
                                        <input type="checkbox" class="input-keep" value="off"/>
                                        <label class="keep-text">로그인 상태 유지</label>
                                    </div>
                                    <div class="ip-check"></div>
                                </div>

ign in error 추가해서 아이디를 다 입력하지 않고 로그인 버튼을 누르면 경고문구가 보이도록 javaScript구문 생성 id를 sign-in-error로 설정
button도 기존의 submit타입에서 일반 버튼타입인 button으로 변경 (submit으로 해두면 경고문구가 뜨기 전에 실제 로그인 화면으로 넘어가게 되어있어서 바꿈)

<!--Sign in error-->
                                <div id="sign-in-error" class="sign-in-error" style="display:none;">
                                    <div class="error-message">
                                        <strong>아이디</strong>를 입력하세요
                                    </div>
                                </div>
                                <!--sign In button wrapper-->
                                <div class="sign-in-button-wrapper">
                                    <button ⭐type="button" class="sign-in-button" onclick="onSubmitHandler()">
                                        <span class="button-text">로그인</span>
                                    </button>
                                </div>
                            </div>
                        </li>
                    </ul>
                </form>
            </div>


아이디 입력란에 공란으로 로그인 버튼 누르면 '아이디를 입력하세요'라는 문구가 수행되게 진행했다.

javaScript의 활용을 위해서 Node.js 설치 후 버전 확인

JavaScript_Basic

console.log('Hello JacaScript!');

// 한줄 주석
/* 부분 주석 */ 

//일반적인 연산은 자바와 유사함
// 변수 선언 방법
// 1. 변수의 타입이 존재하지 않는다 
//      선언할때 타입을 지정하지 않는다
// data의 타입은 있는데, 변수의 타입은 없다.
var variable_name; //선언 , ;없어도 되지만 그냥 찍는 습관 들이기
var variable_name = '변수 값'; //선언과 동시에 초기화
console.log(variable_name.trim());
variable_name = 10; 
//var과 let 모두 동일하게 데이터 타입을 지정하지않고, 
//출력할수있고 타입의 변경도 그냥 된다. 변수의 타입이 없다.
//console.log(variable_name.trim()); 
//문자열이 아닌 숫자에 대해서는 trim이라는 메서드가 없기때문에 
//오류가 뜬다. 이걸 미리 알수가 없다 → javaScript의 문제점

// 2. 변수 선언 키워드
// 2-1 var, let, const
var variable_name; 
//변수 이름이 중복 허용이 된다? var의 문제점 
if(10==10){
    var variable_name2 = '변수';
}
console.log(variable_name2); 
//코드블록 내에 지역변수로 선언을 했는데 밖에서도 실행이 된다. 

let let_variable_1;
// let let_variable_1; 
//let으로는 중복허용이 불가! var의 문제를 해결, 
//let : 블록변수 키워드 선언된 동일블럭 내에서 
//중복허용불가하고 블록내에서만 적용 (기존 자바 변수선언처럼)

if(10 == 10){
    let let_variable_2 = '블럭 변수';
}
//console.log(let_variable_2); 
//let 사용해서 선언하면 블럭 밖에서 호출 불가, 오류뜬다

const const_variable_1 = '상수'; 
//선언과 동시에 초기화해줘야한다. 
//자바에서는 final로 선언후 초기화가능한데, 이건 무조건 초기화까지!
//const_variable_1 = '변경 상수'; //이것도 오류로 뜬다. 상수는 변경되지 않는다. 
//컴파일 기능이 없기때문에 바로 확인할수가 없다

// 3. 데이터의 타입
// 자바는 컴파일 언어라서 각각 타입들이 있는데 기본적으로 숫자형태
// js 에서는 정수 실수를 나누지 않는다. 
//num타입, null 타입, undefined 타입 ...등이 있다.

// 3-1 문자열 string : '' 또는 "" js에서 string은 참조변수가 아니므로 소문자로표현
let stringVariable = '문자열';
let stringVariable2 = "문자열";
// html상에서 script용으로 쓸때는 low_sanke_case로 하지만 
//node로 개발언어로써 사용할때는 lowCamelCase로 사용!
// css에서는 하이픈으로 띄어쓰기 다 표시한다
console.log(typeof(stringVariable,stringVariable2)); //string
//typeof : 타입을 반환해준다 , js에서 오류를 대비해서 
//if안에 typeof써서 조건 걸어서 사용가능

// 3-2 숫자 number : 정수, 실수 모두 포함 
let numberVariable = 10;
let numberVariable2 = 1.5;
console.log(typeof(numberVariable,numberVariable2)); //number

// 3-3 논리 boolean : true, false
let booleanVariable = true;
console.log(typeof(booleanVariable)); //boolean

// 3-4 null
let nullVariable = null; 
console.log(typeof(nullVariable)); //object
//object로 출력되지만 null타입이 있다고 생각해주기

// 3-5 배열 : []
let arrayVariable = [1, 'A', false]; 
//js에서는 배열 내 동일한 타입만 올 필요없다 , type는 object
arrayVariable[0]; 
//자바에서는 get사용해서 값을 보여주는데 js는 이렇게 사용

// 3-6 객체 : {}
let objectVariable = { 
// java에서는 객체 만드려면 클래스 만들어서 작성해야하는데 
// js는 바로 만들수있다.
    /**키 : 값 , 형태로 나열 : json구조**/
    "key" : "value",
    "name" : "John",
    "age" : 20,
    "object" : {
        "key1" : 1
    }
};

//웹상에서 네트워크통신을 할때 객체형태로 보내거나 받아야한다면 json형태로 사용된다

// 4. 연산자 (java와 다른 점만 기술)
// 4-1 나눗셈 연산자 
let number1 = 10 / 3; 
//실수정수 타입이 존재하지않아서 바로 실수로 답이 나온다
console.log(number1); //3.3333333333333335

// 4-2 제곱 연산자 (**)
let number2 = 10 ** 3;
console.log(number2); //1000

// 4-3 비교연산 ==, === 이 다 다른 의미
let numberValue10 = 10;
let stringValue10 = '10';
console.log(numberValue10 == stringValue10); 
//true , 데이터의 타입은 비교하지않고 문자열을 숫자로 바꾸거나 
// 숫자를 문자로 바꿔서 서로 비교
console.log(numberValue10 === stringValue10); 
//false, 데이터의 타입까지 비교를 해서 다르면 다르다고 뜬다.

// 5. if 조건 / 논리연산의 항에 대한 이야기
let tmpValue = null; 
// js에서 문자열의 경우 빈 문자열은 false, 공백이든 다른 문자값은 true
//숫자도 0은 false, 0을 제외한 모든 값들은 true
// 빈 배열, 빈 객체는 true 
//⭐0과 빈문자열을 false인데 배열과 객체는 왜 true? 
// → 참조 주소값이 들어가서 참조변수 형태로 존재하므로 true로 나오게된다.
//⭐object에서는 false를 표현할수 없나? 
// → 값이 0이거나 없으면 false로 인식한다. 
// !참조변수에 값이 없는 것=null!

if(tmpValue) console.log('true');
else console.log('false'); //false (tmpValue = null이므로)
//if조건 자리에 boolean이 아닌 모든 타입의 변수가 올 수 있다.

// 6. javaScript의 class
// 객체지향을 지원을 한다(제어자는 존재하지 않는다)
class Human{
    name; //인스턴스 변수
    age;
    address;
    //메서드는 사용안된다.
    //생성자를 오버로드해서 만드는건 불가
    constructor(name,age,address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
    // constructor(age){
    //     this.age = age; -> 오류뜬다
    // } js에서는 하나의 생성자만 가질수 있다.
}
// js는 일반적으로 class기반으로 돌아가지는 않는다. 객체를 정의한 설계도에 가깝다
// 바로 {}해서 생성가능하기 때문에 잘 쓰진 않지만, 
// 틀에 맞게 작성하겠다는 조건이 있다면 사용하기도 한다.
let humanObject = new Human('John', 30, '부산'); 
// 이렇게 자바처럼 할수 있지만 잘 안쓴다
console.log(humanObject.name); //John
console.log(humanObject.nema); //'undefined' 이라는 결과가 출력
//console.log(HumanObject.nema.trim()); 
//undefined이라 trim을 사용할수 없다는 오류뜸

// js의 객체를 편하게 다룰수 있는 방법 : 비구조화 할당

// 7. 비구조화 할당
//const { name, age, address } = humanObject ; 
// java에서 dto를 통해서 데이터를 주고받을때 
// 그 값을 하나씩 꺼내오게되는데 
// js는 비구조화 할당으로 바로 받을수있다.
let { name, ...others } = humanObject; 
// ... : spread 연산자
console.log(name); //John
console.log(others); //{ age: 30, address: '부산' }

name = 'Micle';
humanObject = { ...humanObject, name }; 
//객체 내부에서 ...하면 하나씩 다 분해가 된다
//{name, age, address}로 다 분해해서 넣은다음 {name, age, address, name}을 해준것.
//spread 이용한 경우 요소가 중복이 될 때 
// 뒤에 오는 것으로 덮어씌우고 처음 요소를 날려버리게 된다.
console.log(humanObject); //{ name: 'Micle', age: 30, address: '부산' }

const tmpArray = [1, 'A', true];
const [number, ...otherArray] = tmpArray;
console.log(number); //1
console.log/**이건 메서드**/(otherArray); //[ 'A', true ]

// 8. 함수선언
//js에서는 함수라고한다. java에서는 method
//인스턴스 내부나 클래스 내부에 있으면 method. 
//그 밖에 있으면 함수 function이라고 한다
function function1 (arg, arg2){ //함수도 반환타입 지정하지 않는다

}

function1(1,2); //호출하는 방식

//변수의 타입이 없다 = 변수에 저장할수 있는 메모리 공간이 한정되어 있지않다 
//함수도 변수에 들어갈수 있나? 변수처럼 선언해서 쓰고싶다 
// → 화살표 함수라는걸로 들어가게 할수있다.
const function2 = (arg1, arg2) => {/**구현부**/ //콜백 형태}
function2(1,2);

비구조화 할당(destructuring assignment)

자바스크립트에서 변수에 배열이나 객체의 값을 할당하는 방법 중 하나입니다. 이 기능을 사용하면 배열이나 객체의 각 요소를 쉽게 분리하여 변수에 할당할 수 있습니다.

배열에서 비구조화 할당을 사용하여 각 요소를 변수에 할당할 수 있습니다.

const arr = [1, 2, 3];
const [a, b, c] = arr;

console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

객체에서 비구조화 할당을 사용하여 각 속성을 변수에 할당할 수도 있습니다.

const obj = { x: 1, y: 2, z: 3 };
const { x, y, z } = obj;

console.log(x); // 1
console.log(y); // 2
console.log(z); // 3

이러한 방법으로, 변수에 객체나 배열의 값을 빠르고 쉽게 할당할 수 있습니다.

javaScript에서 함수

자바스크립트에서 함수(function)는 일급 객체(first-class object)로 취급됩니다. 이는 함수가 변수에 할당되거나, 다른 함수의 인자로 전달되거나, 다른 함수의 반환값으로 사용될 수 있음을 의미합니다. 함수는 기본적으로 다음과 같은 형태로 정의됩니다.

function functionName(parameter1, parameter2, ...) {
  // 함수 본문
  return returnValue;
}

함수는 함수 이름과 함수 매개변수(parameter) 목록으로 구성됩니다. 함수 본문은 중괄호({})로 감싸진 코드 블록입니다. 함수는 이 본문에 작성된 코드를 실행하고, 필요한 값을 반환할 수 있습니다.

함수를 호출할 때는 다음과 같이 함수 이름과 함께 인자(argument) 값을 전달합니다.

functionName(argument1, argument2, ...);

함수는 이러한 인자를 받아들이고, 함수 본문에서 이 인자를 사용하여 작업을 수행할 수 있습니다.

함수는 다양한 방법으로 정의할 수 있습니다. 함수 표현식(function expression)과 화살표 함수(arrow function)는 ES6에서 추가된 기능 중 하나입니다. 이러한 함수 정의 방법은 다음과 같습니다.

// 함수 표현식
const functionName = function(parameter1, parameter2, ...) {
  // 함수 본문
  return returnValue;
}

// 화살표 함수
const functionName = (parameter1, parameter2, ...) => {
  // 함수 본문
  return returnValue;
}

화살표 함수

화살표 함수(arrow function)는 ES6에서 추가된 함수 정의 방법 중 하나입니다. 기존의 함수 정의 방법보다 간결하게 함수를 정의할 수 있으며, 함수 내부에서의 this 키워드 처리 방식이 다르다는 특징이 있습니다. 다음은 화살표 함수의 예시입니다.

// 기존의 함수 정의 방법
function square(x) {
  return x * x;
}

// 화살표 함수로 변환
const square = (x) => x * x;

화살표 함수는 다음과 같은 특징을 가집니다.

  1. 함수 표현식과 유사한 형태를 가집니다.
    function 키워드 대신 => 연산자를 사용하여 함수를 정의합니다.
  2. 함수 본문이 단일 표현식인 경우 중괄호({})를 생략할 수 있습니다.
    이 경우, 해당 표현식의 결과값이 함수의 반환값이 됩니다.
  3. 인자가 하나인 경우, 괄호를 생략할 수 있습니다.
  4. ⭐this 키워드 처리 방식이 다릅니다.
    화살표 함수 내부에서 this 키워드를 사용하면, 해당 함수를 포함하는
    외부 스코프의 this 값을 그대로 사용합니다.
// 인자가 하나인 경우
const double = x => x * 2;

// 인자가 두 개인 경우
const sum = (x, y) => x + y;

// 중괄호를 사용한 복수 표현식
const log = message => {
  console.log(message);
  console.log(new Date());
}
// 외부 스코프의 this 값을 그대로 사용하는 예시
const person = {
  name: 'John',
  sayHi: function() {
    // 일반 함수 내부에서의 this 키워드는 person 객체를 가리킵니다.
    console.log(`Hi, my name is ${this.name}`);
  },
  sayHiArrow: () => {
    // 화살표 함수 내부에서의 this 키워드는 상위 스코프의 this 값을 그대로 사용합니다.
    console.log(`Hi, my name is ${this.name}`);
  }
}

위 코드에서 person 객체는 sayHi 메소드와 sayHiArrow 메소드를 가지고 있습니다. sayHi 메소드는 일반 함수로 정의되어 있기 때문에, 함수 내부에서 사용되는 this 키워드는 해당 메소드를 호출한 객체인 person 객체를 가리킵니다. 따라서 this.name은 person.name과 동일한 값을 가집니다.

반면에 sayHiArrow 메소드는 화살표 함수로 정의되어 있기 때문에, 함수 내부에서 사용되는 this 키워드는 해당 화살표 함수가 속한 상위 스코프의 this 값을 그대로 사용합니다. 즉, sayHiArrow 메소드가 속한 person 객체의 외부 스코프에서의 this 값을 그대로 사용합니다. ⭐이 경우, sayHiArrow 메소드가 속한 객체는 person 객체가 아닌 전역 객체를 가리키게 되며, 따라서 this.name은 undefined 값을 가집니다.

따라서 일반적으로 객체의 메소드를 정의할 때에는 화살표 함수보다는 일반 함수를 사용하는 것이 좋습니다.

Scope

Scope(스코프)는 변수나 함수 등의 식별자(identifier)가 유효한 범위를 말합니다. 즉, 스코프는 변수나 함수가 선언된 위치에 따라 그들이 유효한 범위가 결정되며, 해당 범위를 벗어나면 그들에 접근할 수 없게 됩니다.

자바스크립트에서는 전역 스코프(global scope)와 지역 스코프(local scope)로 나뉘며, 스코프는 함수 단위로 생성됩니다. 즉, 함수 내부에서 선언된 변수는 해당 함수의 지역 스코프(local scope)에서만 유효하며, 함수 외부에서 선언된 변수는 전역 스코프(global scope)에서 유효합니다.

// 전역 스코프에서의 변수 선언
const globalVar = 'Global variable';

function foo() {
  // 지역 스코프에서의 변수 선언
  const localVar = 'Local variable';
  
  console.log(globalVar); // 'Global variable'
  console.log(localVar); // 'Local variable'
}

foo();

console.log(globalVar); // 'Global variable'
console.log(localVar); // ReferenceError: localVar is not defined

위 코드에서 globalVar 변수는 전역 스코프에서 선언되었으므로, foo() 함수 내부와 외부에서 모두 사용할 수 있습니다. 반면에 localVar 변수는 foo() 함수 내부에서만 선언되었으므로, 함수 외부에서는 사용할 수 없습니다.

TypeScript_Basic

console.log('Hello Typescript');

// 변수
var number: number; //변수타입 변수명 : 데이터 타입 ; 까지가 선언
number = 10;
//number = 'string';

let string = 'string'; //초기화 할때 들어오는 데이터 타입으로 맞춰지게 된다
//string = 10;

// 함수
const funtion = (/**매개변수 받을적에는 any 포함 형태 만들면 안된다*/ arg:number):string => {
    //상수 변수 타입 설정해놓고 function으로 변수명 설정하니까 빨간줄 떴다. funtion으로 설정해서 하면 안뜸
    return string; //지정한 문자열을 return해줘야한다
};
const myFunction = (arg: number): string => {
  return arg.toString(); // arg를 string으로 변환하여 반환합니다.
};

const result = myFunction(10); // result 변수에는 "10"이 할당됩니다.

myFunction 함수는 number 타입의 인수를 받아 해당 값을 문자열로 변환하여 반환하고 있습니다. 이 함수를 호출할 때 인수로 10을 전달하면, 반환값으로 "10"이 생성됩니다. 이 값을 result 변수에 할당할 수 있습니다.

// 객체
// 1. class 이용
class Object1 {
    prop1: string;
    prop2: number;

    constructor(prop1: string, prop2: number){ //생성자를 따로 만들어서 사용해줘야한다 -> 귀찮다?
        this.prop1=prop1;
        this.prop2=prop2;
    };
};

const object1: Object1 = {prop1 : 'prop1', prop2 : 2};

Object1 클래스는 prop1과 prop2라는 두 개의 멤버 변수를 가지고 있으며, 생성자 함수를 통해 이 변수들을 초기화하고 있습니다.

object1 변수는 Object1 타입의 객체를 할당받고 있습니다. 이 객체는 prop1과 prop2 프로퍼티를 갖고 있으며, prop1 값으로는 문자열 'prop1'을, prop2 값으로는 숫자 2를 각각 할당받고 있습니다.

하지만 위 코드에서 object1은 Object1 클래스의 인스턴스가 아닙니다. 이는 TypeScript에서 타입이 일치하지 않기 때문입니다. 따라서 object1에는 prop1과 prop2의 값만 할당되고, Object1 클래스의 메서드나 프로퍼티를 사용할 수 없습니다.

//2. type 키워드 사용
type Object2 = {
    prop1: string,
    prop2: number
}
const object2: Object2 = {prop1 : 'prop1', prop2 : 2};

Object2는 객체 타입을 정의하는 인터페이스와 유사한 형태를 가진 타입 별칭(Alias)입니다.

Object2는 prop1과 prop2라는 두 개의 프로퍼티를 가지고 있으며, prop1의 값으로는 문자열, prop2의 값으로는 숫자를 각각 할당받고 있습니다.

object2 변수는 Object2 타입의 객체를 할당받고 있습니다. 이 객체는 prop1과 prop2 프로퍼티를 갖고 있으며, prop1 값으로는 문자열 'prop1'을, prop2 값으로는 숫자 2를 각각 할당받고 있습니다.

//인터페이스를 이용해서 쓰이는 규칙 그대로 가져올수있다?
// 3. interface 활용
interface Object3 {
    prop1 : string;
    prop2 : number;
    func1?/**필수가 아닌애로 만들어준다 */: (arg1: number) => string; 
    //인터페이스에서 메서드를 선언만 하고 싶을땐 함수의 타입만 지정할수있다. 선언부만 작성할 수 있다.
}
const object3: Object3 | null = null; //ts에서는 null을 넣으려면 | 사용해서 받을 수 있다. java에서는 됐나...객체에

Object3는 객체 타입을 정의하는 인터페이스입니다. 이 인터페이스는 prop1과 prop2라는 두 개의 필수 프로퍼티를 가지고 있으며, func1이라는 선택적 프로퍼티를 가지고 있습니다.

func1 프로퍼티는 (arg1: number) => string 타입의 함수를 값으로 가질 수 있습니다. 이 함수는 arg1이라는 숫자형 매개변수를 받고, 문자열을 반환합니다.

object3 변수는 Object3 타입 또는 null 타입 중 하나의 값을 가질 수 있습니다.

이 코드에서 object3는 null로 초기화되어 있기 때문에, object3는 null 값을 가지고 있습니다.

interface Object4 {
    prop3: string;
    prop4: number;
}
//ts는 타입을 합칠수 있다. 
const object4 : Object3 & Object4 = {prop1 : 'prop1', prop2 : 2, prop3 : 'prop3', prop4 : 4}

첫 번째 인터페이스(Object3)는 prop1, prop2, 그리고 func1이라는 세 개의 속성(property)을 가지고 있습니다. 그리고 func1은 number 타입의 인자를 받아 string을 반환하는 함수입니다. 하지만 func1은 선택적(optional)으로 정의되어 있기 때문에, object4를 정의할 때 func1을 생략할 수 있습니다.

두 번째 인터페이스(Object4)는 prop3, prop4라는 두 개의 속성을 가지고 있습니다.

그리고 const 키워드를 사용하여 object4라는 객체를 선언하고 있습니다. 이 객체는 Object3와 Object4 인터페이스의 속성들을 모두 가지고 있어야 하므로 '&' 연산자를 사용하여 두 인터페이스를 합친 타입을 지정해주었습니다. 즉, prop1, prop2, prop3, prop4 속성을 가지고 있습니다.

profile
개발자가 될 거야!

0개의 댓글