Node.js
- Node.js는 JavaScript 런타임 환경으로 서버 애플리케이션을 개발하는데 주로 사용된다.
- function
function sum(num1, num2){
console.log('sum() 호출!');
return num1 + num2;
}
const result = sum(10, 20);
console.log(result);
console.log('-----------------');
// 함수의 메모리 주소 전달하는 방법
const add = sum;
console.log(sum(10, 30));
console.log(add(10, 30));
console.log('-----------------');
// 함수의 작성팁
// 조건식이 있을 때 조건을 만족하지 않는 경우를 함수 도입부분에서 모두 처리 후 함수를 미리 종료
function print(num){
if(num < 0) return;
console.log(num);
}
print(10);
print(-5);
console.log('-----------------');
// 매개변수의 기본값을 무조건 undefined
// arguments: 함수의 전달된 인수에 해당하는 값을 array 형태의 객체로 반환
function total(num1, num2){
console.log(num1);
console.log(num2);
console.log('arguments: ', arguments);
console.log('arguments: ', arguments[0]);
console.log('arguments: ', arguments[1]);
return num1 + num2;
}
console.log(total());
console.log(total(10, 20));
console.log('-----------------');
// 콜백 함수 활용
const calc_add = (a, b) => a + b;
const calc_multiply = (a, b) => a * b;
console.log(calc_add(10, 20));
console.log(calc_multiply(10, 20));
// calculater(num1, num2, action)
function calculater(num1, num2, action){
if(num1 < 0 || num2 < 0) return;
const result = action(num1, num2);
console.log(result);
return result;
}
calculater(4, 2, calc_add);
calculater(4, 1, calc_multiply);

nodejs에서 function의 기본값은 undefined이다.
arguments는 함수가 호출될 때 전달된 모든 인수를 포함하는 객체이다. 반환값은 배열과 비슷한 형태의 객체를 반환한다.
- object
const Rucy = {
name: "몽이",
age: 14,
weight: 3.5,
["height"]: 0.7,
["owner-name"]: "오너",
};
console.log(Rucy.name);
console.log(Rucy.weight);
console.log(Rucy.height);
// console.log(Rucy.owner-name);
console.log(Rucy["owner-name"]);
Rucy.family = "허스키";
console.log(Rucy.family);
console.log(Rucy["family"]);
console.log(Rucy);
delete Rucy["owner-name"];
console.log(Rucy["owner-name"]);
console.log(Rucy);
console.log("-------------------");
// 동적으로 프러퍼티에 접근하는 함수
function getValue(object1, key) {
return object1[key];
}
getValue(Rucy, "name");
console.log(Rucy);
// 동적으로 요소를 추가하는 함수
function addKey(object2, key, value) {
return (object2[key] = value);
}
addKey(Rucy, "owner-name", "오너");
console.log(Rucy);
// 동적으로 요소를 삭제하는 함수
function deleteKey(object4, key) {
delete object4[key];
}
deleteKey(Rucy, "owner-name");
console.log(Rucy);
console.log("-------------------");
// 객체 생성 함수 만들기
// 좌표 객체 만들기
const x = 0;
const y = 0;
const coord = { x, y };
console.log(coord);
// 이름, 나이를 전달하여 객체로 만들어주는 함수 만들기
function makeObj(name, age) {
return { name, age };
}
console.log(makeObj("오너", 20));
console.log("-------------------");
// 리터럴 표기법으로 객체 만들기
const apple = {
name: "사과",
display: function () {
console.log(`${this.name}: 🍎`);
},
};
const banana = {
name: "바나나",
display: function () {
console.log(`${this.name}: 🍌`);
},
};
console.log(apple);
apple.display();
console.log(banana);
banana.display();
// Fruit 생성자를 만들고 위 결과와 같은 동일한 결과를 출력하는 객체를 만들어보자.
// Fruit(name, emoji)
// const apple = new Fruit('apple', '🍎');
// console.log(apple);
// apple.display();
function Fruit(name, emoji) {
this.name = name;
this.emoji = emoji;
this.display = () => {
console.log(`${this.name}: ${this.emoji}`);
};
}
const apple1 = new Fruit("apple", "🍎");
const banana1 = new Fruit("banana", "🍌");
console.log(apple1);
apple1.display();
console.log(banana1);
banana1.display();

