오늘은 JSON, AJAX에 대해서 배워보겠습니다
목차 | |
1. | parameter |
2. | non-standard |
3. | JSON |
4. | AJAX |
5. | 예제 문제 |
6. | 느낀점 |
1. parameter
<!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>
<h1>
parameter (파라미터)
</h1>
<ul>
<li>
파라미터 개수 관계없이 사용 가능 함수(메서드) 이름이 호출될 때 전달 사용
</li>
<li>
파라미터의 개수가 2개 / 실제 값이 1개처럼
파라미터의 개수가 불일치하여 받지 못하는 값이 있다면
undefined 처리
</li>
<li>
값을 받아오지 못하는 파라미터가 undefined 처리가 되는 걸 막기 위해
기본값을 설정할 수 있음 => optional parameter
</li>
<li>
모든 파라미터는 arguments라는 프로퍼티를 이용하여 파라미터를 관리
배열로 담겨서 관리
</li>
<li>
optional parameter는 arguments에 저장되지 않음
</li>
<li>
optional parameter는 다른 파라미터보다 뒤에 있어야 한다. (가장 끝에 존재가능)
</li>
<li>
rest parameter : 남는(이외의, 여분의) 파라미터
</li>
<li>
사용할 파라미터는 일반 파라미터로 배정하고 나머지 파라미터들을 통합하여 하나의
이름으로 배정하는 기법
</li>
<li>
... : spread 연산자라고 하여, 배열, 객체를 복제하는데도 사용함.
</li>
</ul>
<script>
function testFun(p1, p2, p3, p4 = 0, p5 = 0){
console.log(p1, p2, p3, p4, p5);
console.log(arguments);
return p1 + p2 + p3 + p4 + p5;
}
console.log(testFun(1,2,3));
console.log(testFun(1,2,3));
console.log(testFun(1,2)); // NaN
function restFun(a,b, ...others){
console.log(a,b);
console.log(others);
others.forEach(function(e){
console.log(e);
});
}
restFun(1,2,3,4,5,6,7,8,9);
console.log("-------");
let oldArr = ['a','b','c','d'];
let newArr = [...oldArr]; //... 배열복사 기능도 있음
console.log(oldArr);
console.log(newArr);
let newObj = {...oldArr};
console.log(newObj);
let num = [1,2,3,4,5,6,7,8,9];
function sum(a,b, ...others){
let s = a+b;
others.forEach((e)=>{
s += e;
})
return s
}
console.log(sum(...num));
</script>
</body>
</html>
▷ 출력
2. non-standard
<!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>
<h1>
비표준 속성(non-standard attribute)
</h1>
<ul>
<li>
html 태그의 종류에 따라 속성들이 제한적
개발자들이 직접 속성을 만들어서 사용할 수 있는 방법을 제공
</li>
<li>
너무 과도하면 개발 효율성과 가독성 저하, 적당히 사용하는 것을 권장
</li>
<li class="list" data-name="가나다">
data-변수명="${값}"
data-변수명 : 속성명
${값}이 value로 인지할 수 있도록 설계되어 있음
</li>
<li class="list" data-Age="20" data-item="listItem">
읽어 올 때 : dataset.변수명 값이 리턴됨
dataset property를 사용하여 읽어들임
</li>
<li>
변수명에 대문자는 허용 안 함
dataset.Age(인지 못함) dataset.age(인식 가능)
대문자를 사용하더라도 소문자로 변환하여 읽기 가능
</li>
</ul>
<script>
// querySelector('css선택자') : 처음 만나는 값을 인지
// querySelector('css선택자') : 모든 값을 인지
// All은 값이 하나더라도 배열로 인지
let li_list_tag = document.querySelectorAll('.list');
console.log(li_list_tag);
console.log(li_list_tag[0].dataset.name);
console.log(li_list_tag[1].dataset.Age); // 대문자 인식 못함. undefined
console.log(li_list_tag[1].dataset.item);
</script>
</body>
</html>
▷ 출력
3. JSON
<!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>
<h1>
JSON(JavaScript Object Notation) : 자바 스크립트의 객체 표기법
</h1>
<ul>
<li>
데이터 요청 및 응답처리에 필요한 데이터의 표준 형식을 제공하는 타입
</li>
<li>
백엔드(서버)언어 종류에 상관없이 데이터를 송수신 단말형식으로 통일
</li>
<li>
백엔드(서버)에서는 무조건 String 처리 - 화면(javaScript)는 Object로 처리
</li>
<li>
화면에서 서버로 데이터를 보낼 때 >
Object > String => JSON.stringify(jsObject)
</li>
<li>
서버에서 화면으로 데이터를 받을 때 >
String > Object => JSON.parse(StringData)
</li>
</ul>
<script>
// '{name: value, name2:value2}' => object > string 변환
// {name: value, name2:value2} => string > object 변환
const cake ={
id:'1234',
type: 'donut',
name: 'cake',
image:{
url: 'img/001.jpg',
width: '200',
height: '20'
},
thumbnail:{
url: 'img/th/001.jpg',
width: '20',
height: '5'
}
}
console.log(cake);
// cake를 string으로 변환
let cakeString = JSON.stringify(cake);
console.log(cakeString);
console.log(typeof cakeString);
// {"id":"1234","type":"donut","name":"cake","image":{"url":"img/001.jpg","width":"200","height":"20"},"thumbnail":{"url":"img/th/001.jpg","width":"20","height":"5"}}
// 서버에서 온 string => object로 변경
let stringData ='{"id":"1234","type":"donut","name":"cake","image":{"url":"img/001.jpg","width":"200","height":"20"},"thumbnail":{"url":"img/th/001.jpg","width":"20","height":"5"}}';
let parseData = JSON.parse(stringData);
console.log(parseData);
// 콘솔에 key:value 형식으로 출력
// for in 사용하여 추출
// object[keyName] = value 추출
for(let keyName in parseData){
if(keyName == 'image' || keyName == 'thumbnail'){
for(let key in parseData[keyName]){
console.log(key + ":" + parseData[keyName][key]);
}
}else{
console.log(keyName + ":" + parseData[keyName]);
}
}
</script>
</body>
</html>
▷ 출력
4. AJAX
<!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>
<h1>
비동기 통신(asynchronous communication) : AJAX
AJAX (asynchronous Javascript And Xml) : javaScript와 xml을 이용한 비동기 정보교환기법
</h1>
<ul>
<li>
데이터 통신 방식 : 동기, 비동기
</li>
<li>
동기방식(synchronous)
동시에 일어나는 방식
동기 방식으로 요청을 하면 페이지로 리턴
<form>동기방식</form>
순차적임
</li>
<li>
비동기방식(asynchronous)
동시에 일어나지 않는 방식
비동기 방식으로 요청을 하면 string(json)으로 리턴(data만 리턴)
순차적이지 않음 그자리에서 결과가 바로 주어지지 않을 수도 있음
</li>
<li>
동기와 비동기의 장단점
</li>
<li>
동기 방식 : 직관적, 설계가 간단하다
결과가 주어지기 전까지는 아무것도 못하고 페이지가 오기를 대기해야 한다는 단점이 있음.
</li>
<li>
비동기 방식: 설계가 복잡하다
결과가 주어지는데 시간이 걸리더라도, 다른 작업을 할 수 있어 효율적임.
</li>
<li>
비동기 방식 : AJAX 방식 사용
</li>
</ul>
<ul>
<li>
async 키워드 : 함수 선언 앞에 붙이는 키워드 (async function(){})
</li>
<li>
await 키워드 : 순차적으로 코드가 실행되어야 할 때 사용
순차코드 실행을 보증
지연로딩, 지연 상황이 발생되면 코드 실행이 순차적으로 진행될 수 있도록 보증한다
이전 라인의 코드 실행이 완료될 때까지 다음 라인은 기다릴 수 있도록 하는 기능
</li>
<li>
async await : 비동기 통신 키워드
</li>
<li>
Promise 객체를 생성 / 이용하여 데이터 통신을 편리하게 할 수 있도록 한다.
</li>
<li>
http://jsonplaceholder.typicode.com/todos
</li>
</ul>
<h3>async await 연습</h3>
<button type="button" id="btn">데이터 불러오기</button>
<ul id="ul"></ul>
<script>
document.getElementById('btn').addEventListener('click', ()=>{
asyncFun().then(result=>{
console.log(result);
// 여기서 처리
printData(result);
});
});
function printData(result){
document.getElementById('ul');
let str = '';
for(let key in result){
str += `<li>${key} : ${result[key]}</li>`;
}
ul.innerHTML = str;
}
async function asyncFun(){
try{
const resp = await fetch('http://jsonplaceholder.typicode.com/todos/1');
const result = await resp.json(); //body에 내가 요청한 데이터를 싣어줌 => json() 형태로 리턴
console.log(resp);
console.log(result);
return result;
} catch (error){
console.log(error);
} finally{
console.log("await finish");
}
}
</script>
</body>
</html>
▷ 출력
◈ promise chain
<!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>
<h1>
promise chain 방식
</h1>
<ul>
<li>
promise 객체를 리턴하여 값을 가져오면 then 메서드를 실행하여 실행 순서를 기다리게 할 수 있다
</li>
<li>
fetch(url, [config]) : 데이터 통신을 위해 제공되는 함수 url, 통신에 필요한 정도
config(header에 적용되는 각종 정보를 설정) : 내가 데이터를 보낼 때 사용
</li>
<li>
then : promise 객체를 리턴하는 함수
메서드를 기다려서 리턴값이 만들어지면 다음 로직으로 연결하는 기능
</li>
</ul>
<button type="button" id="btn">데이터 가져오기</button>
<ul id="ul">
</ul>
<script>
document.getElementById('btn').addEventListener('click', ()=>{
fetch('http://jsonplaceholder.typicode.com/todos/2')
.then(resp => resp.json())
.then(result => {
console.log(result);
printData(result);
}) // 성공시
.catch(err => console.log(err)); // 실패시
})
function printData(result){
document.getElementById('ul');
let str = '';
for(let key in result){
str += `<li>${key} : ${result[key]}</li>`;
}
ul.innerHTML = str;
}
</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>Document</title>
</head>
<body>
<button id="btn">데이터 가져오기</button>
<ul id="ul"></ul>
<script>
//http://jsonplaceholder.typicode.com/todos/1 ~ 5번까지 5개의 데이터를 li로 출력
let num = 0;
let str = '';
document.getElementById('btn').addEventListener('click', ()=>{
for(let i = 1; i <= 5; i++){
num ++;
asyncFun(num).then(result=>{
console.log(num);
// 여기서 처리
printData(result);
});
}
});
function printData(result){
document.getElementById('ul');
for(let key in result){
str += `<li>${key} : ${result[key]}</li>`;
}
ul.innerHTML = str;
}
async function asyncFun(N){
try{
const resp = await fetch(`http://jsonplaceholder.typicode.com/todos/${N}`);
const result = await resp.json();
console.log(resp);
return result;
} catch (error){
console.log(error);
} finally{
console.log("await finish");
}
}
</script>
</body>
</html>
▷ 출력
5. 예제 문제
◎ 문제
▶ 1번
◎ 정답
▶ 1번
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="09_style.css">
</head>
<body>
<div class="calculator">
<form action="" name="froms">
<input type="text" id="output">
<button type="button" class="clear" value="C">C</button>
<button type="button" class="operator" value="/">/</button>
<button type="button" value="1">1</button>
<button type="button" value="2">2</button>
<button type="button" value="3">3</button>
<button type="button" class="operator" value="*">*</button>
<button type="button" value="4">4</button>
<button type="button" value="5">5</button>
<button type="button" value="6">6</button>
<button type="button" class="operator" value="+">+</button>
<button type="button" value="7">7</button>
<button type="button" value="8">8</button>
<button type="button" value="9">9</button>
<button type="button" class="operator" value="-">-</button>
<button type="button" class="dot" value=".">.</button>
<button type="button" value="0">0</button>
<button type="button" class="operator result" value="=">=</button>
</form>
</div>
<script>
const output = document.getElementById('output');
let outputValue = '';
function operation(f, o, l){
let result = 0;
switch(o){
case "+": result = f + l; break;
case "-": result = f - l; break;
case "*": result = f * l; break;
case "/": result = f / l; break;
}
return result.toFixed(2);
}
function extractValue(strValue){
// string 13.5 + 12.3 = 연산자와 피연산자로 나누기
console.log(strValue);
let firstNum = strValue.substring(0, strValue.indexOf(" "));
let operator = strValue.substr(strValue.indexOf(" ")+1, 1); // 시작번지부터 1개
let lastNum = strValue.substring(strValue.lastIndexOf(" ")+1); // 마지막 공백부터 끝까지
console.log(firstNum, operator, lastNum);
// 계산값 호출
return operation(parseFloat(firstNum), operator, parseFloat(lastNum));
}
document.querySelector('.calculator').addEventListener('click', (e)=>{
// console.log(e.target); // 내가 선택한 객체
// console.log(e.target.value); // 내가 선택한 객체의 value 값
// console.log(typeof e.target.value);
// eval 함수 : 절대 사용하면 안 됨.
// NaN => op로 사용
let btnVal = e.target.value;
output.value += btnVal;
if(!isNaN(btnVal)){ // 버튼의 값이 숫자라면...
outputValue += btnVal;
}else{
// 숫자가 아닐 때
// + - * / . = C undefined(addEventListener 여백 클릭 시)
if(btnVal != undefined){
switch(btnVal){
case ".":
// 숫자에 붙어서 소수점 역할을 하기.
outputValue += btnVal;
break;
case "C":
// output 창을 지우기
outputValue = '';
output.value = '';
break;
default:
// 사칙연산 + - * / =
let sub = ''; // 결과를 받을 변수
if(btnVal == '='){
// 연산의 결과를 호출(function 작업)
sub = extractValue(outputValue); // 결과값 리턴
outputValue = sub;
}else{
outputValue += ` ${btnVal} `;
// string 13.5 + 12.3 =
// 이후 function 작업으로 피연산자와 연산자로 분리시킴
}
break;
}
}
}
output.value = outputValue;
});
</script>
</body>
</html>
- CSS
body{
background-color: beige;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.calculator{
border: 1px solid black;
background: linear-gradient(#C6FFDD, #FBD786, #f7797d);
padding: 5px;
}
.calculator form{
display: grid;
/* 65px 65px 4개*/
grid-template-columns: repeat(4,65px);
grid-auto-rows: 65px;
gap: 5px;
}
.calculator form button, input{
font-size: 15px;
border: 2px solid black;
cursor: pointer;
padding: 5px;
}
.calculator form button:hover{
box-shadow: 1px 1px 2px black;
}
.calculator form input{
grid-column: span 4;
font-weight: 700;
background-color: white;
text-align: right;
}
.calculator form .clear{
background: linear-gradient(#f12711, #f5af19);
grid-column: span 3;
font-size: 20px;
}
.calculator form .operator{
background: linear-gradient(#e1eec3, #f05053);
}
.calculator form .result{
background: linear-gradient(#ee0979, #ff6a00);
grid-column: span 2;
}
.calculator form .dot{
background: linear-gradient(#FF5F6D, #FFC371);
}
6. 느낀 점
배열 안에 객체가 있거나 객체 안에 배열이 경우 또는 배열과 객체가 반복적으로 들어가 있을 때 향상된 for의 for of, for in 어떤 것을 사용해야 할 지 헷갈리기도 하였다. 그래서 중간중간에 막히는 경우도 많았다. 향상된 for에 대해서 복습을 집중적으로 해야겠다.
'Front-end > Js' 카테고리의 다른 글
Js 기초(event)- AWS 풀스택 과정 24일차 (0) | 2024.08.16 |
---|---|
Js 기초(BOM, DOM, classList)- AWS 풀스택 과정 23일차 (0) | 2024.08.14 |
Js 기초(class)- AWS 풀스택 과정 21일차 (0) | 2024.08.12 |
Js 기초(set, map)- AWS 풀스택 과정 20일차 (0) | 2024.08.09 |
Js 기초(array)- AWS 풀스택 과정 19일차 (0) | 2024.08.08 |