자바스크립트(3) & Node.js(1)

이지우·2024년 6월 14일
0

멋사

목록 보기
5/16

객체

생성 방법

// 방법1
let dic = new Object();	

dic.boy = '소년';
dic.girl = '소녀';
dic.friend = '친구';


// 방법 2
let dic = {
    boy: '소년',
    girl: '소녀',
    friend: '친구'
};


// 자바와 달리 멤버 추가/삭제/수정이 자유로움
dic.apple = '사과';
dic.ten = 10;

delete dic.girl;

dic.boy = '청년';

console.log(dic.boy);
console.log(dic['boy']);	// 이렇게도 가능
// !''로 씌워주어야 함
// 프로퍼티에 띄어쓰기 넣기 가능

객체 데이터 관리 방법

const 키워드로 선언한 객체의 프로퍼티 값을 추가하거나 삭제, 변경이 가능함

  • 객체 자체의 주소 값은 const 형식으로 재할당이 불가능
  • 하지만 객체의 데이터는 다른 주소에 저장되어있는 값이기 때문에 객체 주소에는 영향을 미치지 않으므로 추가, 변경, 삭제가 가능함

여러 객체 생성 방식

const unit = {
    attack: function (weapon){
        return `${weapon}으로 공격한다.`;
    }
  /*attack (weapon){
        return `${weapon}으로 공격한다.`;
    }*/
  // 이렇게 표현도 가능
};

console.log(unit);  // 객체
console.log(unit.attack);   // 객체 프로퍼티
console.log(unit.attack('총')); // 객체 메서드 호출 결과값

객체 생성할 때 프로퍼티 키를 대괄호로 표시할 경우

rl.question('무조건 천원! 상품 입력? ', function(obj){
    let basket = {
        [obj] : "1000원",
    }
    console.log(basket[obj]);
	// 무조건 1000원 출력
  
    rl.close();
})

프로퍼티 키와 값의 이름이 같아도 됨

let id = 'jamsu';
let pw = '1111';

let user = {
    id : id,
    pw : pw
  // 이때 값 부분 생략 가능
  /*id,
  	pw*/
}

console.log(user.id);
console.log(user.pw);

// 하나씩 꺼내서 출력하기
for(let info in user){
    console.log(`${info} : ${user[info]}`);
}

화살표 함수

수행 컨텍스트가 달라질 때 화살표 함수 사용으로 편하게 사용 가능


function plus(a, b){
  return a + b;
}

// 이름 없는 function을 변수에 할당
let plus = (a, b) =>{
	return a + b;
}

// 매개변수 하나일 경우 괄호 생략 가능
let plus = a => a+1;	

// 매개변수가 없는 경우 빈괄호 표시
let plus = () => 2+1;	
let obj = {
    myVar: 'foo',
  
    myFunc: function(){
        let self = this;	// object의 주소가 self에 할당됨
        console.log(this.myVar);    // 수행 컨텍스트가 obj
        
        setTimeout(function(){
            console.log(this.myVar);// 수행 컨텍스트가 window
        }, 1000);
      
      	setTimeout(function(){
            console.log(self.myVar);// 수행 컨텍스트가 obj
        }, 1000);
      	
      // self 변수에 주소 할당하여 사용하는것을 함수로 만든 것이 bind(this)
      	setTimeout(function(){
            console.log(this.myVar);
        }.bind(this), 1000);		// 수행 컨텍스트가 obj
      
      // 수행 컨텍스트가 달라질 때 화살표 함수 사용으로 편하게 사용 가능
      	setTimeout(() => {  // 화살표 함수, function() 객체가 만들어질 때 this를 바인딩
            console.log(this.myVar);// 수행 컨텍스트가 obj
        }, 1000);
    }
}
obj.myFunc();   // foo   undefined   foo

어떤 객체에 귀속되는 함수(메소드) 마들 때는 프로퍼티에 할당되는 함수를 function 키워드로 만들기

나머지는 콜백함수는 화살표 함수로 만드는게 베스트

let obj = {
    myVar: 'foo',

    myFunc: function(){
        console.log(this.myVar);    // 수행 컨텍스트가 obj
      
      	setTimeout(() => {  
            console.log(this.myVar);// 수행 컨텍스트가 obj
        }, 1000);
    }
}

