객체
Key:Value 가 모여있는 형태 { K:V , K:V , K:V }
📍 자바스크립트에 객체를 생성하는 방법
🔑 CF
DOM
HTML(웹문서, 웹페이지) 문서를 객체 기반으로 표현한 것
📍 Node와 Element 차이
Node : 태그(요소 노드), 속성, 주석, 내용(텍스트 노드) 등을 모두 표현
Element : Node의 하위 개념으로 요소 노드만을 표현
📍 탐색법
📍 innerHTML / DOM 요소 생성(createElement) 차이점
innerHTML을 이용한 요소 생성 원리
1) 특정요소 내부의 내용을 모두 삭제
2) 특정요소.innerHTML = "태그가 포함된 문자열";
특정 요소 내부에 일단은 문자열 형태 내용 추가
3) HTMLParser를 이용해서 태그를 해석
(내부 내용을 다 지우고 새로운 내용을 추가해서 처음부터 다시 해석)
document.createElement("태그명") : 해당 태그 요소를 생성하여 반환
div 생성 O, 화면 배치 X --> append로 붙여주기
🔑 CF
함수
📍 기본 함수
function 함수명(매개변수){ // 함수선언
// 함수정의
}
함수명(); // 함수호출
📍 익명함수(이름이 없는 함수)
function(매개변수){ // 함수 선언
// 함수 정의
}
이름이 없는 함수이기 때문에 필요할 때 마음대로 호출하는 것이 불가능
이벤트 핸들러와 같이 바로 동작하는 함수가 필요한 경우 또는
변수, 매개변수에 함수를 저장해야 하는 경우 사용
📍 즉시 실행 함수
(function(매개변수){ // 함수 선언
// 함수 정의
})();
📍 화살표 함수
( [매개변수] ) => { 함수 정의 }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>11_객체</title>
<style>
.area{
width: 400px;
height: 400px;
border: 1px solid black;
}
</style>
</head>
<body>
<h1>자바스크립트 객체</h1>
<pre>
자바스크립트의 객체는 {} 내에 Key:Value 가 모여있는 형태로 작성된다.
(Map 형식)
{ K:V , K:V , K:V } // 자바스크립트 객체
(참고) 자바스크립트 객체 모양의 문자열
== JSON(JavaScript Object Notation, 자바스크립트 객체 표기법)
-> "{ K:V , K:V , K:V }"
- 자바스크립트에 객체를 생성하는 방법
1. {} : 객체 리터럴 표기법을 이용한 생성
2. 생성자 + new 생성자()를 이용한 생성
</pre>
<button id="btn1">객체생성 1</button>
<div class="area" id="div1"></div>
<hr>
<button id="btn2">객체생성 2(생성자 함수)</button>
<script src="JS/11_객체.js"></script>
</body>
</html>
// 객체 생성
document.getElementById("btn1").addEventListener("click", function(){
const div1 = document.getElementById("div1");
// {}객체 리터럴 표기법으로 객체 생성
// ** (중요) **
// 자바스크립트 객체의 key는 무조건 string(묵시적)
// "Key" 또는 'Key'
// 또는 Key (따옴표 없어도 String으로 인식)
const brand="할리스";
const product = {
"pName" : "텀블러",
'brand' : '스타벅스',
color : ["white", "black", "silver"],
price : 35000,
// 기능(메소드)
mix : function(){
console.log("섞기 시작합니다.");
},
information : function(){
console.log(this.pName);
console.log(this.brand);
console.log(this.color);
console.log(this.price);
// 같은 객체 내부의 다른 속성을 호출하고 싶은 경우
// 현재 객체를 뜻하는 this를 앞에 붙여야 된다.
// this 미작성 시 객체 외부 변수 호출
console.log(brand);
}
}
// 결과 출력
div1.innerHTML = ""; // div1 내부 내용 삭제
div1.innerHTML += "product.pName : " + product.pName + "<br>";
div1.innerHTML += "product.brand : " + product.brand + "<br>";
div1.innerHTML += "product.color : " + product.color + "<br>";
div1.innerHTML += "product.price : " + product.price + "<br>";
div1.innerHTML += "<hr>";
// 자바스크립트 객체용 향상된 for문 (for ... in)
// 객체 내부에 작성된 key를 순서대로 하나씩 꺼내옴
for(let key in product){
div1.innerHTML += product[key] + "<br>";
// 배열의 인덱스 선택하듯이 (product.key로 하면 undefined 됨)
}
// 객체 메소드 호출
product.mix();
product.information();
})
//------------------------------------------------------------------------------------
// 생성자 함수(자바의 생성자를 함수로 작성하는 모양)
// 1. 생성자 함수 정의(생성자 함수명은 대문자로 시작!)
function Student(name, grade, ban){
// 속성
// this == 생성되는 객체
this.name = name; // 생성되는 객체 name에 매개변수 name 대입
this.grade = grade; // 생성되는 객체 grade에 매개변수 grade 대입
this.ban = ban; // 생성되는 객체 ban에 매개변수 ban 대입
// 기능 (메소드)
this.intro = function(){
console.log(grade + "학년 " + ban + "반 " + name + "입니다.");
}
}
// 2. 생성자 함수 호출(new 연산자)
document.getElementById("btn2").addEventListener("click", function(){
const std1 = new Student("홍길동", 3, 1);
const std2 = new Student("홍길순", 2, 7);
const std3 = new Student("김길동", 1, 5);
console.log(std1);
console.log(std2);
console.log(std3);
// 생성자 함수 사용 이유: 같은 형태의 객체가 다수 필요한 경우에 사용
// 코드 길이 감소, 재사용성 증가
console.log(std1.name);
std1.intro();
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM</title>
<style>
.area{
width: 400px;
height: 400px;
border: 1px solid black;
}
.area > div {
width: 100%;
height: 10%;
box-sizing: border-box;
border: 2px solid red;
background-color: yellow;
}
</style>
</head>
<body>
<h1>DOM(Document Object Model)</h1>
<pre>
HTML(웹문서, 웹페이지) 문서를 객체 기반으로 표현한 것
-> HTML 문서에 작성된 내용을 트리구조(계층형으로 표현)로 나타냈을 때
각각의 태그, TEXT, COMMENT 등을 Node라고 한다.
document : {
DOCTYPE : html,
HTML : {
HEAD : {
TITLE : { TEXT : "문서 제목" },
STYLE : {...},
META : {...}
} ,
BODY : {
H1 : { TEXT : "제목", ATTRIBUTE : "속성" },
COMMNET : {TEXT : "주석 내용"},
DIV : {...}
}
}
}
</pre>
<hr>
<h1>Node 확인하기</h1>
<ul id="test">
<!-- Node 확인 테스트 주석입니다. -->
<li id="li1">1번</li>
<li class="cls">2번</li>
<!-- 중간 주석 -->
<li style="background-color: yellow;">3번</li>
<li>
<a href="#">4번</a>
</li>
</ul>
<button id="btn1">확인하기</button>
<hr>
<h1>Node와 Element의 차이</h1>
<pre>
Node : 태그(요소 노드), 속성, 주석, 내용(텍스트 노드) 등을 모두 표현
Element : Node의 하위 개념으로 요소 노드만을 표현
[Element만 탐색하는 방법]
children : 자식 요소만 모두 선택
parentElement : 부모 요소 선택
firstElementChild : 첫 번째 자식 요소 선택
lastElementChild : 마지막 자식 요소 선택
previousElementSibling : 이전 형제 요소 선택
nextElementSibling : 다음 형제 요소 선택
</pre>
<button id="btn2">Element 확인하기</button>
<hr>
<h2>innerHTML / DOM 요소 생성(createElement) 차이점</h2>
<pre>
- innerHTML을 이용한 요소 생성 원리
1) 특정요소 내부의 내용을 모두 삭제
2) 특정요소.innerHTML = "태그가 포함된 문자열";
특정 요소 내부에 일단은 문자열 형태 내용 추가
3) HTMLParser를 이용해서 태그를 해석
(내부 내용을 다 지우고 새로운 내용을 추가해서 처음부터 다시 해석)
-> 문제점
1) 해석 속도가 느림
2) 기존 요소에 존재하던 효과/이벤트가 모두 사라져 버리는 문제가 있음
</pre>
<button id="btn3-1">innerHTML</button>
<div class="area" id="div3-1">
<!-- <div id="temp">temp</div> -->
</div>
<hr>
<button id="btn3-2">createElement</button>
<div class="area" id="div3-2">
<div id="temp">temp</div>
</div>
<script src="JS/12_DOM.js"></script>
</body>
</html>
// Node 확인하기
document.getElementById("btn1").addEventListener("click", function(){
// #test의 자식 노드를 모두 얻어오기
// 원하는요소.childNodes : 요소의 자식 노드를 모두 반환
const nodeList = document.getElementById("test").childNodes;
console.log(nodeList);
// 노드 탐색
// 1) 부모 노드 탐색 : parentNode
const li1 = document.getElementById("li1");
console.log(li1.parentNode); // ul#test
// 부모 노드의 배경색 변경
li1.parentNode.style.backgroundColor = "lightskyblue";
// 부모 노드 마지막에 새로운 노드 추가(append : (마지막에) 덧붙인다.)
li1.parentNode.append("ABCD");
// 2) 첫 번째 자식 노드 탐색 : firstChild
console.log(document.getElementById("test").firstChild);
// 3) 마지막 자식 노드 탐색 : lastChild
console.log(document.getElementById("test").lastChild); // 추가된 ABCD
// 4) 중간에 존재하는 자식 노드 탐색 : 부모요소.childNodes[인덱스]
console.log(nodeList[11]);
nodeList[11].append("1234");
// 5) 이전 형제 노드 탐색 : previousSibling
// 다음 형제 노드 탐색 : nextSibling
console.log(nodeList[8].previousSibling);
console.log(nodeList[8].nextSibling);
// 노드 탐색을 위한 구문은 연달아서 사용 가능
console.log(nodeList[8].previousSibling.previousSibling.previousSibling);
})
// Element 탐색 확인하기
document.getElementById("btn2").addEventListener("click", function(){
// #test의 모든 자식 요소를 반환
const list = document.getElementById("test").children;
console.log(list);
// #test의 첫 번째 자식 요소
document.getElementById("test").firstElementChild.style.backgroundColor="red";
// #test의 마지막 자식 요소
document.getElementById("test").lastElementChild.style.backgroundColor="yellowgreen";
// #test의 자식 중(list) 2번째 인덱스의 이전/다음 형제 요소
list[2].previousElementSibling.addEventListener("click", function(){
alert("2번 인덱스의 이전 형제 요소 클릭됨");
})
list[2].nextElementSibling.addEventListener("click", function(){
alert("2번 인덱스의 다음 형제 요소 클릭됨");
})
console.log( prevEl(list[2]));
console.log( prevEl(prevEl(list[2])));
console.log( nextEl(list[2]));
})
// 이전 형제 요소 선택 함수
function prevEl(el){
return el.previousElementSibling;
}
// 다음 형제 요소 선택 함수
function nextEl(el){
return el.nextElementSibling;
}
let count1 = 1;
// innerHTML 버튼 클릭 시
document.getElementById("btn3-1").addEventListener("click", function(){
/* const list = document.getElementById("div3-1").children;
console.log(list);
for(let i = 1; i<10; i++){
list.innerHTML += "<div>"+ i + "</div>";
}
아니ㅠㅜ 문제 좀 읽어라..한 번에 열 칸이 아니라 누를 때마다 한 칸씩 증가라고ㅠ*/
// 쌤 코드
const div = document.getElementById("div3-1");
if(count1 <= 10) {
// 누적
div.innerHTML += "<div>" + count1 + "</div>";
count1++;
}
})
let count2 = 1;
// createElement 버튼 클릭 시
document.getElementById("btn3-2").addEventListener("click", function(){
const div1 = document.getElementById("div3-2"); // #div3-2 선택
// createElement를 이용해서 div 요소 생성
// document.createElement("태그명") : 해당 태그 요소를 생성하여 반환
const child = document.createElement("div"); // div 생성 O, 화면 배치 X
if(count2 <=10){
// 만들어진 div(child)에 내용 추가(append)
child.innerHTML = count2;
count2++;
// #div3-2 마지막 자식 요소로 추가하기
div1.append(child);
}
})
document.getElementById("temp").addEventListener("click", function(){
alert("temp");
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>13_요소추가제거</title>
<style>
/* div{
border: 1px solid black;
} */
/* 한 줄 */
.row{
margin: 5px 0;
}
/* input 태그 */
.in{
width: 100px;
}
/* span태그 (X버튼) */
.remove{
border: 1px solid black;
width: 20px;
display: inline-block;
text-align: center;
border-radius: 50%;
font-weight: bold;
cursor: pointer;
margin-left: 5px;
}
</style>
</head>
<body>
<div id="container">
<div class="row">
<input type="number" class="in">
</div>
<!-- <div class="row">
<input type="number" class="in"><span class="remove">X</span>
</div> -->
</div>
<button id="add">추가</button>
<button id="calc">계산</button>
<script src="JS/13_요소추가제거.js"></script>
</body>
</html>
// 추가버튼(#add)가 클릭되었을 때
document.getElementById("add").addEventListener("click", function(){
const con = document.getElementById("container"); // 전체 container 요소
// div 요소 생성
const div = document.createElement("div");
// div에 row 클래스 추가
div.classList.add("row")
//---------------------------------------------------------------------------
// input 요소 생성
const input = document.createElement("input");
// input에 in 클래스 추가
input.classList.add("in")
// input의 "type"속성, "number" 속성값 추가(type = "number")
// 요소.setAttribute("속성", "속성값") : 요소에 속성/ 속성값 추가
input.setAttribute("type", "number");
//---------------------------------------------------------------------------
// span 요소 생성
const span = document.createElement("span");
// span에 remove 클래스 추가
span.classList.add("remove");
// span의 내용으로 "X" 추가
span.innerHTML="X";
// span이 클릭 되었을 때 이벤트 동작 추가
span.addEventListener("click", function(){
// 요소.parentElement : 부모 요소
// 요소.remove() : 요소 제거
// 부모(.row)제거
span.parentElement.remove();
})
//----------------------------------------------------------------------------
// div 내부에(자식으로) input, span 순서대로 추가
div.append(input);
div.append(span);
// #container에 div 마지막 자식으로 추가
con.append(div);
})
// 계산 버튼 클릭 시 이벤트 동작
document.getElementById("calc").addEventListener("click", function(){
/* let sum = 0;
const list = document.getElementsByClassName("in");
for(let i = 0; i<list.length; i++){
sum+=Number(list[i].value);
} */
// 쌤 코드
let sum = 0;
// in 클래스 요소를 모두 얻어오자 -> 배열
const list = document.getElementsByClassName("in");
// 배열용 향상된 for문(for of) 사용
for(let item of list){
// sum에 입력값 누적
// -> input에 작성된 값은 모두 string -> 숫자 변환 Number
sum+=Number(item.value);
// Number("") == 0 .// 빈칸은 0으로 변환됨
}
// sum을 alert로 출력
alert("합계 : " + sum)
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>14_함수</title>
<style>
/* code태그 */
code{
color: red;
font-size: 20px;
font-weight: bold;
}
/* btn1 */
#btn1{
width: 50px;
height: 50px;
font-size: 30px;
font-weight: bold;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
</style>
</head>
<body>
<h3>기본적인 함수의 선언, 정의, 호출</h3>
<pre>
<code>
function 함수명(매개변수){ // 함수선언
// 함수정의
}
함수명(); // 함수호출
</code>
</pre>
<!-- 매개변수 this : 클릭된 요소를 의미 -->
<div id="btn1" onclick="clickCount(this)">0</div>
<hr>
<h3>익명함수(이름이 없는 함수)</h3>
<pre>
<code>
function(매개변수){ // 함수 선언
// 함수 정의
}
</code>
- 이름이 없는 함수이기 때문에 필요할 때 마음대로 호출하는 것이 불가능
- 이벤트 핸들러와 같이 바로 동작하는 함수가 필요한 경우 또는
변수, 매개변수에 함수를 저장해야 하는 경우 사용
</pre>
<hr>
<h3>즉시 실행 함수</h3>
<pre>
<code>
(function(매개변수){ // 함수 선언
// 함수 정의
})();
</code>
- 익명 함수의 한 종류로써
함수가 정의되자마자 바로 실행되는 함수
*** 즉시 실행 함수 사용 이유
1) 함수 선언, 정의, 호출의 일련 과정을 수행하지 않아도 바로 실행된다.
-> 호추룹가 없으므로 일반적인 함수보다 속도적 우위를 가지고 있음
2) 사용하려는 변수명이 전역변수로 사용되어지고 있는 경우
즉시 실행 함수를 이용하여 내부의 지역변수로 작성하여
변수명 충돌 문제를 해결할 수 있다.
</pre>
<hr>
<h3>화살표 함수</h3>
<pre>
익명함수의 표현식을 간단히 표현한 표기법
작성법1. 기본 형태( [매개변수] ) => { 함수 정의 }
익명함수 : function(){}
화살표함수: () => {}
익명함수 : function(num){return num*2;}
화살표함수 : (num) => {return num*2;}
작성법2. 매개변수가 "하나"인 경우 () 생략 가능
익명함수 : function(e){e.target.style.backgroundColor = "yellow";}
화살표함수 : e => {e.target.style.backgroundColor = "yellow";}
작성법3. 매개변수가 없을 경우 무조건 "()" 작성
작성법4. 함수의 정의 부분이 return [식 또는 값]으로만 작성되어 있는 경우
{}, return 생략 가능
작성법5. 함수 정의 부분이 return 구문만 있으나
return되는 값이 객체(Object)인 경우 {}, return 생략 불가능
</pre>
<button id="btn2-1">기본형태</button>
<button id="btn2-2">매개변수 1개</button>
<button id="btn2-3">(), return 생략</button>
<button id="btn2-4">this 사용 불가</button>
<script src="JS/14_함수.js"></script>
</body>
</html>
// 기본 함수
function clickCount(btn){
console.log(btn);
btn.innerText = Number(btn.innerText) + Number(1);
}
//-----------------------------------------------------------------------------
// 즉시 실행 함수 확인하기
function test1(){ // 기본함수 선언&정의
console.log("기본함수")
}
test1(); // 호출
// 즉시 실행 함수
(function(){
console.log("즉시 실행 함수");
// 호출하지 않아도 자동으로 수행
})();
// *즉시 실행 함수의 변수명 중복 해결
const str = "전역변수";
(function(){
const str = "즉시실행함수의 전역변수";
console.log(str);
})();
console.log(str);
//--------------------------------------------------------------------------------
// 화살표 함수(Arrow Function)
// 1. 기본 형태 : ([매개변수]) => {}
document.getElementById("btn2-1").addEventListener("click",() => {
alert("화살표 함수 기본형태입니다.");
})
// 2. 매개변수 1개 : (매개변수) => {}
document.getElementById("btn2-2").addEventListener("click", e => {
e.target.style.backgroundColor = "yellow";
})
// 3. {}, return 생략
document.getElementById("btn2-3").addEventListener("click", () => {
// 함수 호출(익명 함수)
printConsole(function(num){return num*10});
// 함수 호출(화살표 함수)
printConsole(num=> num*10);
// 반환값이 Object면 {}, return 생략 불가
// -> 화살표(=>) 다음에 함수 정의 부분이 있어야 하는데
// 객체(Object)가 작성되어 있어 문법 오류 발생
// printConsole((num)=>{price : num*100, n : num}); // 문법 오류
printConsole((num)=>{return {price : num*100, n : num}});
})
function printConsole(fn){
console.log(fn(2));
}
// this(이벤트가 발생한 요소) 사용 불가
// 1) 익명 함수는 this 사용 가능
document.getElementById("btn2-4").addEventListener("click", function(){
this.style.backgroundColor ="pink";
})
// 2) 화살표 함수 this 사용 불가
document.getElementById("btn2-4").addEventListener("click", e => {
// 화살표 함수에서 this는 창 자체를 나타내는 객체(window)이다.
console.log(this);
//this.style.color = "white"; // 글자색 변경
e.target.style.color = "white"; // 글자색 변경
})