ㅁ
<!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>
<h2>in과 with 키워드</h2>
이름 : <input type="text" id="name"> <br>
국어 : <input type="number" id="kor"> <br>
수학 : <input type="number" id="math"> <br>
영어 : <input type="number" id="eng"> <br><br>
<button onclick="fnInWith();">실행확인</button>
<div id="result2"></div>
<script>
function fnInWith() {
const student = {
name : document.getElementById("name").value,
kor : Number(document.getElementById("kor").value), // "70" >> 70
math : Number(document.getElementById("math").value),
eng : Number(document.getElementById("eng").value),
// student 객체를 화면에 출력하고 싶다면
toString : function() { // 객체의 속성에 저장된 함수를 메소드라고 한다.
return this.name + " " + this.kor + " " + this.math + " " + this.eng;
},
// 이 학생 객체가 가지고 있는 총점을 반환하는 메소드 정의
getSum : function() { // 메소드도 속성이라 연속될 때 위 마지막에 컴마 빠트리면 안 됨.
return this.kor + this.math + this.eng;
},
getAvg : function() {
// return (this.kor + this.math + this.eng) / 3; 이래도 되지만
return this.getSum() / 3;
}
}
console.log(student);
document.getElementById("result2").innerHTML = student;
}
</script>
</body>
</html>
- 사용자 입력 데이터는 무조건 문자열이다. value 타입 자체가 string으로 정의되어 있다.
덧셈 등의 연산을 하려면 숫자로 변환해야 한다.
- 텍스트 상자에 아무것도 입력하지 않았는데 value 값을 가져오면 빈문자열이다.
- 자바스크립트에서 빈문자열 가지고 넘버 타입으로 형변환하면 0으로 변환된다.
자바에서는 빈문자열 가지고 형변환하면 오류 난다.
※ 참고
- string은 기본 자료형(primitive type)으로, 문자열 데이터를 나타냅니다.
- String은 객체 타입입니다. String 객체는 문자열을 감싸는 객체다.
ㅁ in과 with 키워드
- in : 객체 내에 해당 속성이 있는지 확인해주는 키워드 (존재할 경우 true / 아니면 false)
- with : 객체의 속성에 접근시 객체명 제시를 생략하게 해주는 키워드
<!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>
<h2>in과 with 키워드</h2>
이름 : <input type="text" id="name"> <br>
국어 : <input type="number" id="kor"> <br>
수학 : <input type="number" id="math"> <br>
영어 : <input type="number" id="eng"> <br><br>
<button onclick="fnInWith();">실행확인</button>
<div id="result2"></div>
<script>
function fnInWith() {
const student = {
name : document.getElementById("name").value,
kor : Number(document.getElementById("kor").value), // "70" >> 70
math : Number(document.getElementById("math").value),
eng : Number(document.getElementById("eng").value),
// student 객체를 화면에 출력하고 싶다면
toString : function() { // 객체의 속성에 저장된 함수를 메소드라고 한다.
return this.name + " " + this.kor + " " + this.math + " " + this.eng;
},
// 이 학생 객체가 가지고 있는 총점을 반환하는 메소드 정의
getSum : function() { // 메소드도 속성이라 연속될 때 위에 컴마 필요
return this.kor + this.math + this.eng;
},
getAvg : function() {
// return (this.kor + this.math + this.eng) / 3; 이래도 되지만
return this.getSum() / 3;
}
}
console.log(student);
document.getElementById("result2").innerHTML = student;
// 프로퍼티 명은 문자열로 작성
console.log("name" in student); // true
console.log("age" in student); // false
// 객체명을 전부 작성하는 방식
console.log("학생이름 : ", student.name);
console.log("점수 : ", student.kor, student.math, student.eng);
console.log("총점 : ", student.getSum());
console.log("평균 : ", student.getAvg());
// with 구문 방식
with(student) { // 이 블럭 내에서는 항상 student 객체에 접근한다.
console.log("학생이름 : ", name);
console.log("점수 : ", kor, math, eng);
console.log("총점 : ", getSum());
console.log("평균 : ", getAvg());
}
}
</script>
</body>
</html>
- 특정 속성이 특정 객체에 있는지 확인. 조건식으로도 사용 가능.
- with 키워드는 특정 객체의 속성에 반복적으로 접근할 때 코드의 가독성을 높이기 위해 사용됩니다. (근데 비추천)
ㅁ 구조 분해 할당 Destructuring Assignment
- 객체와 함께 쓸 수 있는 표현식
- 객체가 가지고 있는 각 property 값들을 개별 변수에 쉽게 할당할 수 있는 표현식
- 단, 객체의 프로퍼티명과 개별 변수명을 동일하게 맞춰야 함.
- 특정 함수 호출시 객체를 반환하는 경우가 있다.
반환되어 돌아오는 객체에 각각의 프로퍼티값을 내가 원하는 변수에 대입시키고자 할 때 구조 분해 할당을 사용하면 좋다.
키워드 { 변수1, 변수2, .. } = 객체;
(1) 직접 대입 방식
<!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>
<h2>구조 분해 할당</h2>
<button onclick="fnDestructuring1();">구조분해할당1</button>
<script>
function fnDestructuring1() {
// 테스트를 위해 객체 하나 생성
const car = {
maker : 'bmw',
model : 'x6',
year : 2024
}
// 객체 car의 각 property값을 각각의 변수에 직접 대입
let maker = car.maker;
let model = car.model;
let year = car.year;
console.log(maker, model, year);
}
</script>
</body>
</html>
(2) 구조 분해 할당 방식
<!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>
<h2>구조 분해 할당</h2>
<button onclick="fnDestructuring1();">구조분해할당1</button>
<script>
function fnDestructuring1() {
// 테스트를 위해 객체 하나 생성
const car = {
maker : 'bmw',
model : 'x6',
year : 2024
}
// 구조 분해 할당 방법
// (1) 변수 선언과 동시에 초기화.
var { maker, model, year } = car;
console.log(maker, model, year);
// (2) 선언 후 할당.
var maker, model, year; // 선언 후
( { maker, model, year } = car ); // 대입하고자 할 경우 반드시 ( )로 묶어야 함.
console.log(maker, model, year);
}
</script>
</body>
</html>
- 키워드 하나로 여러 변수를 한번에 선언하는 것이 가능하다.
- 선언 후 할당하는 경우 이미 선언되었으므로 키워드를 또 붙이지 않아도 된다.
그러나 그냥 중괄호만 쓰면 구조 분해 할당으로 인식하지 않아서 전체를 괄호로 감싸주고 콜론을 써야한다.
(3) 구조 분해 할당 방식 - 변수명과 프로퍼티명이 다른 경우
<!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>
<h2>구조 분해 할당</h2>
<button onclick="fnDestructuring2();">구조분해할당2</button>
<script>
function fnDestructuring2() {
const qna = {
q : '한국의 수도는?',
a : '서울'
}
// var { question, answer } = qna; 값이 대입되지 않음. question과 answer는 undefined
// var { q, a } = qna; 이건 잘 됨.
// 프로퍼티명과 이름이 다른 변수에 대입하고자 하는 경우
var { q : question, a : answer } = qna;
console.log(question, answer);
}
</script>
</body>
</html>
- qna 객체가 가지고 있는 q라는 프로퍼티값이랑 a라는 프로퍼티값을 각각의 변수에 담는다.
- 변수명이 프로퍼티명과 다르면 변수에 값이 대입되지 않는다. 콘솔에 undefined가 출력된다.
- 프로퍼티명과 이름이 다른 변수에 대입하고자 하는 경우
콜론 앞에는 프로퍼티명을 쓰고, 콜론 뒤에는 변수명 작성.
ㅁ 객체 배열
- 다수의 객체들을 배열에 담아서 관리해야 할 때가 있다.
<!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>
<h2>객체 배열</h2>
<button onclick="fnObjectArray();">객체 배열</button>
<script>
function fnObjectArray() {
const students = [ // 배열 선언
{
name : '유니', // 0번 인덱스에 첫번째 객체 담기
java : 100,
oracle : 80, // 후행 쉼표
},
{
name : '칸나',
java : 80,
oracle : 70,
},
{
name : '리제',
java : 60,
oracle : 100,
}, // 또 객체가 들어올 수도 있으니 후행 쉼표. 배열도 후행 쉼표 지원함.
] ;
students.push( {
name : '시로',
java : 70,
oracle : 40,
} )
console.log(students);
console.log(students[0]);
console.log(students[0].name); // .을 통해서 객체의 프로퍼티에 접근
}
</script>
</body>
</html>
- 대괄호로 감싸져 있으니 배열이다. 그 안에는 중괄호로 감싸져 있으니 객체다.
펼쳐보면 각각의 인덱스에 어떤 객체가 담겨있는지 볼 수 있다.
- 0번 인덱스가 객체이므로 또 펼쳐서 객체의 속성에 접근해볼 수 있다.
- 나중에 웹개발 하면 응답 데이터로 ArrayList를 받는다.
ArrayList에는 주로 vo객체가 담겨 있다.
그걸 자바스크립트에서 출력해보면 이렇게 나온다.
ㅇ 객체 배열로 다수의 객체를 배열에 담아둔 이유는 관리의 편리성 때문이다.
- 반복문 사용 가능 (배열에 for 문, for in 문, for of문 다 가능)
<!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>
<h2>객체 배열</h2>
<button onclick="fnObjectArray();">객체 배열</button>
<script>
function fnObjectArray() {
const students = [ // 배열 선언
{
name : '유니', // 0번 인덱스에 첫번째 객체 담기
java : 100,
oracle : 80, // 후행 쉼표
},
{
name : '칸나',
java : 80,
oracle : 70,
},
{
name : '리제',
java : 60,
oracle : 100,
}, // 또 다른 객체가 들어올 수도 있으니 후행 쉼표. 배열도 후행 쉼표 지원함.
] ;
students.push( {
name : '시로',
java : 70,
oracle : 40,
} )
// for of 문으로 배열의 각 인덱스에 담겨있는 객체에 접근하기
for(let stu of students) { // {}, {}, {}, {}
console.log(stu);
}
console.log("==================");
// 각 객체에 속성을 일괄적으로 추가하기
for(let stu of students) {
stu.front = 100;
stu.getSum = function() {
return this.java + this.oracle + this.front;
}
stu.getAvg = function() {
return this.getSum() / 3 ;
}
}
console.log(students);
console.log("==================");
}
</script>
</body>
</html>
- 그런데 지금 students라는 배열 내에 담긴 객체를 보면 모든 객체가 다 동일한 속성을 가지고 있다.
- 객체들을 direct로 중괄호 블록을 사용하여 생성하면 다 동일한 프로퍼티임에도 불구하고
매번 저 프로퍼티들을 기술해줘야 한다.
이럴 때 아예 new라는 키워드로 객체를 생성하면 저 프로퍼티들을 가진 채로 만들어지게 설정할 수있다.
그게 생성자 함수.
ㅁ 생성자 함수
- 함수긴 한데 마치 생성자처럼 쓸 수 있는 함수를 만들 수 있다.
- new 키워드를 통해 객체 생성을 진행시킬 수 있는 함수다.
- 함수명의 첫글자는 대문자로 작성
- 화살표 함수로 작성 불가능
- 프로퍼티를 함수 내에 this.프로퍼티로 정의
- function 대문자로시작하는함수명 ( param1, param2, ... ) {
// 일반 속성
this.prop1 = param1;
this.prop2 = param2;
...
// 메소드 속성
this.methodProp = function( ) {
메소드내용
}
}
new 대문자로시작하는함수명 (1, 2, ..); // 저 값들이 프로퍼티에 대입된 채로 호출이 진행된다.
<!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>
<script>
function Student(name, java, oracle, front) { // 함수명 첫글자는 대문자로 작성
// 일반 속성
this.name = name;
this.java = java;
this.oracle = oracle;
this.front = front;
// 메소드 속성
this.getSum = function() {
return this.java + this.oracle + this.front;
}
this.getAvg = function() {
return this.getSum() / 3;
}
}
function fnConstructorTest() {
const students = [ // 배열 정의
new Student('온앤온', 100, 70, 50),
new Student('정망개', 80, 90, 100),
new Student('금사향', 100, 60, 70)
];
students.push(new Student('마마뫄', 60, 10, 70));
console.log(students);
}
</script>
<h2>생성자함수</h2>
<button onclick="fnConstructorTest();">생성자함수확인</button>
</body>
</html>
- 직접 중괄호 블록을 썼을 때랑 생성자 함수를 썼을 때랑 살짝 다르다.
콘솔 출력된 것을 확인해보니 배열이긴 한데 각각의 인덱스에 Student가 담겨있다.
이 Student도 객체다.
- 확장해서 보면 0번 인덱스에 중괄호 블록의 객체, 1번 인덱스에 중괄호 블록의 객체, ...를 볼 수 있다.
- 중괄호 블럭으로 생성했을 때와 살짝 다르긴 한데 제어하는 방식과 접근하는 방식은 동일하다.
다만, 객체를 중괄호 블럭이 아닌 생성자함수로 생성했다면 중괄호 앞에 생성자 함수명(Student)이 보여진다.
- 객체들이 가지고 있는 프로퍼티는 동일하다.
이 Student 객체들도 확장해 보면 어떤 속성을 가지고 있는지 확인할 수 있다.
- 자주 생성시킬 객체의 형태는 생성자 함수를 정의해 두고 활용하면 편리하다.
미리 프로퍼티를 정의해 둔다면 이렇게 프로퍼티를 가지는 객체의 형태로 만들 수 있다.
console.log(students);
console.log(students[0]);
console.log(students[0].name);
ㅁ 예제
<!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>
<script>
function fnPractice() {
let cars = [
{ model: 'K3', }, // 중괄호 블럭 하나하나가 객체다. maker 속성 추가 예정
{ model: 'K5', },
{ model: 'K7', },
{ model: 'G70', },
{ model: 'GV80', },
{ model: 'G90', }, // 후행쉼표
];
// cars 배열 내의 객체들 중
// model 값이 'K'로 시작할 경우 maker: 'Kia'가 추가 되고
// model 값이 'G'로 시작할 경우 maker: 'Genesis'가 추가되게끔
// (생성자 함수랑은 상관 없음)
for(let i=0; i<cars.length; i++) {
if( cars[i].model.startsWith('K') ) {
cars[i].maker = 'Kia';
}
else {
cars[i].maker = 'Genesis';
}
}
/* [답]
for(let car of cars) { // {}, {}, {}
if( car.model.startsWith('K') ) {
car.maker = 'Kia';
}
else if( car.model.startsWith('G') ){
car.maker = 'Genesis';
}
}
*/
console.log(cars);
}
</script>
<button onclick="fnPractice();">버튼</button>
</body>
</html>