3번 사분면 고르기

문제

흔한 수학 문제 중 하나는 주어진 점이 어느 사분면에 속하는지 알아내는 것이다. 사분면은 아래 그림처럼 1부터 4까지 번호를 갖는다. "Quadrant n"은 "제 n사분면"이라는 뜻이다.

https://www.acmicpc.net/problem/14681

 

예를 들어, 좌표가 (12, 5)인 점 A는 x좌표와 y좌표가 모두 양수이므로 제1사분면에 속한다. 점 B는 x좌표가 음수이고 y좌표가 양수이므로 제2사분면에 속한다. 점의 좌표를 입력받아 그 점이 어느 사분면에 속하는지 알아내는 프로그램을 작성하시오. 단, x좌표와 y좌표는 모두 양수나 음수라고 가정한다.

 

입력

첫 줄에는 정수 x가 주어진다. (−1000 ≤ x ≤ 1000; x ≠ 0) 다음 줄에는 정수 y가 주어진다. (−1000 ≤ y ≤ 1000; y ≠ 0)

 

출력

점 (x, y)의 사분면 번호(1, 2, 3, 4 중 하나)를 출력한다.

 

x 가 양수인지 음수인지, y가 양수인지 음수인지 구분해서 조건

 

C++

#include <iostream>
using namespace std;
int main(){
    int x, y;
    cin >> x;
    cin >> y;
    char result;
    if (x > 0)
    {
        if (y > 0)
            result = '1';
        else 
            result = '4';
    }
    else{
        if (y > 0)
            result = '2';
        else
            result = '3';
    }
    cout << result;
    return 0;
}

 

 

C#

using System;
class Program{
    static void Main(string[] args){
        string inputX = Console.ReadLine();
        string inputY = Console.ReadLine();
        int x = int.Parse(inputX);
        int y = int.Parse(inputY);
        char result;
        if (x > 0)
        {
            if (y > 0)
                result = '1';
            else 
                result = '4';
        }
        else{
            if (y > 0)
                result = '2';
            else
                result = '3';
        }
        Console.WriteLine(result);
    }
}

 

앞의 문제들과 다르게 각 줄에 값들이 들어온다. 따라서 입력을 따로 두 번 받아서 값을 저장한다.

 

Python

x = int(input());
y = int(input());
if x > 0:
    if y > 0:
        result = '1';
    else:
        result = '4';
else:
    if y > 0:
        result = '2';
    else:
        result = '3';
print(result);

 

파이썬에서 중첩 조건문을 쓸 때는 들여 쓰기로 구분한다.

 

Node.js

const readline = require('readline');
const rl = readline.createInterface({
    input : process.stdin,
    output : process.stdout
});
let x, y;
let result;
rl.question('', (answerX)=>{
    x = parseInt(answerX, 10);
    rl.question('', (answerY)=>{
    y = parseInt(answerY, 10);
        if (x > 0){
            if (y > 0)
                result = '1';
            else
                result = '4';
        }
        else{
            if (y > 0)
                result = '2';
            else
                result = '3';   
        }
        console.log(result);
        rl.close();
    });
});

 

각 각의 입력을 받고 처리한다.

rl.close()가 호출되면 입력된 값을 사용할 수 없기 때문에 호출 전에 결과를 출력해야 한다.

728x90
반응형

3번 윤년

문제

연도가 주어졌을 때, 윤년이면 1, 아니면 0을 출력하는 프로그램을 작성하시오. 윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때 또는 400의 배수일 때이다. 예를 들어, 2012년은 4의 배수이면서 100의 배수가 아니라서 윤년이다. 1900년은 100의 배수이고 400의 배수는 아니기 때문에 윤년이 아니다. 하지만, 2000년은 400의 배수이기 때문에 윤년이다.

 

입력

첫째 줄에 연도가 주어진다. 연도는 1보다 크거나 같고, 4000보다 작거나 같은 자연수이다.

 

출력

첫째 줄에 윤년이면 1, 아니면 0을 출력한다.

 

연도가 4의 배수 && (100의 배수가 아닐 때  || 400의 배수일 때)

 

C++

#include <iostream>
using namespace std;
int main(){
    int input;
    cin >> input;
    char result;
    if ((input % 4) == 0 && ((input % 100) != 0 || (input % 400) == 0))
        result = '1';
    else
        result = '0';
    cout << result;
    return 0;
}

 

배수인지 확인할 때는 나머지가 0인지를 확인하면 된다.

 

C#

using System;
class Program{
    static void Main(string[] args){
        int input = int.Parse(Console.ReadLine());
        char result;
        if ((input % 4) == 0 && ((input % 100) != 0 || (input % 400) == 0))
            result = '1';
        else
            result = '0';
        Console.WriteLine(result);
    }
}

 

Python

inputData = int(input());
if inputData % 4 == 0 and (inputData % 100 != 0 or inputData % 400 == 0):
    result = '1';
else:
    result = '0';
print(result);

 

파이썬의 논리 연산자는 and, or, not으로 작성한다.

 

Node.js

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim();
const year = parseInt(input, 10);
let result;
if ((input % 4) == 0 && ((input % 100) != 0 || (input % 400) == 0))
    result = '1';
else
    result = '0';
console.log(result);

 

728x90
반응형

2번 시험 성적

문제

시험 점수를 입력받아 90 ~ 100점은 A, 80 ~ 89점은 B, 70 ~ 79점은 C, 60 ~ 69점은 D, 나머지 점수는 F를 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 시험 점수가 주어진다. 시험 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.

 

출력

시험 성적을 출력한다.

 

C++

#include <iostream>
using namespace std;
int main(){
    int score;
    cin >> score;
    char result;
    if (score >= 90) {
        result = 'A';
    }
    else if (score >= 80){
        result = 'B';
    }
    else if (score >= 70){
        result = 'C';
    }
    else if (score >= 60){
        result = 'D';
    }
    else {
        result = 'F';
    }
    cout << result;
    return 0;
}

 

C#

using System;
class Program{
    static void Main(string[] args){
        int score = int.Parse(Console.ReadLine());
        char result;
        if (score >= 90)
            result = 'A';
        else if (score >= 80)
            result = 'B';
        else if (score >= 70)
            result = 'C';
        else if (score >= 60)
            result = 'D';
        else
            result = 'F';
        Console.WriteLine(result);
    }
}

 

Python

score = int(input());
if score >= 90: 
    result = 'A'
elif score >= 80:
    result = 'B'
elif score >= 70:
    result = 'C'
elif score >= 60:
    result = 'D'
else:
    result = 'F'
print(result);

 

파이썬에서 조건문을 사용할 때는 들여 쓰기에 주의해야 한다.

 