- class
class Fruit{
// static
// 정적 프러퍼티 및 메서드를 생성
// 클래스 레벨 메소드에서는 this를 참조할 수 없음
static count_fruits = 10;
static makeBanana(){
return new Fruit('banan', '🍌');
}
constructor(name, emoji){
this.name = name;
this.emoji = emoji;
}
display = () => {
console.log(`${this.name}: ${this.emoji}`);
}
}
const apple = new Fruit('apple', '🍎');
console.log(apple);
apple.display();
console.log('----------------');
console.log(Fruit.count_fruits);
const banana = Fruit.makeBanana();
console.log(banana);
console.log('-------------------');
// 객체지향 프로그래밍의 은닉성
// private
class Dog{
#name; // private
#color;
constructor(name, color){
this.#name = name;
this.#color = color;
}
// 프러퍼티명과 setter 프러퍼티메서드의 이름은 일치할 필요없음
set name(value){
console.log('set', value);
this.#name = value;
}
get name(){
return this.#name;
}
set color(value){
console.log('set', value);
this.#color = value;
}
get color(){
return this.#color;
}
run = () => {
console.log(`${this.#color} 생삭의 강아지 ${this.#name}달립니다.`);
}
#eat = () => {
console.log(`${this.#name} 사료를 먹습니다.`);
}
myEat = () => {
this.#eat();
}
}
const Rucy = new Dog('루시', '흰색');
console.log(Rucy);
console.log(Rucy.name);
// set 프러퍼티가 실행
Rucy.name = '복실';
// get 프러퍼티가 실행
console.log(Rucy.name);
Rucy.run();
Rucy.myEat();

- inherit
class Animal {
constructor(color){
this.color = color;
}
eat(){
console.log('먹습니다.');
}
sleep(){
console.log('잡니다.');
}
// 오버라이딩
eat(){
console.log('맛있게 먹습니다.');
}
}
class Dog extends Animal{
constructor(color){
super(color); // 부모에게 값을 넘겨줌..?
}
play(){
console.log('놉니다.');
}
}
const Rucy = new Dog('흰색');
console.log(Rucy);
Rucy.eat();
Rucy.sleep();
Rucy.play();

이터레이터(Iterator)
- 이터레이터는 이터러블 객체를 통해 값의 시퀀스를 반복하는 데 사용되는 인터페이스, 반복자이다.
- next() 메서드를 구현하는 객체이다. (next() 메서드는 현재 요소를 반환하고 다음 요소로 이동하는 메서드이다.)
const arr = [1, 2, 3, 4, 5];
console.log(arr.values());
console.log(arr.entries());
console.log(arr.keys());
const iterator = arr.values();
while(true){
const item = iterator.next();
if(item.done) break;
console.log(item.value);
}
for(let item of arr){
console.log(item);
}

value 값을 가져오기에 arr안에 있는 1~5까지 가져오게 된다.

key값을 가져오기에 arr안에 인덱스 0~4까지 가져오게 된다.

entries는 [ key, value ] 형태로 이루어져 있다. 그래서 값을 가져오면 [ key, value ] 형태로 가져오게 되는 것이다.
이터러블(Iterable)
- 이터러블은 반복 가능한 객체를 말하며, [Symbol.iterator] 메서드를 구현해야 한다.
- [Symbol.iterator] 메서드는 이터레이터를 반환하는 함수이다.
- 이터러블 객체는 for..of 루프나 배열 같은 반복 가능한 객체를 사용하는 문맥에서 반복될 수 있다.
function iterable(){
let index = 0;
let data = [1, 2, 3, 4];
return {
next(){
if(index < data.length){
return {value:data[index++], done:false};
}
else{
return {value:undefined, done:true};
}
}
}
}
let i = iterable();
console.log(i.next());
console.log(i.next());
console.log(i.next());
console.log(i.next());
console.log(i.next());

위 코드를 보면 next() 메서드 내부에서 현재 인덱스의 길이를 초과하지 않는지 확인하고, 인덱스 길이를 초과하지 않으면 {value:data[index++], done:false} 를 반환하고, 길이를 초과하면 {value:undefined, done:true} 를 반환한다.
반복이 종료되면 iterable 함수를 호출하여 이터레이터 객체 i를 생성한다. 그 후 next() 메서드를 호출하여 반환된 값을 출력한다.
스프레드(Spread) 연산자
- 배열이나 객체를 펼쳐서 개별 요소로 분해할 수 있다. 즉, 배열이나 객체를 복사하거나, 다른 배열이나 객체에 요소를 추가하거나 결합할 때 유용하게 사용된다.
// 원시값과 객체값의 비교
// 원시값: 값에 의한 복사가 일어남
// 객체값: 참조에 의한 복사(메모리 주소)
function display(num) {
num = 10;
console.log(num);
}
const value = 5;
display(value);
console.log(value);