obj.myFunc(); 

비구조화 할당

배열의 요소나 프로퍼티를 변수에 할당하여 사용

const color=['red', 'green', 'blue'];
let [r, g, b] = color;
// [r, g, b]=['red', 'green', 'blue'];

console.log(r);
console.log(g);
console.log(b);

// 변수값 변경
[b, g, r] = [r, g, b]

배열에서 ...을 붙인 매개변수에 요소 여러개 넣기 가능

const [a, b, ...rest] 
= ['C#', 'javascript', 'python', 'react', 'C++'];
console.log(a);
console.log(b);
console.log(rest.length);	// 3
console.log(rest[0]);
console.log(rest[1]);
console.log(rest[2]);
console.log(rest);	// [ 'python', 'react', 'C++' ]
// 배열 결합
const arr1 = ['C#', 'javascript'];
const arr2 = ['python', 'react', 'C++'];
const arr3 = [...arr1, ...arr2];

console.log(arr3);	
// [ 'python', 'react', 'C++' ]

console.log([arr1, arr2]); 
/*  [ [ 'C#', 'javascript' ],
	  [ 'python', 'react', 'C++' ] ]*/

객체의 프로퍼티

let {id, pw, name} 
	= {id: 'a', pw: 'b', name: 'c', age: 30};
// 이때 age는 사용할 수 없음

프로미스

function c(){
    console.log('c');
}
function b(){
    console.log('b');
}
function a(){
    console.log('a');
}

setTimeout(a, 3000);    // 3초 뒤에 a 실행
setTimeout(b, 2000);    // 2초 뒤에 b 실행
setTimeout(c, 1000);    // 1초 뒤에 c 실행
// 예상: 3초 뒤 a 출력, 2초 뒤 b 출력, 1초 뒤 c 출력(동기)
// 실제 실행 결과: c b a 1초 간격으로 출력 (비동기)

setTimeout(function(){
    console.log('a');
}, 3000);
setTimeout(function(){
    console.log('b');
}, 2000);
setTimeout(function(){
    console.log('c');
}, 1000);
// 같은 결과

-> a b c 순서로 나오게 하려면?

setTimeout(function(){
    console.log('a');
    setTimeout(function(){
        console.log('b');
        setTimeout(function(){
            console.log('c');
        }, 1000);
    }, 2000);
}, 3000);

콜백이 너무 많고 가독성 떨어짐

프로미스를 사용하여 의도하는 순서대로 실행 가능

var pro1 = new Promise(function(resolve, reject){   
  // resolve: 정상, reject: 비정상
    if(true)    // 서버에 갔다온 시점 / 결과 올때까지 기다리고 결과가 있으면 then으로 넘어감
        resolve(1); // then 안의 함수 실행됨
    else    reject();
});

pro1
    .then(function(value){ // true일 때
        console.log(value);     // 후속작업
    })
    .catch(function(){  // false일 때
        console.log(2);
    });

flag 변수로 매개변수에 따라 resolve/reject결과 출력

function f(flag){
    return new Promise((resolve, reject) => {   
        if(flag){
          resolve(1); 
        }else{
          reject('처리 오류');
        }
    });
}

const prom = f(false);	

prom
    .then(function(value){ 
        console.log(value);     
    })
    .catch(function(errMsg){  
        console.log(errMsg);
    });

프로미스를 이용하여 a b c 순서로 나오도록

function f(flag, time){
    return new Promise((resolve, reject) => {   
        if(flag){
            setTimeout(resolve, time);
        }else{
            reject('처리 오류');
        }
    });
}

f(true, 3000)
    .then(function(){ 
        console.log('a');     
        return f(true, 2000);   // then을 한번 더 쓰기 위함
    })
    .then(function(){
        console.log('b');
        return f(true, 1000);
    })
    .then(function(){
        console.log('c');
    })
    .catch(function(errMsg){  
        console.log(errMsg);
    });

Node.js

  • v8 엔진 사용
  • 비동기 이벤트 기반의 런타임
const http = require('http');   // core 라이브러리에 있는 http 모듈 가져옴