Node.js

const fs = require('fs');
const inputData = fs.readFileSync('/dev/stdin').toString().trim();
const score = parseInt(inputData, 10);
let result;
if (score >= 90)
    result = 'A';
else if (score >= 80)
    result = 'B';
else if (score >= 70)
    result = 'C';
else if (score >= 60)
    result = 'D';
else 
    result = 'F';

console.log(result);

 

'fs' 모듈 사용해서 입력 처리

728x90
반응형

1번 두 수 비교하기

문제

두 정수 A와 B가 주어졌을 때, A와 B를 비교하는 프로그램을 작성하시오.

 

입력

첫째 줄에 A와 B가 주어진다. A와 B는 공백 한 칸으로 구분되어 있다.

 

출력

첫째 줄에 다음 세 가지 중 하나를 출력한다. 

- A가 B보다 큰 경우에는 '>'를 출력한다. 

- A가 B보다 작은 경우에는 '<'를 출력한다. 

- A와 B가 같은 경우에는 '=='를 출력한다.

 

C++

#include <iostream>
#include <string>
using namespace std;
int main(){
    int a, b;
    cin >> a;
    cin >> b;
    string result = "";
    if (a > b)
        result = ">";
    else if (a < b)
        result = "<";
    else
        result = "==";
    cout << result;
    return 0;
}

 

C#

using System;
class Program{
    static void Main(string[] args){
        string input = Console.ReadLine();
        string[] arr = input.Split(' ');
        int a = int.Parse(arr[0]);
        int b = int.Parse(arr[1]);
        if (a > b) input = ">";
        else if (a < b) input = "<";
        else input = "==";
        Console.WriteLine(input);
    }
}

 

Python

strInput = input()
arrInput = strInput.split(' ')
a = int(arrInput[0])
b = int(arrInput[1])
if a > b: 
    c = ">"
elif a < b: 
    c = "<"
else: 
    c = "=="
print(c);

 

파이썬의 경우 조건문 작성 시

if 조건 :

elif 조건 :

else :

 

방식으로 작성한다. 그리고 중요한 점은 파이썬의 변수의 범위는 함수 단위로 이루어지기 때문에 조건문 내부에서 선언된 c는 외부에서도 접근이 가능하다. 하지만 함수 내에서 변수를 선언했다면 외부에서 접근할 수 없다.

 

Node.js

const readline = require('readline');
const rl = readline.createInterface({
    input:process.stdin,
    output:process.stdout
});

rl.question('', (answer) =>{
    let input = answer;
    let arr = input.split(' ');
    let a = parseInt(arr[0], 10);
    let b = parseInt(arr[1], 10);
    let result;
    if (a > b) {
        result = ">";   
    }
    else if (a < b) {
        result = "<";    
    }
    else {
        result = "==";  
    } 
    process.stdout.write(result);
    rl.close();
});

 

node.js 에서 입력은 모듈을 사용하여 처리한다.

 

1. 'readline' 모듈을 사용하여 입력 인터페이스를 생성한다.

2. 'rl.question'을 사용하여 사용자로부터 숫자를 입력받는다.

 

더 축약한 코드

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question('', (answer) => {
    const [a, b] = answer.split(' ').map(Number);
    const result = (a > b) ? '>' : (a < b) ? '<' : '==';
    process.stdout.write(result);
    rl.close();
});

 

map을 사용하여 입력된 값을 저장하고 삼항 연산자로 조건을 비교하여 코드를 단축시켰다.

 

728x90
반응형

고차 함수

고차 함수는 함수형 프로그래밍 개념 중 하나로 함수를 인수로 받거나, 함수를 반환하는 함수를 말한다.

코드를 더 모듈화 하고 재사용 가능하게 만들며, 함수 조합과 같은 고급 프로그래밍 기술을 사용할 수 있게 해 준다.

 

함수를 인수로 받는 고차 함수

고차 함수는 다른 함수를 인수로 받아서 호출하거나, 인수로 받은 함수를 내부에서 사용하는 함수이다. 자바스크립트의 내장 메서드 중 'map', 'filter', 'reduce' 등이 이에 해당한다.

 

map

배열의 각 요소에 대해 제공된 함수를 호출하고, 그 결과를 새로운 배열로 반환한다.

const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

 

여기서 'map' 함수는 'num => num * 2' 함수를 인수로 받아, 배열 'numbers'의 각 요소에 대해 이 함수를 호출한다.

 

filter

배열의 각 요소에 대해 제공된 함수를 호출하고, 그 결과가 'true'인 요소만을 포함하는 새로운 배열을 반환한다.

const numbers = [1, 2, 3, 4, 5];

const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

 

여기서 'filter' 함수는 'num => num % 2 === 0' 함수를 인수로 받아, 배열 'numbers'의 각 요소에 대해 이 함수를 호출하고, 짝수인 요소만을 포함하는 새로운 배열을 반환한다.

 

함수를 반환하는 고차 함수

고차 함수는 새로운 함수를 반환할 수도 있다. 이를 통해 함수 조합이나 부분 적용(Partial Application)을 쉽게 구현할 수 있다.

 

함수 생성기

