1. Delete - remove(), empty(), removeAttr()

위와 같이 실행한다.
순서대로 클릭해 remove(), empty(), removeAttr()의 역할을 알아보자
실행하기 전 태그는 아래와 같이 나온다.

1) remove()

remove를 사용하면 <p> 태그 자체가 사라진 것을 볼 수 있다.
2) empty()

empty()는 태그는 남기고 태그 안의 내용만 제거한다.
3) removeAttr()

removeAttr()은 remove()나 empty()와 달리 괄호 안에 제거하려는 속성을 입력해주면 된다.
여기서는 removeAttr("sytle")로 작성해서 위와 같이 스타일 속성이 제거되었다.
2. 비동기 처리 방식 정리
이번에는 동기와 비동기 개념을 정리했다.
0-1) 동기
동기(Sync)는 작업을 순서대로 처리하는 방식이다. 앞의 작업이 끝나야 다음 작업이 실행된다.
예를 들어
| test1(); test2(); test3(); |
이렇게 작성하면
test1 실행 → test1 종료 → test2 실행 → test2 종료 → test3 실행 → test3 종료
이 순서로 진행된다. 즉, 하나가 끝나야 다음 작업으로 넘어간다.
동기 방식은 순서가 명확하다는 장점이 있지만, 앞 작업이 오래 걸리면 그만큼 뒤 작업도 계속 기다려야 한다.
0-2) 비동기(Async)
비동기(Async)는 앞의 작업이 끝날 때까지 기다리지 않고 다음 작업도 함께 진행하는 방식이다.
같은 코드라도 비동기 상황에서는
test1 실행 → test2 실행 → test3 실행 → test1 종료 → test2 종료 → test3 종료
처럼 처리될 수 있다.
즉, 실행은 먼저 시작했더라도 끝나는 순서는 달라질 수 있다.
비동기 통신은 여기서 더 자주 사용된다. 비동기 통신은 페이지 전체를 다시 불러오지 않고, 필요한 데이터만 뒤에서 주고받는 방식이다.
즉, 화면이 아예 안 바뀌는 것이 아니라 페이지 전체는 그대로 두고 필요한 부분만 바꿀 수 있다.
예를 들어 댓글 목록만 다시 불러오거나, 좋아요 수만 바꾸거나, 검색 결과만 갱신하는 경우가 비동기 방식에 가깝다.
반대로 동기 방식은 요청을 보내면 응답이 끝날 때까지 기다리는 느낌이 강하고, 경우에 따라 페이지가 통째로 다시 바뀌거나 이동할 수 있다.
정리하면 동기는 순차 처리, 비동기는 동시에 진행 가능한 처리 방식이라고 볼 수 있다.
동기는 앞 작업이 끝나야 다음 작업을 실행하고, 비동기는 앞 작업이 끝나지 않아도 다음 작업을 실행할 수 있다.
또 비동기 통신은 화면이 전혀 바뀌지 않는 방식이 아니라, 페이지 전체를 새로고침하지 않고 필요한 부분만 바꾸는 방식이라고 이해하면 된다.
동기는 앞 작업이 끝나야 다음 작업을 실행하고, 비동기는 앞 작업이 끝나지 않아도 다음 작업을 실행할 수 있다.
1) 동기/비동기

