FrontEnd Develop/JavaScript DeepDive

JS THEME #5. 기본 문법 (하) + 함수의 특별성과 this 부연 설명

Frisbeen 2025. 2. 1. 18:49

표현식 → 하나의 값!

표현식(Expression)은 하나의 값으로 평가(Evaluation)된다.

값(리터럴), 변수, 객체의 프로퍼티, 배열의 요소, 함수 호출, 메소드 호출, 피연산자와 연산자의 조합은 모두 표현식이며 하나의 값으로 평가(Evaluation)된다.

표현식은 결국 하나의 값이 되기 때문에 다른 표현식의 일부가 되어 조금 더 복잡한 표현식을 구성할 수도 있다.

아래의 예에서 5 * 10은 50으로 평가(연산)된다.

// 표현식
5             // 5
5 * 10        // 50
5 * 10 > 10   // true
(5 * 10 > 10) && (5 * 10 < 100)  // true

THEME #4의 문과 사뭇 다른데요

자연어에서 문(Statement)이 마침표로 끝나는 하나의 완전한 문장(Sentence)이라고 한다면

표현식은 문을 구성하는 요소이다. 표현식은 그자체로 하나의 문이 될 수도 있다.

→ 문 안에 표현식이 있는 것. 문 ≥ 표현식

할당문 vs 선언문

// 선언문(Declaration statement)
var x = 5 * 10; // 표현식 x = 5 * 10를 포함하는 문이다.
// 할당문(Assignment statement)
x = 100; // 이 자체가 표현식이지만 완전한 문이기도 하다.

어케 구분함

표현식과 문은 매우 유사하여 구별이 어려울 수 있다.

표현식은 평가되어 값을 만들지만 그 이상의 행위는 할 수 없다.

문은 var, function과 같은 선언 키워드를 사용하여 변수나 함수를 생성하기도 하고 if, for, while 문과 같은 제어문을 생성하여 프로그램의 흐름을 제어하기도 한다.

표현식을 통해 평가한 값을 통해 실제로 컴퓨터에게 명령을 하여 무언가를 하는 것은 문이다.

그 문들을 포함한 함수

함수란 어떤 작업을 수행하기 위해 필요한 문(statement)들의 집합을 정의한 코드 블록이다. 함수는 이름과 매개변수를 갖으며 필요한 때에 호출하여 코드 블록에 담긴 문들을 일괄적으로 실행할 수 있다.

// 함수의 정의(함수 선언문)
function square(number) {
  return number * number;
}

// 함수의 정의(함수 선언문)
function square(number) {
  return number * number;
}

// 함수의 호출
square(2); // 4

동일한 작업을 반복적으로 수행해야 한다면 (동일한 구문을 계속해서 중복해서 작성하는 것이 아니라) 미리 정의된 함수를 재사용하는 것이 효율적이다. 이러한 특성은 코드의 재사용이라는 측면에서 매우 유용하다.

객체

자바스크립트는 객체(object) 기반의 스크립트 언어이며 자바스크립트를 이루고 있는 거의 “모든 것”이 객체이다.

원시 타입(Primitives)을 제외한 나머지 값들(함수, 배열, 정규표현식 등)은 모두 객체이다.

자바스크립트 객체는 키(이름)와 값으로 구성된 프로퍼티(property)의 집합이다.

프로퍼티의 값으로 자바스크립트에서 사용할 수 있는 모든 값을 사용할 수 있다.

함수는 특별한 객체(일급객체) 값 또는 속성값으로 취급이 가능하다.

자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다.

따라서 프로퍼티 값으로 함수를 사용할 수도 있으며 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메소드라 부른다.

var person = {
  name: 'Lee',
  gender: 'male',
  sayHello: function () {
    console.log('Hi! My name is ' + this.name);
  }
};

console.log(typeof person); // object
console.log(person); // { name: 'Lee', gender: 'male', sayHello: [Function: sayHello] }

person.sayHello(); // Hi! My name is Lee

왜 굳이 구분하죠? → this의 동작 차이

const person = {
  name: "Alice",
  sayHi: function () {
    console.log("Hi, I am " + this.name);
  },
};

const greet = person.sayHi;
greet(); // ❌ "Hi, I am undefined" (this가 다름!)

메서드는 this가 해당 객체를 가리키지만, 일반 함수로 호출하면 this undefined 또는 window를 가리킴

✔ 따라서 메서드를 일반 함수처럼 사용하면 this가 원래 객체를 잃어버릴 수 있음.

아마 저 두 줄로는 이해가 안될거임

🚀 왜 greet(); 실행 시 this.name이 undefined가 되는가?

✅ 1. const greet = person.sayHi;가 의미하는 것

✔ 이 코드는 person.sayHi 메서드를 greet 변수에 할당한 것입니다. (이건 명확할거임)

✔ 그런데 중요한 점은, 함수를 변수에 할당할 때는 this 바인딩이 유지되지 않는다! (여기가 포인트)

✔ 즉, greet()을 실행할 때 더 이상 person 객체의 메서드가 아니라, 일반 함수가 되어버린다

따라서 객체의 속성값인 메서드를 일반 함수 처럼 끌어와서 쓰면 의도치 않은 결과가 나옴

this는 원래 객체 내부에서 객체 그 자체를 가리켰는데 , 일반 함수로 끌어온 순간 객체의 메서드로 취급당하는것이 아닌 일반함수로 취급

→ 그에따라 this가 먹히지 않겠죠

해결법은 없나요

bind(), call(),apply() 이런게 있는데 안쓸거잖아

화살표함수 활용해서 this 변하지 않게하는 방법이 있는데

그러면 메서드를 쓰는 의미가 없으니 권장하진 않는다.

const person = {
  name: "Alice",
  sayHi: () => {
    console.log("Hi, I am " + this.name);
  },
};

person.sayHi(); // ❌ "Hi, I am undefined"

여기의 소 결론은 객체의 속성값으로 함수 즉 메서드를 활용할때 화살표 함수는 쓰지마쇼

배열

배열(array)은 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다. 자바스크립트의 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.

그중 Array.isArray()는 매우 유용함

var arr = [1, 2, 3, 4, 5];

console.log(arr[1]); // 2