function createMultiplier(multiplier) {
    return function(value) {
        return value * multiplier;
    };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

 

여기서 'createMultiplier' 함수는 'multiplier'를 인수로 받아, 'value'를 인수로 받아 'value'와 'multiplier'의 곱을 반환하는 함수를 반환한다.

 

함수 조합기

function compose(f, g) {
    return function(x) {
        return f(g(x));
    };
}

const addOne = x => x + 1;
const square = x => x * x;

const addOneAndSquare = compose(square, addOne);

console.log(addOneAndSquare(2)); // 9

 

'compose' 함수는 두 함수를 받아, 먼저 'g' 함수를 호출하고 그 결과를 'f' 함수에 전달하는 새로운 함수를 반환한다.

 

함수를 실행하면 addOne(2)가 먼저 실행되어 3을 반환하게 된다.

square 함수에 위의 반환값 3으로 실행되어 최종 출력값은 9가 된다.

 

고차 함수의 장점

1. 재사용성

고차 함수는 인수로 전달된 함수에 따라 다른 동작을 수행할 수 있어, 더 유연하고 재사용 가능한 코드를 작성할 수 있다.

 

2. 모듈화

고차 함수는 코드의 기능을 작은 단위로 나누고, 이를 조합하여 더 복잡한 동작을 만들 수 있게 한다.

 

3. 가독성

고차 함수를 사용하면 반복적인 패턴을 추상화하여 코드의 가독성을 높일 수 있다.

 

이벤트 처리

function addEventListener(element, event, handler) {
    element.addEventListener(event, handler);
}

const button = document.querySelector('button');
addEventListener(button, 'click', () => alert('Button clicked!'));

 

여기서 'addEventListener' 함수는 'handler' 함수를 인수로 받아, 특정 이벤트가 발생했을 때 이를 처리한다.

 

데이터 변환

const data = [
    { name: 'Bak', age: 25 },
    { name: 'Kim', age: 30 },
    { name: 'Lee', age: 35 }
];

const names = data.map(person => person.name);
console.log(names); // ['Bak', 'Kim', 'Lee']

 

'map' 함수는 'person => person.name' 함수를 인수로 받아, 'data' 배열의 각 객체에서 이름을 추출하여 새로운 배열을 만든다.

728x90
반응형

'Program Language > JavaScript' 카테고리의 다른 글

Arrow Function  (0) 2024.08.26
this  (0) 2024.08.26
JavaScript #16 객체지향 프로그래밍(OOP)  (0) 2024.07.23
JavaScript #15 비동기 자바스크립트  (0) 2024.07.23
JavaScript #14 ES6+ 문법  (4) 2024.07.23

객체 지향 프로그래밍(OOP)

객체 지향 프로그래밍 (Object Oriented Programming)은 객체를 중심으로 프로그램을 설계하고 구현하는 방법론이다. 자바스크립트에서 OOP는 클래스와 인스턴스, 생성자 함수, 상속 그리고 프로토타입 개념을 통해서 구현된다.

 

클래스와 인스턴스

클래스는 객체를 생성하기 위한 블루프린트 또는 템플릿이다. 클래스는 속성과 메서드를 정의하며, 인스턴스는 클래스를 기반으로 생성된 객체를 의미한다.

 

클래스

ES6 이전에는 자바스크립트에서 클래스를 정의하기 위해 생성자 함수와 프로토타입을 사용했다. 이후에는 'class' 키워드가 추가되어 키워드를 사용하여 클래스를 정의할 수 있게 되었다.

 

클래스 정의

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    }
}

// 인스턴스 생성
const bak = new Person('Bak', 30);
bak.greet(); // "Hello, my name is Bak and I am 30 years old."

 

생성자 함수

생성자 함수는 클래스를 정의하는 전통적인 방법으로 'new' 키워드를 사용하여 생성자 함수를 호출하면 새로운 인스턴스가 생성된다.

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.greet = function() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

// 인스턴스 생성
const bak = new Person('Bak', 25);
bak.greet(); // "Hello, my name is Bak and I am 25 years old."

 

상속과 프로토타입

상속은 한 클래스가 다른 클래스의 속성과 메서드를 상속받아 사용하는 개념이다. 자바스크립트에서는 프로토타입 기반 상속을 사용한다. 자바스크립트의 모든 객체는 프로토타입 객체를 가지고 있으며, 다른 객체로부터 메서드와 속성을 상속받을 수 있다.

 

클래스 상속

ES6에서는 'extends' 키워드를 사용하여 상속을 구현할 수 있다.

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a noise.`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name); // 부모 클래스의 생성자를 호출
        this.breed = breed;
    }

    speak() {
        console.log(`${this.name} barks.`);
    }
}

const rex = new Dog('Rex', 'Labrador');
rex.speak(); // "Rex barks."

 

프로토타입 상속

ES6 이전에는 프로토타입을 사용하여 상속을 구현하였다.

function Animal(name) {
    this.name = name;
}

Animal.prototype.speak = function() {
    console.log(`${this.name} makes a noise.`);
};

function Dog(name, breed) {
    Animal.call(this, name); // 부모 생성자 호출
    this.breed = breed;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function() {
    console.log(`${this.name} barks.`);
};

const rex = new Dog('Rex', 'Labrador');
rex.speak(); // "Rex barks."

 

상속의 이점

상속의 특징을 제대로 이해하고 적절한 상황에 맞게 활용하는 것이 중요하다.

 

코드 재사용성

상속을 통해 기존 클래스의 기능을 재사용할  수 있기 때문에 이를 통해 중복 코드를 줄이고 새로운 기능을 쉽게 추가할 수 있다.

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a noise.`);
    }
}

class Dog extends Animal {
    speak() {
        console.log(`${this.name} barks.`);
    }
}

const dog = new Dog('Rex');
dog.speak(); // "Rex barks."

 

'Dog' 클래스는 'Animal' 클래스의 'name' 속성과 'speak' 메서드를 재사용하여 기능을 확장한다.

 

코드의 가독성과 유지보수성 향상

상속으로 클래스 간의 관계를 명확히 하고, 코드를 더 구조적이고 일관성 있게 작성하여 코드의 가독성을 높이고 유지보수를 쉽게 할 수 있다.

class Shape {
    constructor(color) {
        this.color = color;
    }

    draw() {
        console.log('Drawing a shape');
    }
}

class Circle extends Shape {
    constructor(color, radius) {
        super(color);
        this.radius = radius;
    }

    draw() {
        super.draw();
        console.log(`Drawing a circle with radius ${this.radius}`);
    }
}

const circle = new Circle('red', 5);
circle.draw();
// "Drawing a shape"
// "Drawing a circle with radius 5"

 

'circle' 클래스는 'shape' 클래스를 상속받아 'color' 속성과 'draw' 메서드를 재사용하고 필요한 기능을 추가한다. 이를 통해서 코드가 더 구조적이고 명확해지도록 할 수 있다.

 

다형성(Polymorphism)

다형성은 같은 메서드가 다양한 클래스에서 다른 방식으로 동작하도록 하는 것으로 코드의 유연성을 높일 수 있다.

class Animal {
    speak() {
        console.log('Animal makes a noise');
    }
}

class Dog extends Animal {
    speak() {
        console.log('Dog barks');
    }
}

class Cat extends Animal {
    speak() {
        console.log('Cat meows');
    }
}

function makeAnimalSpeak(animal) {
    animal.speak();
}

const dog = new Dog();
const cat = new Cat();

makeAnimalSpeak(dog); // "Dog barks"
makeAnimalSpeak(cat); // "Cat meows"

 

'makeAnimalSpeak' 함수는 'Animal' 클래스를 상속받는 객체를 인수로 받아 다형성을 통해 다양한 동작을 수행할 수 있다.

 

클래스 간의 계층 구조 정의

상속 구조는 클래스 간의 계층 구조를 정의할 수 있어 복잡한 시스템을 더 쉽게 이해하고 관리할 수 있다.

class Vehicle {
    constructor(brand) {
        this.brand = brand;
    }

    start() {
        console.log('Starting the vehicle');
    }
}

class Car extends Vehicle {
    constructor(brand, model) {
        super(brand);
        this.model = model;
    }