위 코드를 보면 동기와 비동기를 확인할 수 있다.
동기는 순서대로 실행1 → 실행2 → 실행3 이렇게 실행되고
비동기는 setTimeout() 으로 3초 뒤에 실행2가 실행되어 실행1 → 실행3 → 실행2 순서이다.
| sum(22,33,(val) => {console.log(`sum: ` + val);}); console.log("sum 실행 완료!"); |
이 코드는 sum() 함수를 호출하면서
22, 33, 그리고 결과를 받아 출력할 콜백 함수를 함께 넘긴다.
즉, sum() 함수가 계산을 끝내면 그 결과값을 (val) => {console.log("sum: " + val);} 이 함수가 받아서 출력하는 구조이다.
| setTimeout(()=>{ let sum = no1 + no2; call(sum);},2000); |
그 다음 함수를 보면
setTimeout(() => { ... }, 2000);를 사용해서
안쪽 코드가 2초 뒤에 실행되도록 만들었다.
즉, sum() 함수가 호출되면 바로 덧셈을 하는 것이 아니라,
2초 뒤에 no1 + no2를 계산하고 그 결과를 콜백 함수에 넘기는 구조이다.
안쪽 코드를 보면
let sum = no1 + no2;
call(sum);
이렇게 작성되어 있기 때문에, 2초가 지난 뒤 22 + 33을 계산해서 55를 만들고, 그 값을 call(sum);으로 콜백 함수에 전달하게 된다.
즉, 이전처럼 setTimeout()이 빈 함수만 예약하는 구조가 아니라,
이번에는 실제 계산과 콜백 실행 자체가 2초 뒤로 미뤄진 비동기 코드라고 볼 수 있다.
그래서 실행 순서는
- sum 실행 완료!
- (2초 뒤) sum: 55
처럼 보이게 된다.
이번 sum() 함수는 setTimeout() 안에서 계산을 수행하고 있기 때문에,
결과가 바로 나오지 않고 2초 뒤에 콜백 함수를 통해 전달되는 비동기 함수이다.
2) promise()

버튼을 하나 더 만들어주었다.
인라인 방식으로 버튼을 누르면 test2() 함수가 실행된다.
설명을 순서대로 하면:
- 버튼 클릭 시 test2() 실행
- new Promise(...)
비동기 작업 하나를 만든다. - setTimeout(..., 2000)
2초 뒤에 안쪽 코드를 실행 - resolve
promise가 성공했을 때 결과값을 넘겨준다. - reject
promise가 실패했을 때 에러를 넘겨준다.
const로 no에 10을 저장한다. 만약 숫자이면 resolve, 숫자가 아니면 reject가 실행된다.
10은 숫자이기 때문에
resolve(no + 10)이 실행되고
아래 promise.then(value) value 값에 20이 저장된다.
성공: resolve → then(value)
실패: reject → catch(error)
Promise는 비동기 작업을 처리하기 위한 객체이다.
비동기 작업은 바로 결과가 나오지 않을 수 있기 때문에,
Promise는 그 작업의 결과뿐만 아니라 현재 상태까지 함께 관리한다는 점이 특징이다.
Promise가 가지는 상태는 크게 세 가지이다.
- 대기(pending) : 아직 작업이 끝나지 않은 상태
- 성공(fulfilled) : 작업이 정상적으로 완료된 상태
- 거부(rejected) : 작업이 실패한 상태
즉, Promise는
비동기 작업이 아직 진행 중인지, 성공했는지, 실패했는지를 구분해서 처리할 수 있게 해주는 객체라고 볼 수 있다.
여기서 resolve는 작업이 성공했을 때 결과값을 넘겨주는 역할을 하고, reject는 작업이 실패했을 때 에러를 넘겨주는 역할을 한다.
그리고 Promise 뒤에 이어 붙는 then()과 catch()를 통해
성공한 결과와 실패한 결과를 각각 나누어 처리할 수 있다.
resolve → then()
reject → catch()
이 흐름으로 이해하면 훨씬 보기 쉽다.
Promise는 비동기 작업을 조금 더 구조적으로 다루고,
성공과 실패를 나누어 처리할 수 있도록 도와주는 객체이다.
3) async/await

3-1) async
먼저 버튼을 누르면 test3()이 실행된다.
| async function getData(){ return {name:"lee",id:"lcj"}; } console.log(getData()); |
여기서 중요한 건 getData()가 async 함수라는 점이다.
async를 붙인 함수는 안에서 그냥 객체를 return해도, 실제로는 Promise 형태로 반환된다.

