728x90
반응형
1) Javascript 함수
1-1) 함수 복습
1-2) 함수 표현식
1-3) 화살표 함수(arrow function)
1-4) 콜백 함수(callback function)
1-5) 콜스택 / 콜백 함수 활용 예시
2) Javascript 객체
2-1) 객체 생성 방법
2-2) 점 표기법 / 응용 방법
2-3) in 연산자 / for in 문
2-4) Spread Operator(스프레드 연산자)
2-5) 참조형 데이터 타입 활용 예시
1) Javascript 함수
1-1) 함수 복습
// 복습
// 함수 선언
/*
함수 호이스팅 : 함수 호출 구문이 함수 선언문보다 위에 있어도 코드가 정상 실행됨
(함수 선언문이 최상단으로 끌어올려저서 코드 형태 상에서는
호출 구문이 상단에 있는 것처럼 보여도 내부에서는 함수 선언문이 먼저 최상단에서 처리된 뒤
함수 호출을 처리함!!)
*/
function showMessage(name, age) {
// code block
return undefined;
}
// 함수 호출
showMessage();
// 인수(argument) - 함수 호출 구문에 명시
showMessage("sangbeom", 27);
// (참고) var 호이스팅
console.log(num); // undefined
var num = 10;
// 위의 코드는 var 호이스팅이 발생하여 아래와 같이 동작함!!
var num;
console.log(num); // undefined
num = 10;
// 콜스택 이해를 위한 예시
function ingoo() {
console.log(3);
return 4;
}
function goak() {
console.log(1);
return ingoo();
}
function hello() {
goak();
console.log(5);
ingoo();
return 10;
}
const result = hello();
const answer = goak();
console.log(result);
/*
출력 결과
1
3
5
3
1
3
10
*/
// 자바스크립트는 코드를 실행하기 전에 콜스택의 익명함수가 전체 코드를 한 줄 한 줄 훑어본 뒤에 코드를 한 줄 한 줄 실행함!!(코드 실행이 전부 완료되면 익명함수 또한 콜스택에서 사라짐)
// 함수는 return을 만나야 비로소 종료됨!! >> return : 함수를 종결시키는 역할
1-2) 함수 표현식
// 함수 선언문
function showMessage() {}
// 함수 표현식 >> 함수 호출 시 "변수명();" 형태로 호출하기에 함수명을 따로 지정할 필요가 없어 일반적으로 함수 표현식은 익명함수로 생성함!!
const showMessage2 = function() {};
// 함수 표현식은 함수 선언문과 달리 호이스팅이 발생하지 않음!!
// 단, var 예약어를 사용해 함수 표현식을 정의한 경우에는 var 호이스팅이 발생하여 함수 호출을 먼저 쓰는 경우에는 변수명만 선언되어 함수 선언부를 인식하지 못하여 코드 실행 시 함수를 찾을 수 없다는 에러가 발생함!!
// 대입 연산자를 사용한 함수(함수 표현식)도 무언가의 값이다!!
// 함수 표현식은 별도로 함수명을 기재할 필요 없는 익명함수 형태로 많이 사용됨!! >> 함수 호출 시 함수명이 아닌 "변수명();"으로 호출하기 때문에 익명함수로 선언해도 호출 시 문제되지 않음!!
// 즉시 실행 함수 : 함수를 선언하자마자 바로 호출하여 함수를 실행함!!
(function () {
console.log("hello world");
})();
showMessage3(); // (중요) 함수 표현식은 호이스팅이 발생하지 않아 함수 호출을 선언보다 먼저 할 시 에러가 발생함
const showMessage3 = function () {
console.log("good morning");
};
// 함수 선언문
function showMessage4() {
console.log("hello func");
}
// 함수를 호출하지 않고 함수 이름만 console.log() 찍었을 시 함수 자체가 값으로 찍힘!!
console.log(showMessage4);
// 새로운 변수를 만들고 해당 변수에 함수명을 넣으면 함수가 정상 실행됨
const fun = showMessage4;
fun();
// 함수도 값이기에 변수에 할당이 가능함!!(like 함수 표현식)
const showMessage5 = function() {};
// (매우 중요)함수도 값이다!!
1-3) 화살표 함수(arrow function)
// 화살표 함수
// 함수 표현식을 좀 더 간결한 문법으로 만드는 방법
// ES6에서 추가된 문법으로 '화살표 함수(arrow function)'라고 함!!
// 문법
// 함수 표현식
const sum = function (a, b) {
return a + b;
};
// 위의 함수 표현식 코드와 동일한 코드를 화살표 함수로 변형하여 나타냄
// 화살표 함수
const sum2 = (a, b) => {
return a + b;
};
// 본문이 1줄인 경우, 중괄호와 return을 생략하고 한 줄에 이어서 쓸 수 있음!!
const sum3 = (a, b) => a + b;
// 매개변수가 1개일 경우, "()" 생략 가능함!!
const sum4 = (a) => a + 1;
// const sum5 = a => a + 1; // 이것도 오류 없이 정상 실행되지만 많은 개발자들이 소괄호와 중괄호를 사용하여 코드를 작성함(일종의 syntax에 해당)
1-4) 콜백 함수(callback function)
// (매우 중요)함수도 값이다!!
// callback 함수 : 함수도 값이기에 매개변수에도 함수를 넣을 수 있음!!
// callback 함수 예시
function hello(fn) {
console.log(fn());
}
function print() {
return 10;
}
hello(print); // 출력 결과 : 10
// 매개변수(parameter)의 값은 함수 자체의 값이고, 'hello' 함수 호출 시 '인수값(argument)'으로 함수값을 전달함!!
// 'hello' 함수 내부에서 'print' 함수를 호출함
// 이 내용을 이해하기 위해서는 "함수도 값이다"라는 사실을 반드시 유념해야 함!!
// callback 함수 내에서도 인수값(argument)을 넣을 수 있다!
function hello2(fn) {
let sangbeom = "javascript";
console.log(fn(sangbeom));
}
function print2(name) {
return 10 + name;
}
hello2(print2); // 출력 결과 : 10javascript
/*
함수 선언문과 함수 표현식의 차이점
- 함수 표현식의 장점 : "호이스팅" 해결
- 함수 표현식의 단점 : 가독성 이슈
*/
function ingoo(callback) {
return callback;
}
function goak(callback) {
const fn = function () {
return 30;
};
const result = 1 + callback(fn);
return result;
}
function getNumber(callback) {
return 2 * callback();
}
console.log(goak(getNumber)); // 출력 결과 : 61
// 위의 함수들을 화살표 함수로 바꿔서 표현한 것
const ingoo = (callback) => callback
const goak = (callback) => 1 + callback(() => 30)
const getNumber = (callback) => 2 * callback()
1-5) 콜스택 / 콜백 함수 활용 예시
function goak(callback) {
const fn = function () {
console.log("1");
return 30;
};
const result = 1 + callback(fn);
console.log("2");
return result;
}
function getNumber(callback) {
console.log("3");
return 2 * callback();
}
console.log(goak(getNumber));
console.log(getNumber(() => 60));
/*
출력 결과
3
1
2
61
3
120
*/
2) Javascript 객체
2-1) 객체 생성 방법
// 객체는 자바스크립트를 잘 다루기 위해 꼭 알아야 할 '데이터'이다!
// '데이터 타입'은 크게 '원시형'과 '객체형'의 2가지로 분류됨!
/*
1) 원시형
- 문자형
- 숫자형
- boolean
- undefined
- null
2) 객체형(참조형)
- 배열
- 객체
...
*/
// 객체를 만드는 방법(문법)
// 1. 객체 생성자 문법 : new 키워드를 사용하여 객체를 생성하는 방법
const user = new Object();
console.log(user); // 출력 결과: {}
// 2. 객체 리터럴 문법 : "{}"를 활용하여 객체를 생성하는 방법
const user2 = {};
console.log(user2); // 출력 결과: {}
// 변수 하나에 여러가지 데이터를 담고싶을 때 사용하는 것이 "배열"이다! >> 어떤 특정 리스트를 구현할 때 좋음
// 변수 하나에 여러가지 데이터를 담고싶을 때 사용하는 것이 "객체"이다! >> 어떤 특정 사람 혹은 사물의 상세정보를 입력할 때 좋음
const students = ["곽인구", "강찬수", "김건영", "김성희", "김주형"];
// 배열에 학생 리스트를 담는다면, 총 학생 숫자도 구하기 쉽고, 하나의 변수에 배열로 담다보니 관리가 용이하다!
// 하지만 배열의 경우, 학생 한 명의 정보를 저장하는 데에는 한계가 있다.
// 학생 한 명의 정보를 저장하기 위해서 사용하는 '데이터 타입'이 바로 '객체'이다!!
// 객체는 사람, 주문, 에어컨 등과 같이 실제 존재하는 개체를 표현할 때 적합하다!
const Person = {
name: "곽인구",
age: 32,
"content-type": "text/javascript",
};
console.log(Person);
// 객체는 우리가 앞서 배웠던 CSS 문법과 굉장히 유사하다!!
// 변수 'Person' 안에서 'name' key에는 '곽인구'라는 value를 입력하고,
// 'age' key에는 32라는 value를 입력함!!
// '데이터 타입'에는 어떠한 것이든 들어올 수 있음!!
// >> String, Number, Boolean, Function, Array, Object
2-2) 점 표기법 / 응용 방법
// 객체 또한 변수 하나에 여러가지 값이 있다보니, 특정 값만 뽑아올 수 있어야 함!
// 객체 안에 있는 'name'을 console.log();를 이용해 콘솔에 찍고 싶다면
// 아래와 같이 코드를 실행(점 표기법 활용)하면 됨!!
console.log(Person.name); // 점 표기법
// '점 표기법' 예시 >> 실행은 안 됨!!(console.log();가 이미 있기 때문에 syntax error가 발생함)
// const console = {
// log: function() {
// console.log('hello world')
// }
// }
// console.log()
// key 부분에 특수문자(-, \, ...)가 들어간 경우가 있음
// >> 이 경우, 양쪽 끝에 "", ''을 넣음(대부분은 ""를 씀)
// 만약 key에 특수문자가 들어갈 경우, value를 뽑고 싶다면 '점 표기법'이 아닌 '대괄호 표기법'을 사용해야 함!!
console.log(Person["content-type"]);
// 응용 방법 >> 임의의 변수를 하나 만든 다음에 "content-type" 내용을 해당 변수에 넣어주어도 됨!
let contentType = "content-type";
console.log(Person[contentType]);
// 객체는 '점 표기법'을 이용하여 key, value를 추가할 수 있음!!
Person2.height = 180;
console.log(Person2);
// 객체는 '점 표기법'을 이용하여 value를 수정할 수 있음!!
Person2.height = 170;
console.log(Person2);
2-3) in 연산자 / for in 문
// 목적 : 객체 안에 있는 'key'를 알아내는 방법 >> 'in 연산자'
// 'in 연산자'를 사용해서 특정 객체에 해당 key가 있는지 없는지 검사한 후 그 결과를 boolean 값(true / false)으로 반환함
const Person2 = {
name: "곽인구",
age: 32,
"content-type": "text/javascript",
};
console.log("name" in Person2); // true
console.log("subname" in Person2); // false
// for in 문 : 객체 내용을 반복문을 통해 안에 있는 정보를 다 보고 싶을 때 사용함
for (let key in Person2) {
console.log(key); // 해당 객체의 key 값 출력
console.log(Person2[key]); // 해당 객체의 value 출력
}
// 객체는 참조형 데이터 타입에 해당하기 때문에 value에 메모리 주소를 할당 시 실제 저장되어 있는 다른 공간의 메모리 주소를 입력하여 참조하도록 함!!
console.log({} === {}); // false(같지 않다!!) >> 서로 다른 주소값을 참조하고 있기 때문에 다르다!!
const obj = {};
const clone = obj;
console.log(clone === obj); // true(같다!!) >> 대입연산자를 통해 각각의 값에 대한 주소값을 그대로 할당했기에 같다!!
const clone2 = {};
const obj2 = {
name: "sang",
age: 27,
};
for (let key in obj2) {
clone2[key] = obj2[key];
}
console.log(clone2);
console.log(clone2 === obj2); // false(같지 않음)
/*
>> clone2는 앞서 이미 객체 리터럴 방식("{}"를 이용해 객체 생성)을 통해
객체를 새로 생성한 상태에서 for in 문을 활용해
각각의 key에 따른 value를 obj2에서 주소값을 가져와서 그대로 할당했기 때문에
각 key와 value들이 동일한 주소값을 참조할지라도 clone2라는 객체가 참조하는 주소값은
앞서 언급한대로 이미 객체 리터럴 방식을 이용해 객체를 새로 생성한 시점부터 이미 obj2와는
다른 주소값을 참조하고 있기에 비교 결과는 'false'가 출력됨!!
*/
2-4) Spread Operator(스프레드 연산자)
// Spread Operator(스프레드 연산자)
// 객체 리터럴 문법에서 안에 있는 key, value 쌍들에 대해 각각의 주소값을 그대로 가져와 참조하도록 함!!
const obj2 = {
name: "sang",
age: 27,
};
const clone3 = { ...obj2 };
console.log(clone3);
console.log(clone3 === obj2); // false
// >> 이유: 객체는 참조형(객체형) 데이터 타입에 해당하므로 스프레드 연산자를 사용해 데이터를
// 가져올 시 key와 value 자체가 아닌 각각의 key와 value들에 대한 주소값을 가져오는 것이기에
// 위의 코드의 경우, 스프레드 연산자를 쓰기 전에 먼저 "{}"를 사용해 새로운 객체를 생성한 뒤
// 스프레드 연산자를 통해 name, age key들에 대해 각각의 주소값을 가져와서 앞서 새로 생성한
// 객체에 넣어주었기에 데이터를 가져오는 obj2 객체와 clone3 객체는 참조하는 주소값이 달라지기에
// 결과적으로 'false'를 결과값으로 반환함!!
console.log(clone3.name === obj2.name); // true
// >> 이유: 객체는 앞서 살펴본 바와 같이 참조형(객체형) 데이터 타입에 해당하므로
// 스프레드 연산자를 사용해 데이터를 가져올 시 key와 value 자체가 아닌 각각의 key와 value들에 대한
// 주소값을 가져오는 것이기에 위의 코드의 경우, 스프레드 연산자를 쓰기 전에
// 먼저 "{}"를 사용해 새로운 객체를 생성한 뒤
// 스프레드 연산자를 통해 name, age key들에 대해 각각의 주소값을 가져와서 앞서 새로 생성한
// 객체에 넣어주었기에 데이터를 가져오는 obj2 객체의 각 key, value들과
// clone3 객체의 각 key와 value들은 동일한 주소값을 참조하게 되기 때문에
// 결과적으로 'true'를 결과값으로 반환함!!
2-5) 참조형 데이터 타입 활용 예시
// 참조형 데이터 타입 이해를 위한 예시
const obj3 = {
name: "sang",
age: 27,
sizes: {
height: 180,
weight: 80,
},
};
// const clone4 = { ...obj3, sizes: { ...obj3.sizes } };
// console.log(obj3.sizes === clone4.sizes); // false
const clone4 = { ...obj3 };
console.log(obj3.sizes === clone4.sizes); // true
console.log(obj3 === clone4); // false
clone4.sizes.height = 190;
console.log(clone4.sizes.height);
console.log(obj3.sizes.height);
/*
코드 설명
우선 obj3의 경우, 데이터 타입이 객체이기에 참조형에 해당하므로
const 예약어를 통해 clone4를 선언하고 값으로 "{ ...obj3, sizes: { ...obj3.sizes } }"을
할당하면 먼저 스프레드 문법을 적용하여 앞서 정의한 obj3의 객체 리터럴 문법을 해제("{}"를 벗겨낸다는 의미)하고
각 key, value 쌍들을 clone4 객체에 넣어준다.
(여기까지 하고 두 객체를 비교하면 두 객체는 동일한 주소값을 참조하고 있기에 비교 시 같다고 확인 가능합니다.)
이때 "sizes" key 같은 경우, 앞서 obj3 전체를 스프레드 문법을 적용하여 푼 다음 객체 안의 값들을
그대로 clone4에 넣어준 뒤 해당 key에 대해 새로운 객체를 생성한다. 그리고 기존 obj3의 sizes key 안의 value들을
스프레드 문법으로 해제하여 해당 값을 새로운 주소값을 가진 sizes key의 value를 key, value 쌍들로 채운다.
이렇게 되면 "obj3.sizes === clone4.sizes"가 값 자체는 동일하지만 서로 다른 주소값을 참조하고 있기 때문에
비교 결과를 boolean 값 중 false로 출력한다. 이것은 객체가 원시타입이 아닌 참조형 데이터 타입이기 때문이다.
이어서 아래의 "clone4.sizes.height = 190;"를 실행시켜 clone4의 'sizes' key 내부의 'height' key를
190으로 재할당하여 값을 수정하면,
console.log(clone4.sizes.height);는 수정된 값인 190이 콘솔에 출력되고,
console.log(obj3.sizes.height);는 애초에 obj3와 clone4의 참조값이 다르기에 obj3의
height key의 value인 180이 그대로 유지되고 출력된다.
만일 앞서 const 예약어를 사용해 clone4를 선언하고 값을 할당할 시 기존 값인
"{ ...obj3, sizes: { ...obj3.sizes } }"에서 "sizes: { ...obj3.sizes }"를 빼고
단순히 obj3 내부의 key, value 쌍들을 스프레드 문법을 통해 중괄호를 벗겨서
해당 값들을 그대로 넣어준다면
"obj3.sizes === clone4.sizes"는 clone4의 sizes key 값은
obj3의 key 값을 그대로 참조하기에 결과값이
true로 나온다.
이어서 "clone4.sizes.height = 190;"은 clone4와 obj3 중
어느 하나의 sizes key 내부의 height key 값을 재할당하여
수정하면 양쪽에 수정사항이 반영되어 동일하게 190으로 출력된다.
*/
// 대부분 자바스크립트 코드 작성 시 참조형 데이터 타입(객체, 배열)은 const로 선언함!!
// (참고) 원시 데이터 기준으로는 한 메모리 안에 하나의 값이 할당됨!!
'Javascript > Javascript(2022 version)' 카테고리의 다른 글
Javascript 기초(6) - 상속 및 메서드 (0) | 2022.11.04 |
---|---|
Javascript 기초(5) - 객체 및 메서드 (0) | 2022.11.03 |
Javascript 기초(3) - 함수 (0) | 2022.11.01 |
Javascript 기초(2) - 기본 문법 및 예시 코드 정리 (0) | 2022.10.31 |
Javascript 기초 - 프로그래밍 기초 및 Javascript 기초 문법 (0) | 2022.10.28 |