    start() {
        super.start();
        console.log(`Starting the car ${this.brand} ${this.model}`);
    }
}

const car = new Car('Toyota', 'Corolla');
car.start();
// "Starting the vehicle"
// "Starting the car Toyota Corolla"

 

'vehicle' 클래스는 기본적인 차량의 속성과 메서드를 정의하고, 'Car' 클래스는 이를 상속받아 구체적인 차량 모델을 정의한다. 이는 클래스 간의 관계를 명확히 하고 계층 구조를 쉽게 이해할 수 있다.

 

객체 간의 관계 모델링

상속을 사용하면 객체 간의 관계를 모델링하여 복잡한 시스템을 설계하고 구현하는 데 유용하다.

class Employee {
    constructor(name, position) {
        this.name = name;
        this.position = position;
    }

    work() {
        console.log(`${this.name} is working as a ${this.position}`);
    }
}

class Manager extends Employee {
    constructor(name, department) {
        super(name, 'Manager');
        this.department = department;
    }

    manage() {
        console.log(`${this.name} is managing the ${this.department} department`);
    }
}

const manager = new Manager('Bak', 'Sales');
manager.work(); // "Bak is working as a Manager"
manager.manage(); // "Bak is managing the Sales department"

 

'manager' 클래스는 'Employee' 클래스를 상속받아 관리자의 속성과 메서드를 정의하여 객체 간의 관계를 명확히 모델링할 수 있다.

 

상속은 객체 지향 프로그래밍에서 매우 유용한 개념이지만 과도하게 또는 잘못된 방식으로 사용하게 되면 오히려 코드의 복잡성을 증가시켜 유지보수를 어렵게 만들 수 있다.

728x90
반응형

'Program Language > JavaScript' 카테고리의 다른 글

this  (0) 2024.08.26
JavaScript #17 고차 함수(High-order Function)  (2) 2024.07.24
JavaScript #15 비동기 자바스크립트  (0) 2024.07.23
JavaScript #14 ES6+ 문법  (4) 2024.07.23
JavaScript #13 DOM(Document Object Model)  (0) 2024.07.23

비동기

비동기는 시간이 걸리는 네트워크 요청, 파일 읽기 등을 수행할 때 코드의 실행을 차단하지 않고 비동기적으로 처리할 수 있게 해주는 중요한 개념이다. 자바스크립트의 비동기와 관련된 기능들은 웹 애플리케이션을 더 빠르고 반응성이 좋게 동작하게 한다.

 

콜백 함수

콜백 함수는 다른 함수의 인수로 전달되는 함수이다.

비동기 작업이 완료되면 호출되며 비동기 작업을 처리하는 가장 기본적인 방법이다.

function fetchData(callback) {
    setTimeout(() => {
        const data = { id: 1, name: 'John Doe' };
        callback(data);
    }, 1000); // 1초 후에 콜백 함수 호출
}

fetchData((data) => {
    console.log('Data received:', data);
});

 

여기서 fetchData 함수는 1초 후에 데이터를 콜백 함수에 전달한다. 이 방식은 간단하지만, 여러 비동기 작업이 중첩될 경우 콜백 지옥이라 불리는 가독성이 떨어지는 코드가 될 위험이 있다.

 

프로미스

프로미스는 비동기 작업의 완료 또는 실패를 처리하는 객체이다. then, catch, finally 메서드를 사용하여 비동기 작업의 결과를 처리한다.

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { id: 1, name: 'John Doe' };
            resolve(data); // 성공적으로 데이터를 반환
        }, 1000);
    });
}

fetchData()
    .then((data) => {
        console.log('Data received:', data);
    })
    .catch((error) => {
        console.error('Error:', error);
    });

 

프로미스를 사용하면 코드의 가독성이 개선되고, 여러 비동기 작업을 체인으로 연결하여 처리할 수 있다. 프로미스가 성공적으로 완료될 때 resolve가 호출되며 'value'에는 성공적으로 완료된 후 전달되는 값이다. 실패할 경우 reject가 호출되며 'reason'은 프로미스가 실패한 이유를 나타내는 값이다.

 

프로미스는 대기(pending), 이행(fulfilled), 거부(rejected) 세 가지 상태를 가질 수 있다.

 

대기

프로미스가 생성된 초기 상태로 'then', 'catch', 'finally' 메서드가 아직 호출되지 않은 상태이다.

 

이행

프로미스가 성공적으로 완료된 상태로 'then' 메서드가 호출된다.

 

거부

프로미스가 실패한 상태로 'catch' 메서드가 호출된다.

 

프로미스가 이행, 거부 상관없이 작업이 완료되었을 때 항상 'finally'가 호출된다. 보통 프로미스의 상태에 상관없이 반드시 실행되어야 하는 리소스를 해제, 로딩 상태를 해제하는 등의 작업 같은 코드를 작성할 때 사용된다.

const myPromise = new Promise((resolve, reject) => {
  let success = true; // 작업 성공 여부를 결정하는 변수
  
  setTimeout(() => {
    if (success) {
      resolve("작업이 성공적으로 완료되었습니다!"); // 이행 상태로 전환
    } else {
      reject("작업이 실패했습니다."); // 거부 상태로 전환
    }
  }, 1000); // 1초 후에 상태 결정
});

myPromise
  .then((value) => {
    console.log("이행됨:", value); // 프로미스가 이행되면 실행
  })
  .catch((reason) => {
    console.log("거부됨:", reason); // 프로미스가 거부되면 실행
  })
  .finally(() => {
    console.log("프로미스가 완료됨."); // 프로미스가 완료되면 항상 실행
  });

 

async, await

async와 await 키워드는 ES2017에서 도입된 비동기 프로그래밍의 최신 방법이다.

async 함수는 항상 프로미스를 반환하며, await 키워드는 프로미스가 처리될 때까지 함수의 실행을 일시 중지한다. 이를 통해 비동기 코드를 동기식 코드처럼 작성할 수 있게 된다.

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { id: 1, name: 'John Doe' };
            resolve(data); // 성공적으로 데이터를 반환
        }, 1000);
    });
}

async function getData() {
    try {
        const data = await fetchData(); // 프로미스가 처리될 때까지 대기
        console.log('Data received:', data);
    } catch (error) {
        console.error('Error:', error);
    }
}

getData();

 

동기식처럼 처리되는 코드처럼 보이면서도 async, await 키워드를 사용해서 비동기적으로 동작하게 한다.

 

콜백 지옥 (Callback Hell)

콜백 지옥은 자바스크립트에서 비동기 작업을 중첩된 콜백 함수로 처리할 때 발생하는 문제로, 코드의 가독성과 유지보수성이 크게 떨어지는 현상을 말한다.

