Lined Notebook

자바스크립트 필수개념들 정리 (함수, 객체, 비동기, 프로토타입 등)

by yjym33

자바스크립트 함수

 

1. 함수의 정의

 

자바스크립트의 함수는 다음과 같이 정의 된다.

function functionName(parameters) {
    // 함수 내용
    return result; // (선택적) 반환 값
}

function: 함수 키워드로 함수를 정의한다.

functionName: 함수의 이름으로, 고유한 이름을 부여할 수 있다.

parameters: (선택적) 함수에 전달되는 매개변수(인자) 목록으로, 함수 내부에서 사용할 수 있습니다.

{}: 중괄호 내부에 함수의 코드 블록을 작성합니다.

return: (선택적) 함수가 값을 반환할 때 사용하는 키워드입니다.

 

2. 함수의 호출

 

함수는 다음과 같이 호출된다.

result = functionName(arguments);

functionName: 호출하려는 함수의 이름.

arguments: 함수에 전달하는 값으로, 매개변수에 매핑됩니다.

result: 함수가 반환하는 값 (return 문을 사용한 경우에만 반환됨).

 

3. 함수의 매개변수와 반환 값

 

함수는 매개변수를 가질 수 있으며, 이를 활용하여 함수 내부에서 작업을 수행할 때 필요한 데이터를 전달받을 수 있습니다. 함수는 값을 반환하여 결과를 호출하는 곳으로 반환할 수도 있습니다.

function add(a, b) {
    return a + b;
}

const sum = add(3, 5); // sum에는 8이 저장됩니다.

 

4. 익명 함수 (Anonymous Function)

 

익명 함수는 이름이 없는 함수로, 주로 콜백 함수 또는 함수 표현식으로 사용됩니다.

const add = function(a, b) {
    return a + b;
};

const sum = add(3, 5); // sum에는 8이 저장됩니다.

 

5. 화살표 함수 (Arrow Function)

 

화살표 함수는 함수 표현식을 간결하게 작성하는 방법입니다.

const add = (a, b) => a + b;

const sum = add(3, 5); // sum에는 8이 저장됩니다.

 

6. 스코프(Scope)

 

함수 내부에서 정의된 변수는 함수 내부에서만 유효한 스코프(영역)를 가집니다. 이러한 스코프를 활용하여 변수의 범위를 관리할 수 있습니다.

function exampleScope() {
    const x = 10; // 함수 내부 스코프에 있는 변수 x
    console.log(x); // 10 출력
}

console.log(x); // 에러: x는 정의되지 않음

 

7. 클로저(Closure)

 

클로저는 함수와 그 함수가 선언된 렉시컬 스코프 사이의 관계를 나타내며, 함수가 자신의 렉시컬 스코프 외부에서도 변수에 접근할 수 있게 합니다.

function outer() {
    const x = 10;
    function inner() {
        console.log(x); // outer 함수의 x에 접근
    }
    return inner;
}

const closureFunc = outer();
closureFunc(); // 10 출력

 

8.재귀 함수(Recursive Function)

 

재귀 함수는 함수 내부에서 자기 자신을 호출하는 함수입니다. 이를 활용하여 반복적인 작업을 처리할 수 있습니다.

function factorial(n) {
    if (n === 0) {
        return 1;
    }
    return n * factorial(n - 1);
}

const result = factorial(5); // 5! = 120

 

9. 함수의 범위(Function Scope) vs 블록 범위 (Block Scope)

 

ES6부터는 블록 범위를 가지는 **let**과 const 변수가 도입되었으며, 이를 활용하여 블록 내부에서 변수를 제한적으로 사용할 수 있습니다. 함수 범위 변수는 함수 내부에서만 유효하지만, 블록 범위 변수는 블록 내부에서만 유효합니다.

if (true) {
    var functionScopedVar = "Function Scoped"; // 함수 범위 변수
    let blockScopedVar = "Block Scoped"; // 블록 범위 변수
}

console.log(functionScopedVar); // "Function Scoped"
console.log(blockScopedVar); // 에러: blockScopedVar는 정의되지 않음

 

 

자바스크립트 객체

 

1. 객체의 정의

 

자바스크립트에서 객체는 데이터와 동작을 하나로 묶은 복합 데이터 타입입니다. 객체는 {} 중괄호를 사용하여 정의하며, "키(key)"와 "값(value)"의 쌍으로 구성됩니다. 이러한 키와 값의 쌍을 "속성(Property)"이라고도 부릅니다.

const person = {
    name: "John",
    age: 30,
    gender: "male"
};

 

2. 객체 생성

  • 객체를 생성하는 방법은 다양합니다. 가장 일반적인 방법은 객체 리터럴을 사용하는 것입니다.