원시값인 value의 값을 복사하여 num이라는 변수에 들어간 것이기 때문에 이후에 num 값이 변해도 원시값인 value의 값은 변경되지 않는다.
// 객체의 값을 변경하는 것은 좋지 않은 알고리즘
function displayObj(obj) {
obj.age = 14;
console.log(obj);
}
const Rucy = { name: "몽이", age: 15 };
displayObj(Rucy);
console.log(Rucy);
// 객체를 복사하여 age 를 변환하고 해당 객체를 반환
function changeAge(obj) {
return { ...obj, age: 6 };
}
PPomi = changeAge(Rucy);
console.log(Rucy);
console.log(PPomi);

첫 번째 호출에서 Rucy의 age 값을 14로 변경하고 출력이 된다. Rucy 객체에 age를 15로 바꿔도 displayObj를 호출하고 Rucy를 담았기 때문에 15가 아닌 14가 나오게 된다. 그 이후에도 Rucy의 age는 14로 유지가 된다.
하지만 두 번째 호출에서는 changeAge 함수가 Rucy를 복사하고 age 값을 6으로 변경했기 때문에 PPomi의 age는 6이 된다.
즉, Rucy, PPomi 객체는 서로 다른 메모리 공간에 저장되어 있다는 것을 알 수 있다.
function add(num1, num2, num3) {
return num1 + num2 + num3;
}
const nums = [10, 20, 30];
console.log(add(10, 20, 30));
console.log(add(nums[0], nums[1], nums[2]));
console.log(add(...nums));
console.log("--------------------");
const fruits1 = [":사과:", ":수박:"];
const fruits2 = [":바나나:", ":딸기:"];
let arr = fruits1.concat(fruits2);
console.log(arr);
arr = [...fruits1, ...fruits2];
console.log(arr);
arr = [...fruits1, "🍀", ...fruits2];
console.log(arr);

숫자 합산에서는 첫 번째, 두 번째는 인덱스를 개별적으로 전달하여 계산을 한다. 마지막 세 번째는 Spread문법을 사용하여 배열을 펼쳐서 전달하여 같은 값이 반환된다.
과일 이름 나열에서는 첫 번째는 두 개의 배열을 concat을 사용하여 연결한 것이다. 두 번째는 Spread문법을 사용하여 concat과 같은 결과값을 반환한 것을 볼 수 있다. 세 번째는 이모티콘 문자열을 추가하여 Spread문법을 사용하여 연결한 것이다. 즉, Spread 문법은 배열을 합치거나 요소를 추가할 수 있다는 것을 알 수 있다.
const apple = {
name: "몽주인",
age: 20,
address: { si: "서울시", gu: "송파구", dong: "석촌동" },
};
console.log(apple);
const new_apple = { ...apple, job: "프로그래머" };
console.log(apple);
console.log(new_apple);

Spread 문법을 사용하여 사용하여 apple객체를 복사하여 new_apple 객체를 생성하고 속성을 추가한 것이다.
즉, apple 객체에는 속성이 추가되지 않고, 복사한 new_apple객체에만 속성이 추가된 것을 알 수 있다.
const fruits = ["🍏", "🍐", "🍑", "🍒", "🍓", "🍅", "🍆", "🌽"];
const [fruit1, fruit2, ...others] = fruits;
console.log(fruit1);
console.log(fruit2);
console.log(others);
function sendEmoji() {
return ["🍏", "🍐", "🍑", "🍒", "🍓", "🍅", "🍆", "🌽"];
}
const [f1, f2, f3, f4, f5] = sendEmoji();
console.log(f1);
console.log(f2);
console.log(f3);
console.log(f4);
console.log(f5);

fruits에서 첫 번째, 두 번째 요소를 출력하고, Spread문법을 사용하여 나머지 요소를 others 배열에 할당하고 출력이 된다.
sendEmoji 함수에서는 반환된 배열의 요소들을 차례대로 출력한다. 인덱스 0 ~ 4까지의 요소들이 출력이 된다.
'Web > javascript' 카테고리의 다른 글
Node.js buffer, stream, pipe (0) | 2024.04.25 |
---|---|
Node.js (비)동기, Promise, JSON, fetch, module, import... 등 (0) | 2024.04.23 |
JavaScript 정규표현식, 이벤트 (1) | 2024.04.22 |
JavaScript 제어문, 배열, 배열 반복, 함수, 객체1 (0) | 2024.04.16 |
JavaScript 변수, 데이터 타입, 타입변환 함수, 연산자 (1) | 2024.04.15 |