function authenticateUser(username, password, callback) {
    setTimeout(() => {
        console.log('User authenticated');
        callback(null, { userId: 1, username: username });
    }, 1000);
}

function fetchUserData(userId, callback) {
    setTimeout(() => {
        console.log('User data fetched');
        callback(null, { userId: userId, data: 'Some user data' });
    }, 1000);
}

function processData(data, callback) {
    setTimeout(() => {
        console.log('Data processed');
        callback(null, { processedData: 'Processed data' });
    }, 1000);
}

authenticateUser('user1', 'password123', (authError, authData) => {
    if (authError) {
        console.error('Authentication error:', authError);
        return;
    }
    fetchUserData(authData.userId, (fetchError, userData) => {
        if (fetchError) {
            console.error('Fetch error:', fetchError);
            return;
        }
        processData(userData.data, (processError, processedData) => {
            if (processError) {
                console.error('Processing error:', processError);
                return;
            }
            console.log('All tasks completed successfully:', processedData);
        });
    });
});

 

'authenticateUser' 함수는 사용자를 인증하고 결과를 콜백 함수에 전달한다.

인증이 성공하면 'fetchUserData' 함수가 호출되어 사용자 데이터를 가져온다. 

사용자 데이터가 성공적으로 가져오면, 'processData' 함수가 호출되어 데이터를 처리한다.

 

위 코드는 각 단계별로 성공 여부를 대기하고 성공 시 다음 단계로 넘어가는 구조이다. 이러한 구조를 중첩된 콜백 함수라고 하며 코드가 길어지고 복잡해져 가독성이 떨어진다는 것이 확인된다. 가독성이 떨어지면 유지보수와 에러 처리에도 어려움이 발생할 수밖에 없다.

 

이를 예방하는 방법으로는 위에서 서술된 프로미스 사용, async, await 키워드를 사용하는 방법들이 있고 그 밖에도 몇 가지 방법들이 존재한다.

 

이름이 있는 함수로 콜백 분리

익명 함수 대신 이름이 있는 함수를 사용하여 콜백을 분리하면 코드의 가독성과 재사용성이 향상된다.

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { id: 1, name: 'John Doe' };
            resolve(data);
        }, 1000);
    });
}

fetchData()
    .then(data => {
        console.log('Data received:', data);
        return fetchData(); // 다음 비동기 작업
    })
    .then(data => {
        console.log('Next data received:', data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

 

모듈화 및 함수 분리

비동기 작업을 여러 작은 함수로 나누고 모듈화 하면 코드가 더 관리하기 쉬워진다.

function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { id: 1, name: 'John Doe' };
            resolve(data);
        }, 1000);
    });
}

async function handleFirstData() {
    try {
        const data = await fetchData();
        console.log('Data received:', data);
        return data;
    } catch (error) {
        console.error('Error in handleFirstData:', error);
    }
}

async function handleSecondData() {
    try {
        const data = await fetchData();
        console.log('Next data received:', data);
        return data;
    } catch (error) {
        console.error('Error in handleSecondData:', error);
    }
}

async function processAllData() {
    await handleFirstData();
    await handleSecondData();
}

processAllData();

 

비동기 제어 라이브러리 사용

비동기 제어 흐름을 관리하기 위해 'async.js'와 같은 비동기 작업을 관리하는 데 유용한 유틸리티를 제공하는 라이브러리를 사용할 수 있다.

 

async.js 등 라이브러리를 사용하기 위해서는 설치가 필요하다.

<script src="https://cdnjs.cloudflare.com/ajax/libs/async/3.2.0/async.min.js"></script>

 

node.js 환경에서는 npm install async를 사용하여 설치할 수 있다.

npm install async

 

async.js 사용법

시퀀스 작업 처리

'async.series'를 사용하여 비동기 작업을 순차적으로 처리할 수 있다.

const async = require('async');

function fetchData(callback) {
    setTimeout(() => {
        console.log('Data fetched');
        callback(null, { id: 1, name: 'John Doe' });
    }, 1000);
}

function processData(data, callback) {
    setTimeout(() => {
        console.log('Data processed:', data);
        callback(null, { processedData: true });
    }, 1000);
}

async.series([
    function(callback) {
        fetchData(callback);
    },
    function(callback) {
        fetchData((err, data) => {
            if (err) return callback(err);
            processData(data, callback);
        });
    }
], function(err, results) {
    if (err) {
        console.error('Error:', err);
    } else {
        console.log('All tasks completed:', results);
    }
});

 

병렬 작업 처리

'async.parallel'을 사용하여 비동기 작업을 병렬로 처리할 수 있다.

const async = require('async');

function fetchData1(callback) {
    setTimeout(() => {
        console.log('Data1 fetched');
        callback(null, { id: 1, name: 'John Doe' });
    }, 1000);
}

function fetchData2(callback) {
    setTimeout(() => {
        console.log('Data2 fetched');
        callback(null, { id: 2, name: 'Jane Doe' });
    }, 500);
}

async.parallel([
    function(callback) {
        fetchData1(callback);
    },
    function(callback) {
        fetchData2(callback);
    }
], function(err, results) {
    if (err) {
        console.error('Error:', err);
    } else {
        console.log('All tasks completed in parallel:', results);
    }
});

 

각 작업 처리

'async.each'를 사용하여 배열의 각 요소에 대해 비동기 작업을 수행할 수 있다.

const async = require('async');

const items = [1, 2, 3, 4, 5];

function processItem(item, callback) {
    setTimeout(() => {
        console.log('Processed item:', item);
        callback(null, item);
    }, 1000);
}

async.each(items, processItem, function(err) {
    if (err) {
        console.error('Error:', err);
    } else {
        console.log('All items processed');
    }
});

 

728x90
반응형

ES6+

ECMAScript 6부터의 버전에서는 자바스크립트 언어에 여러 유용한 기능들이 추가되었다. 

 

이 중에서도 특히 중요한 템플릿 리터럴, 디스트럭처링 할당, 스프레드 연산자와 나머지 매개변수, 모듈화에 대해서 정리한다.

 

템플릿 리터럴 (Template Literals)

템플릿 리터럴은 백틱을 사용하여 문자열을 작성하며, 문자열 내에 표현식을 포함할 수 있는 기능을 제공한다.

 

기본 사용법

const name = 'Bak';
const greeting = `Hello, ${name}!`; // 표현식 ${}을 사용
console.log(greeting); // "Hello, Bak!"

 

${} 표현식을 사용해서 문자열 내에서 직접 변수의 값에 바로 접근할 수 있다.

 

여러 줄 문자열

템플릿 리터럴을 사용하면 여러 줄에 걸쳐 문자열을 작성할 수 있다.