const person = {
  name: 'John',
  age: 30,
};

 

3. 프로퍼티 (속성)

  • 객체 내의 프로퍼티는 이름(키)과 값으로 구성됩니다.
    • 키 (Key): 객체의 속성 이름을 나타냅니다. 키는 문자열 또는 심볼(symbol)이어야 합니다.
    • 값 (Value): 키와 연결된 데이터 또는 함수를 나타냅니다. 값은 어떤 데이터 타입이든 될 수 있습니다
  • 프로퍼티 이름은 문자열 또는 심볼이 될 수 있으며, 값은 어떤 데이터 타입이든 포함할 수 있습니다.
const person = {
  name: 'Alice',
  age: 25,
  isStudent: true,
};

 

4. 메서드

  • 객체 내부에 함수를 포함하는 프로퍼티를 메서드라고 합니다.
  • 메서드는 객체의 동작을 정의하고 실행할 수 있도록 합니다
const calculator = {
  add: function (a, b) {
    return a + b;
  },
  subtract: function (a, b) {
    return a - b;
  },
};

const sum = calculator.add(5, 3); // 결과: 8
const difference = calculator.subtract(10, 4); // 결과: 6

 

5. 객체 접근

  • 객체의 프로퍼티와 메서드에 접근하기 위해 점 표기법 또는 대괄호 표기법을 사용합니다.
const person = {
  name: 'Bob',
  age: 28,
};

console.log(person.name); // 점 표기법으로 프로퍼티에 접근
console.log(person['age']); // 대괄호 표기법으로 프로퍼티에 접근

 

비동기라는 개념 - 이벤트 드리븐 프로그래밍

(콜백, 프로미스, async/await)

 

1. 비동기 프로그래밍이란?

 

자바스크립트는 기본적으로 단일 스레드로 동작하며, 한 번에 하나의 작업만 처리할 수 있습니다.

하지만 웹 애플리케이션에서는 여러 작업을 동시에 처리해야 하는 경우가 많아 비동기 프로그래밍이 필요합니다.

비동기 프로그래밍은 작업이 완료될 때까지 다른 작업을 중단하지 않고 진행하는 방식을 말합니다

 

2. 이벤트 드리븐 프로그래밍 (Event-Driven Programming)

 

이벤트 드리븐 프로그래밍은 주로 웹 애플리케이션에서 사용되며, 어떤 이벤트(예: 클릭, 네트워크 요청 완료, 타이머 등)가 발생할 때마다 관련 작업을 처리하는 프로그래밍 패턴입니다.

이 패턴을 구현하기 위해 콜백 함수, 프로미스, 그리고 async/await을 사용할 수 있습니다.

 

2.1 콜백 함수(Callback Functions)

 

콜백 함수는 이벤트 드리븐 프로그래밍에서 가장 기본적으로 사용되는 비동기 처리 방식입니다. 이벤트가 발생하면 특정 함수(콜백 함수)가 호출됩니다.

// 콜백 함수를 사용한 이벤트 드리븐 프로그래밍 예제
function onClick(event) {
  console.log('버튼이 클릭되었습니다.');
}

document.getElementById('myButton').addEventListener('click', onClick);

 

2.2 프로미스 (Promises)

 

프로미스는 콜백 지옥(callback hell)을 해결하고, 비동기 작업을 더 간결하게 관리할 수 있도록 도와주는 객체입니다. 프로미스는 성공 또는 실패 상태를 반환합니다.

// 프로미스를 사용한 이벤트 드리븐 프로그래밍 예제
function fetchData() {
  return new Promise((resolve, reject) => {
    // 비동기 작업 수행
    setTimeout(() => {
      const data = '데이터가 도착했습니다.';
      resolve(data); // 성공 상태로 전환
    }, 1000);
  });
}

fetchData()
  .then(data => {
    console.log(data); // 성공한 경우 실행
  })
  .catch(error => {
    console.error(error); // 실패한 경우 실행
  });

 

2.3 async/await

 

async/await는 프로미스를 더 쉽게 사용할 수 있도록 도와주는 문법입니다. async 함수 내에서 await 키워드를 사용하면 프로미스가 이행될 때까지 기다릴 수 있습니다.

