개발 일기

2024-10-23(this, class, scope)

민ズl 2024. 10. 23. 17:41

this

  • 어떤 특정 객체를 가리키는 값
  • 자바스크립트는 동적으로 결정
    (함수가 호출되는 시점)

this 바인딩 규칙

기본 바인딩 (Default Binding)

  • 일반 함수 호출에서 this는 전역 객체
  • 엄격 모드에서는 undefined
function showThis() {
  console.log(this);
}

showThis(); // 브라우저 환경에서는 window 객체 출력
// strict 모드에서는 undefined

 

암묵적 바인딩 (Implicit Binding)

  • 객체의 메소드 호출에서 this는 해당 객체
const person = {
  name: 'Alice',
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.greet(); // Alice

const obj1 = {
  name: 'obj1',
  sayName() {
    console.log(this.name);
  },
};

const obj2 = {
  name: 'obj2',
  sayName: obj1.sayName,
}

obj2.sayName(); // obj2

 

명시적 바인딩 (Explicit Binding)

  • call, apply, bind 메소드로 this를 명시적으로 설정
  • call : 객체.call(this로 지정할 값)
function greet() {
  console.log(`Hello, my name is ${this.name}`);
}

const user = {
  name: 'Bob'
};

greet.call(user); // "Hello, my name is Bob"
  • apply : 호출할 함수.apply(this로 사용할 객체, [함수에 전달할 인수들])
function greet(greeting) {
    console.log(greeting + ', ' + this.name);
}

const person = { name: 'David' };
greet.apply(person, ['Hello']); // Hello, David
  • bind : 호출할 함수.bind(this로 사용할 객체, [미리 설정할 인수들])
function greet(greeting) {
    console.log(greeting + ', ' + this.name);
}

const person = { name: 'Eva' };
const greetEva = greet.bind(person);
greetEva('Hi'); // Hi, Eva

⭐new 바인딩 (New Binding)

  • 생성자 함수에서 new 키워드를 사용하면, this는 새로 생성되는 객체(인스턴스)
// 생성자 함수 정의
function Car(maker, model) {
    // new 바인딩에 의해 this는 새로운 객체를 가리킴
    this.maker = maker;
    this.model = model;
}

// new 연산자를 사용해 객체 생성
const myCar = new Car('Toyota', 'Camry');

// 생성된 객체의 프로퍼티 접근
console.log(myCar.maker); // "Toyota"
console.log(myCar.model); // "Camry"

화살표 함수에서의 this

  • 상위스코프의 this
const obj = {
    value: 42,
    regularFunction: function() {
        console.log(this.value); // 42
    },
    arrowFunction: () => {
        console.log(this.value); // undefined (전역의 this를 참조)
    }
};

obj.regularFunction(); // 42
obj.arrowFunction();   // undefined

class

  • 객체 지향 프로그래밍의 중요한 개념
  • 객체를 생성하기 위한 템플릿(설계도) 역할

클래스 특징

-  생성자 함수 (Constructor)

  • 클래스의 인스턴스를 초기화하기 위한 특수한 메소드
  • constructor 키워드를 사용

-  메소드

  • 클래스 내부에 정의된 함수
  • 인스턴스 메소드와 정적 메소드로 나뉨

인스턴스 메소드: 클래스의 인스턴스를 통해 호출되는 메소드, 동적 메소드

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 person1 = new Person('Alice', 30);
person1.greet(); // Hello, my name is Alice and I am 30 years old.

 

정적 메소드 (Static Method): 클래스 자체에서 호출되는 메소드, static 키워드를 사용

class MathUtility {
  static add(a, b) {
    return a + b;
  }
}

console.log(MathUtility.add(5, 3)); // 출력: 8

// 내장 정적 메소드들 예시: Date.now(), Math.ceil(1.3) 등

 

상속

- super : 상위 클래스를 참고할때 or 상위 클래스의 constructor를 호출할때 사용

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

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

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // super : 상위 클래스의 constructor을 실행시킴
    this.breed = breed;
  }

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

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

*오버라이딩 : 상위 클래스에서 정의했지만, 하위 클래스에서 재정의


⭐Scope

  • 변수 유효 범위

함수 스코프

function foo() {
  var x = 'local';
  console.log(x); // 'local'
}

foo();
console.log(x); // ReferenceError: x is not defined

 

블록 스코프

함수외엔 다 블록 스코프임

if(5 > 4) {
   var secret = '12345'; // var는 블록 스코프를 무시
} 
secret // '12345'

{
  let y = 'block scoped';
  console.log(y); // block scoped
}
console.log(y); // ReferenceError: y is not defined

 

스코프 체인

변수를 찾을 때 현재 스코프에서 찾고, 없으면 상위 스코프로 이동하여 변수를 찾는 방식

let a = 'global';

function outer() {
  let b = 'outer';
  /* if (true) {
	  let d = 10;
  } */

  function inner() {
    let c = 'inner';
    console.log(a); // global
    console.log(b); // outer
    console.log(c); // inner
    // console.log("d:",d);
  }

  inner();
}

outer();

 

렉시컬환경

  • 함수가 선언된 시점에서 상위 스코프를 결정하는 방식
  • 실행되는 위치가 아닌, 함수가 선언된 위치에 따라 상위 스코프가 결정
// 아래 코드의 출력 결과는?
const y = 5;

function first() {
  const y = 20;
  second();
}

function second() {
  console.log(y);
}

first(); // 5
second(); // 5