const server = http.createServer((req, res)=>{
    res.statusCode = 200;   // 정상
    res.setHeader('Content-Type', 'text/html');	// html 사용 위함
    res.end('<h1>Hello World<h1>');
});

server.listen(3000, "127.0.0.1", () => {
    console.log("server ready...");
});
  • express 모듈을 깔아두어서 위 코드를 작성하지 호출하여 사용

  • 라이브러리 매니저가 있으면 패키지를 가져오기 편함
    -> npm로 install

  • 코드가 업데이트 될때마다 서버를 다시 켜줘야하는데 nodemon을 사용하면 코드 변경이 있을 때 자동으로 적용해줌

const express = require('express');
const app = express();

app.listen(3000, function(){
    console.log('server ready...');
});

get 요청 처리

app.get('/book', function(req,res){
    res.send('도서 목록 관련 페이지입니다.')
});

실습

서버 코드

const express = require('express');
const app = express();

app.listen(3000, function(){
    console.log('server ready...');
});

app.get('/', function(req,res){
    res.sendFile(__dirname + '/index.html');
});

app.get('/inputUser', function(req,res){
    res.sendFile(__dirname + '/inputUser.html');
});

app.get('/userInfo', function(req,res){
    res.sendFile(__dirname + '/userInfo.html');
});

3개의 페이지 구성

root

Navbar의 Home, 회원 정보 등록 클릭 시 페이지 이동이 가능하도록 href="/", href="/inputUser" 속성 추가

  • bootstrap에서 가져온 코드에는 href="#"로 작성되어 있었음
  • 클릭 시 실행내용은 없지만 페이지 최상단으로 이동한다는 의미
  • 최상단으로도 이동하지 않게 하려면 href="#none" 또는 href="#;"로 작성

inputUser

  • 입력값에 대한 유효성 검사는 넣지 않음
  • 가입하기 버튼 클릭 시 등록 알림창 띄워짐
  • 다시 작성 버튼 클릭 시 입력 내용 초기화
<form action="">
  <fieldset>
    <legend>개인정보 입력</legend>
    이름:<br>
    	<input type="text" name="name"><br><br>
    비밀번호:<br>
    	<input type="password" name="pw"><br><br>
    E-mail:<br>
    	<input type="text" name="email"><br><br>
    연락처:<br>
    	<select name="ntype">
    	<option>KT</option>
    	<option>SK</option>
    	<option>LGU+</option>
    	<option>자급제</option>
    	</select> <input type="text" name="n1" size="3"> - <input type="text" name="n2" size="4"> - <input type="text" name="n3" size="4"><br>
    <br>
    성별 : <input type="radio" name="gender" value="남성"><input type="radio" name="gender" value="여성"><br>
    <br>
    취미 : <input type="checkbox" name="hobby" value="운동">운동 <input type="checkbox" name="hobby" value="독서">독서
    <input type="checkbox" name="hobby" value="여행">여행 <input type="checkbox" name="hobby" value="음악감상">음악감상<br>
    <br>
    본인 소개:<br>
    <textarea name="mes" cols="100" rows="3"></textarea>
    <hr>
    <div style="text-align: center;">
    <input type="button" id="submit" value="가입하기">
    
    <input type="reset" value="다시작성">
    </div>
  </fieldset>
</form>
<script>
  function sub(){
    alert('등록되었습니다.');
    document.location = "userInfo";
  }

  submit.addEventListener('click',sub);
</script>
  • form 태그 안에 작성 할 경우 fieldset으로 내용 필드를 생성할 수 있음

  • 이때 legend로 이 필드의 제목 작성 가능

  • radio: 단일선택

  • checkbox: 다중선택

  • textarea: 긴 내용 작성 가능한 칸

  • div 안에 style을 text-align: center;로 지정하여 가운데 정렬

  • form 태그 안에서 input type을 reset으로 지정하면 적은 내용 삭제 버튼 생성됨

  • 가입하기 버튼 클릭 시 '등록되었습니다.' 문구가 띄워지고 userInfo 페이지로 넘어가도록 함수 작성

  • document.location으로 현재 페이지를 userInfo로 변경 가능

userInfo

profile
노력형 인간

0개의 댓글