즉, return {name:"lee", id:"lcj"}; 이렇게 써도 실제 반환은 왼쪽 사진처럼
Promise { <fulfilled>: {name:"lee", id:"lcj"} } 으로 된다.
| async function data2() { return new Promise((resolve) => { setTimeout(()=>{resolve({name:"lee",id:"lcj"})},1000); }); } |
이 함수는 1초 뒤에 resolve(...)가 실행되는 Promise를 반환한다.
- data2() 실행
- Promise 생성
- setTimeout()으로 1초 뒤 실행 예약
- 1초 뒤 resolve({name:"lee", id:"lcj"}) 실행
- Promise 성공 상태가 됨
즉, 이 함수는 1초 뒤에 데이터가 준비되는 비동기 함수라고 보면 된다.
그래서 바로 아래의 console.log(data2()); 를 실행하면, 아직 1초가 지나기 전이니까 결과 객체가 아니라 Promise 객체가 먼저 찍힌다.
| data2().then((result)=>{ console.log(result); }); |
data2()가 끝난 뒤, 즉 Promise가 성공적으로 처리된 뒤에 결과를 받는 부분이다.
- resolve(...)로 넘긴 값
- 그 값이 then((result) => ...)의 result로 들어간다
즉, 최종적으로 {name:"lee", id:"lcj"} 가 출력된다.

위 사진과 같이 실행되고 마지막 3번째 {name:"lee", id:"lcj"} 는 1초 뒤에 실행된다.
async가 붙은 함수는 일반 값을 반환해도 Promise 형태로 반환된다.
그래서 console.log(getData())나 console.log(data2())를 하면 결과 객체가 아니라 Promise 객체가 먼저 출력된다.
실제 결과값은 then()을 사용해서 Promise가 처리된 뒤 받아올 수 있다.
이번 코드에서는 data2()가 1초 뒤 resolve()를 실행하고, 그 값이 then((result) => ...)의 result로 들어가 최종적으로 객체가 출력되는 흐름이다.
3-2) await

먼저 prn() 함수는 async 함수이기 때문에 안에서 await를 사용할 수 있다.
| async function prn(){ console.log("prn 실행"); let res = await data2(); console.log(res); } |
이 함수가 실행되면 가장 먼저 "prn 실행"이 출력된다.
| let res = await data2(); |
그 후, 이 코드가 실행된다.
여기서 data2()는 Promise를 반환하는 함수이고,
await는 그 Promise가 끝날 때까지 기다렸다가 결과값을 받아 res에 저장하는 역할을 한다.
즉, 이 줄에서 prn() 함수 안의 다음 코드인
| console.log(res); |
는 바로 실행되지 않고, data2()가 끝난 뒤에 실행된다.
하지만 여기서 중요한 점은 await가 prn() 함수 안에서만 기다린다는 것이다.
프로그램 전체가 멈추는 것은 아니다.
그래서 prn();을 호출한 뒤 바로 아래에 있는
| console.log("prn() 호출 후 출력!!"); |
이 console.log(res);보다 먼저 실행된다
await는 함수 안에서만 기다리고, 함수 밖 코드는 멈추지 않기 때문에 "prn() 호출 후 출력!!"이 먼저 출력되는 것.
결과는 아래와 같다.

await는 Promise 결과를 받을 때까지 기다리게 해주는 키워드이지만,
그 기다림은 async 함수 내부에서만 적용된다.
즉, await를 썼다고 해서 아래 모든 코드가 멈추는 것은 아니고,
함수 바깥 코드는 먼저 실행될 수 있다.
3-2-1) async/await 실행 순서 확인