// async/await를 사용한 이벤트 드리븐 프로그래밍 예제
async function fetchData() {
  try {
    const response = await fetch('<https://example.com/api>');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

fetchData();

 

호출스택, 이벤트루프, 실행 컨텍스트 (정확하게 설명하기가 어려움, 지속적으로 찾아보면서 이해해야함)

 

호출 스택 (Call Stack):

  • 호출 스택은 자바스크립트 엔진이 함수 호출을 관리하는 데이터 구조, 이것은 함수 호출의 순서를 추적하고, 어떤 함수가 실행 중인지를 관리하는 역할을 한다.
  • 함수가 호출될 떄마다 해당 함수의 실행 컨텍스트가 호출 스택에 푸시(Push) 된다.
  • 현재 실행 중인 함수가 종료되면 호출 스택에서 해당 실행 컨텍스트가 팝(Pop) 되어 제거된다.
  • 호출 스택은 Last-In, First-Out (LIFO)의 구조를 따른다. 가장 최근에 호출된 함수가 먼저 실행되고, 가장 오래된 함수가 나중에 실행된다.

이벤트 루프 (Event Loop):

  • 자바스크립트는 단일 스레드 기반으로 동작하며, 비동기 작업을 관리하기 위해 이벤트 루프를 사용한다.
  • 이벤트 루프는 호출 스택, 메시지 큐 (Message Queue), 백그라운드 태스크로 구성된다.
  • 호출 스택이 비어있을 때 이벤트 루프는 메시지 큐에서 대기 중인 작업을 호출 스택으로 이동시킨다.
  • 이벤트 루프는 비동기 작업을 효율적으로 처리하며, 브라우저에서는 웹 API (예: setTimeout, XMLHttpRequest)를 사용하여 비동기 작업을 처리한다.

실행 컨텍스트 (Execution Context): (가장 중요한 개념임)

  • 실행 컨텍스트는 코드가 실행될 때 생성되며, 해당 코드의 환경 정보를 포함하는 객체이다.
  • 실행 컨텍스트는 변수, 함수 선언, 스코프 체인, this 등의 정보를 관리한다.
  • 현재 실행 중인 함수 또는 코드 블록의 실행 컨텍스트가 호출 스택의 맨 위에 있다.
  • 실행 컨텍스트는 전역 컨텍스트와 함수 호출마다 새로운 함수 컨텍스트로 생성된다.

이러한 개념들을 조합하여 자바스크립트의 동작 방식을 설명할수 있다.

  1. 코드 실행이 시작하면 전역 컨텍스트가 생성되고 호출 스택의 맨 위에 푸시됩니다.
  2. 함수가 호출되면 해당 함수의 실행 컨텍스트가 호출 스택에 푸시됩니다.
  3. 함수 내부에서 다른 함수 호출이 있으면 새로운 실행 컨텍스트가 스택에 추가됩니다.
  4. 함수가 실행을 완료하면 해당 실행 컨텍스트가 스택에서 팝되고, 이전 실행 컨텍스트로 돌아갑니다.
  5. 비동기 작업 (예: setTimeout)이 예약되면 이벤트 루프를 통해 백그라운드에서 처리됩니다.
  6. 비동기 작업이 완료되면 해당 콜백 함수가 메시지 큐에 추가되고, 호출 스택이 비어있을 때 실행됩니다.

 

코드를 통한 예시 (호출 스택, 이벤트 루프, 실행 컨텍스트)

console.log("Start");

function foo() {
  console.log("Inside foo");
  bar();
  console.log("Inside foo again");
}

function bar() {
  console.log("Inside bar");
}

foo();

console.log("End");
  1. **console.log("Start");**는 전역 컨텍스트에서 실행되고, 호출 스택에 들어가게 됩니다. 즉, 호출 스택에는 "Start" 출력을 처리하는 실행 컨텍스트가 들어갑니다.
  2. foo() 함수가 호출됩니다. 따라서 foo 함수의 실행 컨텍스트가 호출 스택의 맨 위에 푸시됩니다.
    • foo()
  3. 호출 스택:
  4. foo 함수의 내용이 실행되면, **console.log("Inside foo");**이 출력되고, 그 다음에 bar() 함수가 호출됩니다.
    • foo()
    • bar()
  5. 호출 스택:
  6. bar 함수가 호출되면, 해당 함수의 실행 컨텍스트가 호출 스택에 추가되고, **console.log("Inside bar");**가 출력됩니다.
    • foo()
    • bar()
  7. 호출 스택:
  8. bar 함수의 실행이 완료되면 해당 실행 컨텍스트가 호출 스택에서 팝(pop)되고, foo 함수의 나머지 부분을 실행합니다. 따라서 **console.log("Inside foo again");**가 출력됩니다.
    • foo()
  9. 호출 스택:
  10. foo 함수의 실행이 완료되면 해당 실행 컨텍스트가 호출 스택에서 팝되고, 전역 컨텍스트로 돌아갑니다. 그리고 다음 코드인 **console.log("End");**가 실행됩니다.
  11. 호출 스택: (비어있음)
  12. 전역 컨텍스트에서의 실행이 완료되면 프로그램이 종료됩니다.

 

프로토타입 (자바랑 가장 큰 차이점) → 자바스크립트의 Class는 Class가 아님

자바스크립트의 프로토타입(Prototype)은 이 언어의 중요한 개념 중 하나로, 다른 객체 지향 언어와 큰 차이점 중 하나입니다.

 

1. 프로토타입(Prototype)이란?

  • 자바스크립트는 프로토타입 기반 언어로, 객체 지향 언어입니다. 이 말은 자바스크립트에서 객체들은 다른 객체를 기반으로 만들어진다는 것을 의미합니다.
  • 모든 객체는 프로토타입을 가지며, 이 프로토타입은 다른 객체로부터 상속된 속성과 메서드를 포함하고 있습니다.
  • 객체는 프로토타입 체인을 통해 다른 객체의 속성과 메서드에 접근할 수 있습니다.

 

2. 프로토타입 체인 (Prototype Chain)

  • 자바스크립트에서 객체는 프로토타입을 가집니다. 프로토타입은 또 다른 객체이며, 프로토타입 객체 역시 자신의 프로토타입을 가질 수 있습니다. 이러한 관계가 연쇄적으로 이어지는 것을 프로토타입 체인이라고 합니다.
  • 객체에서 어떤 속성 또는 메서드를 찾을 때, 해당 객체에 없으면 프로토타입 체인을 따라 상위 프로토타입 객체에서 검색합니다.

 

3. 자바와의 차이점

 

자바와 자바스크립트는 이름이 비슷하지만 객체 지향 프로그래밍의 구조에서 다르게 동작합니다.

 

3.1 클래스(Class) 와 프로토타입(Prototype) 의 차이

  • 자바는 클래스(Class) 기반 객체 지향 언어로, 객체를 클래스로부터 생성합니다. 클래스는 객체의 설계도이며, 객체는 클래스의 인스턴스입니다.
  • 자바스크립트는 프로토타입 기반 언어로, 객체는 다른 객체로부터 직접 생성됩니다. 클래스의 개념이 없으며, 상속은 프로토타입 체인을 통해 이루어집니다.

 

3.2 상속 방식의 차이

  • 자바에서는 클래스 상속을 사용하여 하위 클래스가 상위 클래스의 속성과 메서드를 상속받습니다.
  • 자바스크립트에서는 프로토타입 체인을 사용하여 하위 객체가 상위 객체의 속성과 메서드를 상속받습니다. 클래스의 개념이 없어도 객체 간 상속이 가능합니다.
// 상위 클래스 (슈퍼 클래스)
class Animal {
    void makeSound() {
        System.out.println("동물이 소리를 낸다.");
    }
}

// 하위 클래스 (서브 클래스)
class Dog extends Animal {
    void makeSound() {
        System.out.println("강아지가 짖습니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = new Dog();

        animal.makeSound(); // "동물이 소리를 낸다." 출력
        dog.makeSound();    // "강아지가 짖습니다." 출력
    }
}
  • 자바에서 클래스 상속은 클래스 간의 명시적인 계층 구조를 형성하고, 상위 클래스의 메서드와 속성을 하위 클래스에서 재사용하거나 재정의할 수 있도록 합니다.
// 자바스크립트에서의 상속 (프로토타입 기반)
const parent = {
  greet: function() {
    console.log('Hello');
  }
};

const child = Object.create(parent);
child.greet(); // 'Hello'
  • 자바스크립트에서는 프로토타입 체인을 사용하여 하위 객체가 상위 객체의 속성과 메서드를 상속받습니다. 클래스의 개념이 없어도 객체 간 상속이 가능합니다.

 

4. Class 문법

 

자바스크립트 ES6부터 class 문법이 도입되었지만, 이는 클래스 기반 언어에서의 클래스와는 다릅니다. 자바스크립트의 **class**는 사실 프로토타입 기반의 문법을 좀 더 명확하게 표현하기 위한 문법적 설탕(syntactical sugar)입니다.

내부적으로는 프로토타입을 사용하며, 클래스 선언문은 생성자 함수와 프로토타입 메서드를 정의하는 것과 동일한 역할을 합니다.

class Person {
  constructor(name) {
    this.name = name;
  }
  
  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const person = new Person('Alice');
person.sayHello(); // 'Hello, my name is Alice'

위 코드는 아래의 프로토타입 기반의 코드와 내부적으로 동일함

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

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('Alice');
person.sayHello(); // "Hello, my name is Alice" 출력

'Development > Javascript' 카테고리의 다른 글

This  (0) 2023.09.20
이벤트  (0) 2023.09.20
클로저  (0) 2023.09.20
실행 컨텍스트  (0) 2021.08.06
프로토타입  (0) 2021.08.04

블로그의 정보

생각보다 실천을

yjym33

활동하기