const multiline = `This is
a string
that spans multiple lines.`;
console.log(multiline);

 

ES6 이전에는 문자열을 쓸 때 큰따옴표를 사용해야 했으며 백틱을 사용하게 되면 구문 오류(Syntax Error)가 발생한다.

 

그리고 이전의 자바스크립트는 한 줄로 작성된 문자열을 인식하기 때문에 여러 줄에 걸쳐 문자열을 작성하기 위해서는 줄 끝에 백슬래시를 사용하여 줄 바꿈을 나타내야 했다.

 

var multiLineString = "This is the first line \
This is the second line \
This is the third line";
console.log(multiLineString);
// "This is the first line This is the second line This is the third line"

// 또는 

var multiLineString = "This is the first line\n" +
                      "This is the second line\n" +
                      "This is the third line";
console.log(multiLineString);
// This is the first line
// This is the second line
// This is the third line

 

이런 방법들은 코드의 가독성을 떨어뜨릴 여지가 충분했다.

 

디스트럭처링 할당 (Destructuring Assignment)

디스트럭처링 할당은 배열이나 객체의 값을 개별 변수로 쉽게 추출할 수 있게 해주는 문법이다. 이는 코드를 더 간결하고 가독성 좋게 만들며, 특히 복잡한 데이터 구조를 다룰 때 유용하다. 

 

const numbers = [1, 2, 3, 4];
const [first, second, ...rest] = numbers; // 배열의 첫 두 요소를 추출하고 나머지는 rest에 할당
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4]

 

객체 디스트럭처링

const person = {
    name: 'Bob',
    age: 30,
    job: 'developer'
};
const { name, age, job } = person; // 객체의 프로퍼티를 개별 변수로 추출
console.log(name); // 'Bob'
console.log(age); // 30
console.log(job); // 'developer'

 

중첩된 구조 디스트럭처링

const person = {
    name: 'Charlie',
    address: {
        city: 'New York',
        zip: '10001'
    }
};
const { name, address: { city, zip } } = person; // 중첩된 구조에서 프로퍼티 추출
console.log(name); // 'Charlie'
console.log(city); // 'New York'
console.log(zip); // '10001'

 

함수 파라미터에서 디스트럭처링

함수 파라미터에서 디스트럭처링을 사용하면 코드가 더 직관적이고 명확해진다.

function displayPerson({ name, age }) {
  console.log(`Name: ${name}, Age: ${age}`);
}

const person = { name: 'Bak', age: 25 };
displayPerson(person); // Name: Bak, Age: 25

 

디스트럭처링을 잘 활용하면 코드의 유지보수성을 높이고, 가독성을 개선하며, 실수를 줄이는 데 도움이 된다. 

 

스프레드 연산자 (Spread Operator)

스프레드 연산자('...')는 세 개의 점으로 표현된다.

 

배열이나 객체를 펼치거나, 함수의 나머지 매개변수로 사용할 수 있어 배열이나 객체를 보다 간결하고 직관적으로 다룰 수 있게 해 준다.

 

배열에서 스프레드 연산자

// 배열 복사
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr2); // [1, 2, 3]

// 배열 결합
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // 배열을 펼쳐서 결합
console.log(combined); // [1, 2, 3, 4, 5, 6]

 

객체에서의 스프레드 연산자

// 객체 복사
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1 };
console.log(obj2); // { a: 1, b: 2 }

// 객체 결합
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const combinedObj = { ...obj1, ...obj2 }; // 객체를 펼쳐서 결합
console.log(combinedObj); // { a: 1, b: 2, c: 3, d: 4 }

 

배열이나 객체를 단순히 변수에 대입하는 것과 스프레드 연산자를 사용하여 복사하는 것은 중요한 차이가 있다.

변수 대입과 참조

자바스크립트에서 배열이나 객체를 변수에 대입할 때 실제로는 해당 배열이나 객체의 참조가 복사된다. 이는 두 변수가 같은 배열이나 객체를 참조하게 된다는 의미로 한 변수를 통해 배열이나 객체를 변경하면, 다른 변수에도 그 변경 사항이 반영된다.

 

 

나머지 매개변수 (rest parameters)

함수에서 가변 인자를 처리할 수 있도록 도와주는 기능이다. 이 기능은 보다 인자들을 유연하게 다룰 수 있게 된다.

function sum(...args) { // 나머지 매개변수로 모든 인수를 배열로 받음
    return args.reduce((total, current) => total + current, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7)); // 22

 

나머지 매개변수를 사용하면 함수가 전달받는 인자의 수에 제한이 없어 특히 가변 인자를 처리해야 하는 상황에서 유용하다.

function concatenate(separator, ...strings) {
  return strings.join(separator);
}

console.log(concatenate(', ', 'Hello', 'World', 'JavaScript')); // "Hello, World, JavaScript"
console.log(concatenate(' - ', 'Learn', 'Code', 'Enjoy')); // "Learn - Code - Enjoy"

 

배열 메서드를 직접 사용할 수 있어 가변 인자를 처리하는 로직이 명확해져 가독성이 높아지고 가변 인자를 처리하기 위한 별도의 코드를 작성할 필요가 없어 중복 코드를 줄일 수 있다.

 

arguments 

전통적으로 자바스크립트에서는 arguments 객체를 사용하여 함수의 모든 인자를 접근할 수 있다. 하지만 arguments 객체는 배열이 아니기 때문에 배열 메서드를 직접 사용할 수 없어 추가적인 변환 작업을 필요로 한다.

function oldSum() {
  const args = Array.prototype.slice.call(arguments);
  return args.reduce((total, num) => total + num, 0);
}

console.log(oldSum(1, 2, 3)); // 6

 

반면 나머지 매개변수는 배열로 제공되기 때문에 배열 메서드를 바로 사용할 수 있어 더 직관적이고 간편하다.

 

모듈화 (Modules)

모듈화를 통해 코드를 여러 파일로 나눠서 관리할 수 있어 코드의 재사용성과 유지보수성을 높여준다.

 

모듈 내보내기/가져오기 (Export/Import)

모듈에서 함수를 내보내는 두 가지 방법이 있다. 

 

name exports

모듈에서 여러 개의 변수를 내보낼 수 있으며, 각 변수를 특정 이름으로 내보낸다. 가져올 때는 내보낸 이름을 사용하여 모듈을 가져와야 한다.

// math.js
export const pi = 3.14;
export function add(x, y) {
  return x + y;
}
export class Calculator {
  subtract(x, y) {
    return x - y;
  }
}

 

import

// main.js
import { pi, add, Calculator } from './math.js';