ㅇ
| function sum(a,b){ return new Promise((resolve) =>{ setTimeout(()=>{resolve(a+b);},2000); }); } |
- return new Promise(...)
나중에 결과를 줄 비동기 함수로 만듦 - resolve(a+b)
성공 결과로 합계를 넘김 - 그래서 sum()은 "합계값"이 아니라 "합계를 나중에 주는 약속(Promise)"을 반환함
이 sum() 함수는 a+b를 즉시 반환하는 게 아니라 2초 뒤에 결과를 주는 Promise 기반 비동기 함수.
| async function run(){ console.log("start"); const res = await sum(10,30); console.log(res); console.log("end"); } |
sum(10,30)의 결과가 나올 때까지 기다렸다가 순서대로 출력하는 함수이다.
- "start" 출력
- await sum(10,30) 실행
- sum()의 Promise가 끝날 때까지 기다림
- 결과를 res에 저장
- res 출력
- "end" 출력
40은 2초 뒤에 출력된다.
왜냐하면:
- await는 Promise가 끝날 때까지 기다리기 때문.
- 그래서 console.log("end")도 바로 실행되지 않고, res를 받은 뒤에 실행됨.
console.log("--before run()--");
run();
console.log("--after run()--");
먼저 "--before run()--"이 출력되고,
그다음 run()이 실행된다.
하지만 run() 안에는 await가 있기 때문에 결과를 기다리는 동안,
바깥쪽 코드인 "--after run()--"가 먼저 출력된다.
결과는 아래와 같다.


3. Ajax (Asynchronous JavsScript and XML)
Ajax 실습은 파일을 그냥 열면(file://) 브라우저 보안 정책 때문에 XML 데이터를 읽지 못할 수 있다. 그래서 Live Server처럼 로컬 서버 환경에서 실행해야 정상적으로 동작한다.
1) 입력한 사원번호로 XML 데이터 조회하기