console.log(pi); // 3.14
console.log(add(2, 3)); // 5
const calc = new Calculator();
console.log(calc.subtract(5, 3)); // 2

 

name export의 경우 같은 이름을 가진 변수가 이미 사용 중이라면 이름 충돌이 발생하기도 한다. 이를 해결하기 위해서 as 키워드를 사용하여 별칭을 붙일 수 있다.

import { add as addNumbers } from './math.js';

 

default exports

모듈에서 하나의 기본 값을 내보낸다. 모듈당 하나의 default export만 가질 수 있으며 이름 없이 내보낼 수 있다.

// utils.js
export default function greet(name) {
  return `Hello, ${name}!`;
}

 

import

// main.js
import greet from './utils.js';

console.log(greet('Bak')); // Hello, Bak!

 

혼합 사용

하나의 모듈에서 named exports와 default export를 동시에 사용할 수 있다.

// module.js
export const pi = 3.14;
export function add(x, y) {
  return x + y;
}
export default function subtract(x, y) {
  return x - y;
}

// main.js
import subtract, { pi, add } from './module.js';

console.log(pi); // 3.14
console.log(add(2, 3)); // 5
console.log(subtract(5, 3)); // 2
728x90
반응형

DOM

DOM은 HTML 문서의 구조화된 표현이다. 웹 페이지의 각 요소는 객체로 표현되며, 이 객체들은 트리 구조를 형성한다. DOM을 통해 자바스크립트는 문서의 구조, 스타일, 콘텐츠를 동적으로 변경할 수 있다.

 

요소 선택

DOM 요소를 조작하기 위해서는 먼저 해당 요소를 선택해야 한다.

자주 사용되는 두 가지 방법으로 getElementById와 querySelector가 있다.

 

getElementById

getElementById 메서드는 문서에서 특정 ID를 가진 요소를 선택한다. ID는 문서 내에서 고유해야 한다.

 

const element = document.getElementById('myElement');
console.log(element); // 해당 ID를 가진 요소를 출력

 

querySelector

querySelector 메서드는 제공된 CSS 선택자에 매칭되는 첫 번째 요소를 반환하며 더 유연하게 요소를 선택할 수 있다.

const element = document.querySelector('.myClass');
console.log(element); // 해당 클래스를 가진 첫 번째 요소를 출력

const anotherElement = document.querySelector('#myElement');
console.log(anotherElement); // 해당 ID를 가진 요소를 출력

 

요소 조작

선택한 요소의 콘텐츠와 스타일을 변경할 수 있다. 

getElementById나 querySelector는 요소를 선택하는 방법에만 차이가 있을 뿐 선택한 요소는 동일한 프로퍼티를 통해 조작할 수 있다.

 

innerHTML 

innerHTML 프로퍼티는 요소의 HTML 콘텐츠를 설정하거나 가져온다. 요소 내부의 HTML 구조를 동적으로 변경할 수 있다.

const element = document.getElementById('myElement');
element.innerHTML = '<p>새로운 콘텐츠</p>';

 

style

style 프로퍼티는 인라인 스타일을 설정한다. 특정 요소의 CSS 스타일을 직접 변경할 때 유용하다.

const element = document.getElementById('myElement');
element.innerHTML = '<p>새로운 콘텐츠</p>';

 

classList

classList 프로퍼티는 요소의 클래스 목록을 조작하는 메서드를 제공한다. 이를 통해 클래스를 추가, 제거, 토글 할 수 있다.

const element = document.getElementById('myElement');
element.classList.add('newClass');
element.classList.remove('oldClass');
element.classList.toggle('activeClass');

 

이벤트 처리

DOM 요소에 이벤트를 처리하기 위해서는 addEventListener 메서드를 사용한다. 

const button = document.getElementById('myButton');
button.addEventListener('click', function() {
    alert('버튼이 클릭되었습니다!');
});

 

HTML 예제

간단한 HTML을 작성하고 요소를 가져와서 조작해 본다.

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Element Selection Example</title>
    <style>
        .highlight {
            background-color: yellow;
            color: red;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div id="content">
        <h1 id="header">Hello!</h1>
        <p class="paragraph">This is a paragraph.</p>
    </div>
    <button id="changeContent">Change Content</button>
    <button id="changeStyle">Change Style</button>
    <button id="toggleClass">Toggle Class</button>
    <script src="script.js"></script>
</body>
</html>

 

script.js

// 요소 선택
const header = document.getElementById('header');
const paragraph = document.querySelector('.paragraph'); // 클래스 선택자를 사용
const changeContentButton = document.getElementById('changeContent');
const changeStyleButton = document.getElementById('changeStyle');
const toggleClassButton = document.getElementById('toggleClass');

// 콘텐츠 변경
changeContentButton.addEventListener('click', function() {
    header.innerHTML = 'Content has been changed!';
    paragraph.innerHTML = 'The paragraph content has been changed!';
});

// 스타일 변경
changeStyleButton.addEventListener('click', function() {
    header.style.color = 'blue';
    paragraph.style.backgroundColor = 'lightgray';
    paragraph.style.padding = '10px';
});

// 클래스 토글
toggleClassButton.addEventListener('click', function() {
    paragraph.classList.toggle('highlight');
});

 

페이지 상태

HTML

 

 

Change Content 버튼을 클릭 시

OnClick Change Content Button

 

Change Style 버튼 클릭 시

OnClick Change Style

 

Toggle Class 버튼 클릭 시

Onclick Toggle Class

 

728x90
반응형

'Program Language > JavaScript' 카테고리의 다른 글

JavaScript #15 비동기 자바스크립트  (0) 2024.07.23
JavaScript #14 ES6+ 문법  (4) 2024.07.23
JavaScript #11 함수  (0) 2024.07.23
JavaScript #10 조건문과 반복문  (1) 2024.07.23
JavaScript #9 데이터 타입  (9) 2024.07.22

객체 (Object)

객체는 자바스크립트에서 데이터를 구조화하고 저장하는 방식 중 하나로 키와 값 쌍의 집합으로 구성된다. 이 키-값 쌍을 통해서 다양한 테이터와 기능을 하나의 단위로 묶어 관리할 수 있다.

 

특징

키-값

키는 문자열 또는 심볼이어야 하며 값은 어떠한 데이터 타입도 가능하다. 만약 키에 숫자를 입력할 경우 자동으로 문자로 변환된다.

 

중첩 가능

객체의 값으로 또 다른 객체를 가질 수 있다. 이를 통해 복잡한 데이터 구조를 표현하는 것이 가능하다.

 

동적 속성 추가/제거

객체는 생성된 이후에도 속성을 동적으로 추가하거나 삭제할 수 있다.

 

생성 방법

1. 객체 리터럴

가장 일반적인 객체 생성 방법으로 중괄호를 사용하여 키-값 쌍을 정의한다.

const person = {
    name: 'Bak',
    age: 25,
    greet: function() {
        console.log('Hello, my name is ' + this.name);
    }
};

 

2. 객체 생성자

new Object() 구문을 사용하여 객체를 생성할 수 있다. 이후 점 표기법 또는 대괄호 표기법을 사용하여 속성을 추가한다.

const person = new Object();
person.name = 'Bak';
person.age = 25;
person.greet = function() {
    console.log('Hello, my name is ' + this.name);
};

 

3. 생성자 함수

특정 구조를 가진 객체를 반복해서 생성할 때 유용하다.

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        console.log('Hello, my name is ' + this.name);
    };
}