위와 같이 HTML과 script를 작성해준다.
버튼을 클릭하면 함수가 실행된다.
| $(function(){ $("#emp_search").on("click", function(){ → 조회버튼을 클릭하면 함수 실행 let empid = $("input[name=empid]").val(); → #1 if(empid.length>2){ → #2 입력값 길이 검사 //ajax를 활용하여 데이터 가져오기 $.ajax({ → #3 ajax요청 url:"emplist.xml", //통신할 페이지 주소 method: "GET", //서버에 요청하는 방식 //data:{id:"lcj"} //서버에 요청할 때 전송할 데이터 dataType: "xml", //전송받을 데이터의 타입 //async:flase; //비동기요청인지 동기요청인지 결정 //false : 동기요청, true : 비동기요청(기본값) success: function(data){ → #4) 통신 성공했을 때 실행 let empInfo = $(data).find("EMPLOYEE_ID:contains("+empid+")").parent(); → #5) console.log(empInfo); //입력한 id를 가진 row 태그 if((empInfo).is("ROW")){ //입력한 id를 통해 검색되었는가 → #6) $("table input").each(function(i){ → #7) 표에 값 넣기 $(this).val( $(empInfo).children().eq(i).text() ); }); }else{ alert("검색대상이 존재하지 않습니다."); } }, error: function(){ //통신 실패했을 때 실행 alert("데이터 로드 실패") } }); }else{ alert("사원번호는 제대로 입력하세요."); } }); }) |
| <legend>사원 정보 조회</legend> <input type="text" name = "empid"> <input type="button" id="emp_search" value="조회"> |
#1)
empid 변수를 생성해서
| $("input[name=empid]").val() |
- input 태그 중에서
- name="empid" 속성을 가진 요소를 선택한다.
- 그리고 .val() 로 선택한 입력칸 안에 사용자가 입력한 값을 가져온다.
#2) 입력값 길이 검사
입력한 사원번호의 길이가 2보다 큰지 검사한다.
즉, 너무 짧게 입력했을 때는 조회되지 않도록 한 것이다.
조건을 만족하면 Ajax 요청을 보내고,
만족하지 않으면 아래의 alert가 실행된다.
| alert("사원번호는 제대로 입력하세요."); |
#3) Ajax 요청
이건 jQuery의 Ajax 메소드이다.
페이지 전체를 다시 새로고침하지 않고,
필요한 데이터만 비동기로 가져올 때 사용한다.
여기서는 emplist.xml 파일을 읽어오기 위해 사용했다.
url:"emplist.xml", → emplist.xml에 요청을 보낸다는 뜻이다.
method: "GET", → 요청방식은 get으로 HTML 공부할 때 form 태그에서 method="get" 방식을 자주 사용했었다. 기본설정이 get이다.
dataType: "xml", → 서버로부터 받을 데이터가 어떤 형식인지 지정하는 부분이다. 여기서는 XML 형식으로 응답을 받겠다는 뜻이다.
즉, Ajax가 받아온 데이터를 XML 형태로 처리할 수 있게 설정한 것이다.
세미콜론(;)이 아닌 콤마(,) 로 구분한다는 점 알아두자.
#4) 통신 성공했을 때 실행
Ajax 요청이 성공했을 때 실행되는 함수이다. 여기서 data는 서버에서 받아온 XML 전체 데이터이다.
즉, emplist.xml 파일 내용이 data 안에 들어온다고 생각하면 된다.
#5) 입력한 사원번호에 맞는 row 찾기
$(data) - Ajax로 받아온 XML 데이터를 jQuery 방식으로 다루기 위해 감싼 것이다.
.find("EMPLOYEE_ID:contains("+empid+")")
XML 안에서 EMPLOYEE_ID 태그 중 입력한 사원번호(empid)를 포함하고 있는 태그를 찾는다.
예를 들어 empid가 100이면 EMPLOYEE_ID 태그 안에 100이 들어 있는 부분을 찾는 것이다.
.parent() - 찾은 EMPLOYEE_ID 태그의 부모 태그를 선택한다.
여기서 부모는 보통 그 사원 한 명의 정보가 들어 있는 <ROW> 태그이다.
XML 파일 내부 데이터 중 일부로 확인해보면 쉽다.

즉, 입력한 사원번호를 가진 사원의 전체 정보 묶음(ROW)을 찾고, console.log()로 찾은 row를 출력한다.
실패했을 때는 아래의 에러가 실행된다.
| error: function(){ //통신 실패했을 때 실행 alert("데이터 로드 실패") |
#6)
empInfo가 실제로 ROW 태그인지 확인하는 조건문이다.
즉, 검색 결과가 존재하는지 검사하는 부분이다.
- 맞으면 검색 성공
- 아니면 검색 실패
#7) 표에 값 넣기
찾은 사원 정보를 아래 표의 input 칸에 하나씩 넣는 코드이다.
$("table input") - 테이블 안의 모든 input 태그를 선택한다.
즉, 사원번호 / 이름 / 이메일 / 전화번호 / 입사일 칸을 전부 가져온 것이다.
.each(function(i){ ... }) - 선택한 input 태그들을 하나씩 반복한다.
여기서 i는 순서 번호이다.
- 첫 번째 input → i = 0
- 두 번째 input → i = 1
- 세 번째 input → i = 2
이런 식이다.
$(this) - 현재 반복 중인 input 하나를 뜻한다.
$(empInfo).children().eq(i).text()
찾아낸 ROW 태그의 자식 요소들 중에서
i번째 요소의 텍스트를 가져온다.
- 첫 번째 자식 값 → 첫 번째 input에 넣기
- 두 번째 자식 값 → 두 번째 input에 넣기
- 세 번째 자식 값 → 세 번째 input에 넣기
이렇게 순서대로 값이 들어가는 구조이다.
.val(...) - 그 값을 현재 input 칸에 넣는다.
즉, XML에서 찾은 사원 정보를 아래 입력칸에 차례대로 채워 넣는 코드이다.
예시로 사원번호 100을 입력해 결과를 보게 되면 아래와 같다.

사원번호 100을 입력하면 아래 사진과 같이 row 태그를 선택해 반복문으로 내부 태그 하나하나 사원번호, 이름, 이메일, 전화번호, 입사일의 input 태그에 입력하는 것과 같다.

만약 emplist.xml 파일에 없는 사원번호를 입력하게 되면
| else{alert("검색대상이 존재하지 않습니다.");} |
가 출력된다.
이 코드는 조회 버튼을 누르면 입력한 사원번호를 기준으로 XML 데이터에서 해당 사원을 찾아, 그 정보를 아래 표의 input 칸에 자동으로 채워 넣는 Ajax 예제이다.
2) XML 전체 데이터를 테이블로 출력하기
아래와 같이 파일 두 개를 작성한다.
javascript 파일을 하나 만들어서 외부 스크립트 파일로 연결해준다.
js파일과 xml 파일은 아까 1번 예제와 달리 js 폴더를 만들어서 옮겨주었기 때문에
"js/create_table.js" , "js/emplist.xml" 로 연결해준다.


조회 버튼을 눌러주면 ajx 요청이 실행되는 구조이다.
| $(function(){ $("#emp_search").on("click",function(){ $.ajax({ → 비동기 요청을 보내 데이터를 가져옴 url: "js/emplist.xml", dataType : "xml", success:function(data){ → 1) 성공하면 data가뭔매개변수? let rowList = $(data).find("ROW"); XML 안에 있는 모든 ROW 태그를 찾음 let tab = makeTable(rowList); → create_table.js 안에 작성된 makeTable 함수로 ROW 목록을 HTML 테이블 형태로 만듦. $("body").append(tab); → 만들어진 table을 body의 맨 뒤로 추가 }, error:function(){ → 1) 실패하면 "데이터 로드 실패" alert("데이터 로드 실패"); } }); }); }) |
| create_table.js |
| function makeTable(rowList){ → let rowList = $(data).find("ROW"); 라고 이전 파일에서 미리 변수 지정함. //rowList : emplist.xml <ROW>들 //1. 테이블 생성 let $table = $("<table border=1>"); → border=1인 테이블 생성해 변수 $table에 넣기 //2. 1번째 tr태그 생성(칼럼의 이름 가져오기) let $tr = $("<tr>"); → 행 생성해서 변수 $tr에 넣기 for(let i=0; i<rowList.eq(0).children().length; i++){ → 첫 번째 행의 자식 태그 길이만큼 반복문 실행 let $th = $("<th>").append(rowList.eq(0).children().eq(i).prop("tagName") ); → th 태그 안에 첫번째 행의 자식태그의 태그 이름 가져와서 $th 변수에 넣음 $tr.append($th); → 만든 tr 태그에 자식태그의 태그 이름 즉, 제목 한 칸이 추가됨 } $table.append($tr); → 1. 테이블 생성에서 만든 테이블에 제목 한 칸을 행으로 추가. //3. tr태그를 만들어가며 데이터를 테이블에 추가 for(let i=0; i<rowList.length; i++){ → xml 파일의 row 개수만큼 반복문 실행 $tr = $("<tr>"); → 행 생성해서 변수 $tr에 넣기. 아까도 똑같이 했지만 지역변수로 만들었기때문에 또다시 생성. /*rowList.eq(i); rowList.eq(i).children().eq(0); rowList.eq(i).children().eq(1); rowList.eq(i).children().eq(2); rowList.eq(i).children().eq(3); rowList.eq(i).children().eq(4);*/ for(let j=0; j<rowList.eq(i).children().length; j++){ →현재 사원의 자식 태그들 개수만큼 반복 let $td = $("<td>").append(rowList.eq(i).children().eq(j).text()); → 자식 태그안의 글자를 가져와서 열에 넣음. $tr.append($td); → 위 주석처럼 i번째 행에 자식 5개 태그 글자를 넣기.. } $table.append($tr); → 위에 반복문을 행 개수만큼 반복하며 첫번째행에 자식 5개 태그 넣기, 두번째 행에 자식 5개 태그 넣기, 세 번째 행에 자식 5개 태그 넣기.... rowList.length 만큼 반복 } return $table; → 생성한 테이블을 함수 밖으로 전달 } |
조회버튼을 누르면 결과는 아래와 같이 나온다.

4. 정리 및 느낀점
1) 내용 정리
오늘은 remove(), empty(), removeAttr()처럼 요소를 지우거나 속성을 제거하는 메소드부터 시작해서, 동기/비동기 방식, Promise, async / await, 그리고 Ajax까지 이어서 정리했다.
정리하면 오늘 배운 핵심은 아래와 같다.
- remove() : 선택한 요소 자체를 삭제
- empty() : 선택한 요소 안의 자식 요소만 비우기
- removeAttr() : 선택한 요소의 속성 제거
- 동기 : 앞 작업이 끝나야 다음 작업 실행
- 비동기 : 앞 작업이 끝나지 않아도 다음 작업 실행 가능
- Promise : 비동기 작업의 상태와 결과를 관리하는 객체
- resolve → then : 성공 흐름
- reject → catch : 실패 흐름
- async / await : Promise를 더 직관적으로 다루는 문법
- Ajax : 페이지 전체를 새로고침하지 않고 필요한 데이터만 비동기로 가져오는 방식
오늘은 단순 DOM 조작 메소드만 본 것이 아니라 비동기 처리 방식과 Ajax까지 함께 배우면서
JavaScript가 화면 조작뿐 아니라 데이터 요청과 흐름 제어까지 담당한다는 점을 정리한 날이었다.
2) 느낀점
오늘은 메소드 이름만 보면 비슷해 보여서 처음에는 헷갈리는 부분이 많았다.
특히 remove()와 empty()처럼 둘 다 지우는 것처럼 보이지만, 하나는 요소 자체를 지우고 다른 하나는 내부만 비운다는 차이가 있다는 점을 다시 확인할 수 있었다.
또 Promise, async / await, Ajax는 처음 볼 때 구조가 바로 들어오진 않았지만, 실행 순서를 직접 따라가면서 보니
“지금 바로 실행되는 코드”와 “나중에 실행되는 코드”를 구분해서 보는 게 중요하다는 걸 느꼈다.
특히 resolve → then, reject → catch 흐름이나 await가 함수 안에서만 기다린다는 점은 처음보다 훨씬 정리가 되는 느낌이었다.
ajax 부분은 반복문 안에 반복문이 들어가 있어서 처음에는 조금 헷갈렸다.
그래도 코드를 한 줄씩 다시 보면서 흐름을 따라가다 보니, 막연하게 어렵게 느껴졌던 부분이 조금씩 익숙해지는 걸 느꼈다.
실습하면서 매개변수 개념도 다시 정리할 수 있었다.
특히 rowList를 매개변수로 넘기기 위해 js 파일을 따로 만들어 함수로 전달하는 구조를 이해하면서 함수 안과 밖의 변수 범위를 보는 감각도 조금씩 잡히는 것 같았다.
또 저번에 배운 prop() 메소드는 이전에는 값을 설정할 때 사용했었는데 이번에는 값을 가져오는 방식으로도 사용해 보면서 같은 메소드도 상황에 따라 다르게 활용될 수 있다는 점이 더 익숙해졌다.
아직 완전히 편해진 건 아니지만 이렇게 배운 내용을 하나씩 다시 적용하고 정리하다 보면 자주 쓰이는 문법이나 메소드들은 나중에 다시 볼 때 훨씬 빨리 떠올릴 수 있을 것 같다.
'멀티캠퍼스' 카테고리의 다른 글
| [2026.04.14]TIL - 12일차 Java 변수와 메모리 구조, 메소드, 연산자 정리 (0) | 2026.04.14 |
|---|---|
| [2026.04.13]TIL - 11일차 Java 설치 & 변수와 입력, 상수 정리 (4) | 2026.04.13 |
| [2026.04.09] TIL - 9일차 jQuery (DOM 조작과 Effect 정리) (3) | 2026.04.09 |
| [2026.04.08] TIL - 8일차 jQuery (jQuery 기초와 선택자, DOM 탐색) (2) | 2026.04.09 |
| [2026.04.07]TIL - 7일차 JavaScript(DOM 응용과 이벤트, 구조분해할당) (2) | 2026.04.08 |