const alice = new Person('Bak', 25);

 

4. 클래스(ES6 이후)

클래스를 사용하면 객체 지향 프로그래밍의 패턴을 쉽게 구현할 수 있다.

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    greet() {
        console.log('Hello, my name is ' + this.name);
    }
}

const alice = new Person('Alice', 25);

 

객체 사용법 

const game = {
    company: 'Bethesda',
    title: 'Fallout',
    year: 1997
};

// 속성 접근
console.log(game.company); // 'Bethesda'
console.log(game['title']); // 'Fallout'

// 속성 수정
game.year = 2008;
console.log(game.year); // 2008

// 속성 추가
game.series = 'Fallout : New Vegas';
console.log(game.series); // 'Fallout : New Vegas'

// 속성 삭제
delete company.title;
console.log(company.title); // undefined

 

배열 (Array)

배열은 자바스크립트에서 여러 개의 데이터를 순차적으로 저장할 수 있는 자료구조이다. 동일한 타입 또는 서로 다른 타입의 데이터를 모두 저장할 수 있으며 각 데이터는 인덱스로 접근할 수 있다.

 

특징

인덱스 기반

배열의 각 요소는 0부터 시작하는 인덱스를 통해 접근할 수 있다.

 

동적 크기

자바스크립트의 배열은 동적 크기를 가지며, 요소를 추가하거나 제거할 수 있다.

 

다양한 데이터 타입

배열의 요소는 숫자, 문자열, 객체, 다른 배열 등 어떤 데이터 타입도 될 수 있다.

 

배열 생성 방법

1. 배열 리터럴 

가장 일반적인 배열 생성 방법으로 대괄호를 사용하여 배열 요소를 정의한다.

const numbers = [1, 2, 3, 4, 5];
const mixedArray = [1, 'two', {three: 3}, [4, 5]];

 

2. 배열 생성자

new Array() 구문을 사용하여 배열을 생성할 수 있다.

const numbers = new Array(1, 2, 3, 4, 5);
const emptyArray = new Array(10); // 길이가 10인 빈 배열 생성

 

배열 사용법

const fruits = ['apple', 'banana', 'cherry'];

// 요소 접근
console.log(fruits[0]); // 'apple'
console.log(fruits[1]); // 'banana'

// 요소 수정
fruits[1] = 'blueberry';
console.log(fruits[1]); // 'blueberry'

 

인덱스로 배열의 요소에 접근하여 사용할 수 있다.

 

 

배열 메서드

자바스크립트 배열은 다양한 메서드를 통해 요소를 추가, 제거, 탐색, 변형할 수 있다.

 

1. push

push 메서드는 배열의 끝에 하나 이상의 요소를 추가하고 배열의 새로운 길이를 반환한다.

const fruits = ['apple', 'banana'];
let len = fruits.push('orange');
console.log(len); // 3
console.log(fruits); // ['apple', 'banana', 'orange']

.

2. pop

pop 메서드는 배열의 마지막 요소를 제거하고 그 요소를 반환한다.

const fruits = ['apple', 'banana', 'orange'];
const lastFruit = fruits.pop();
console.log(fruits); // ['apple', 'banana']
console.log(lastFruit); // 'orange'

 

push & pop 사용 예제

const fruits = ['apple', 'banana'];

// push: 배열 끝에 요소 추가
fruits.push('cherry');
console.log(fruits); // ['apple', 'banana', 'cherry']

// pop: 배열 끝의 요소 제거
const lastFruit = fruits.pop();
console.log(fruits); // ['apple', 'banana']
console.log(lastFruit); // 'cherry'

 

3. map

map 메서드는 배열 내의 모든 요소에 대해 제공된 함수를 호출한 결과로 새로운 배열을 생성한다.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(num => num * num);
console.log(squared); // [1, 4, 9, 16, 25]

 

4. filter

filter 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]

 

5. reduce

reduce 메서드는 배열의 각 요소에 대해 주어진 reducer 함수를 실행하여 단일 값을 반환한다.

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15

 

reduce는 배열의 각 요소를 순회하며, 콜백 함수의 결과를 누산 하여 단일 값을 생성한다. 여기서 

(acc, curr) => acc + curr는 콜백함수로 두 개의 주요 인수를 받는다.

 

acc : 이전 콜백에서 반환된 값으로 이전 인덱스까지 누산 된 값

curr : 현재 순회 중인 인덱스의 요소

 

(콜백함수), 0 : 0이 초기값으로 이 값을 시작으로 요소의 값들이 누산 되기 시작한다.

 

공식 문법은 다음과 같다.

arr.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)

 

실제 필요한 인수들이 다양한 방식으로 표기가 가능한데 그 이유는 자바스크립트의 함수 인수 처리 방식 때문이다.

 

자바스크립트에서는 함수가 호출될 때 정의된 인수보다 더 많은 인수가 전달되면 무식하고, 더 적은 인수가 전달되면 undefined로 처리한다.

 

따라서 reduce 메서드에서 필요한 인수만이 알아서 사용된다.

 

따라서 생략형 콜백에서는 첫 번째와 두 번째 인수만 사용하며 두 값을 합한 결과만 리턴하기로 한다.

 

이 과정이 반복되면서 전체 요소의 합산이 되는 것이다.

 

모든 인수를 적용해서 호출하면 다음과 같다.

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((accumulator, currentValue, currentIndex, array) => {
    console.log('Accumulator:', accumulator);
    console.log('Current Value:', currentValue);
    console.log('Current Index:', currentIndex);
    console.log('Array:', array);
    return accumulator + currentValue;
}, 0);

console.log('Sum:', sum); // Sum: 15

 

인수 (accumulator, currentValue, currentIndex, array) => {콜백 함수} : 요소의 누산 값을 반환

auccumulator : 누산값

currentVlaue : 현재 요소값

currnetIndex : 현재 인덱스

array : 참조 배열

 

 

 

728x90
반응형

+ Recent posts