자바스크립트/모던 자바스크립트 Deep Dive

함수

막이86 2023. 11. 15. 11:08
728x90

모던 자바스크립트 Deep Dive을 요약한 내용입니다.

12.1 함수란?

  • 함수는 자바스크립트에서 가장 중요한 핵심 개념
  • 자바스크립트의 핵심 개념인 스코프, 실행 컨텍스트, 클로저, 생성자 함수에 의한 객체 갱성, 메서드, this, 프로토타입, 모듈화 등이 모두 함수와 깊은 관련이 있다
  • 함수는 자바스크립트를 정확히 이해하고 사용하기 위해 피해갈 수 없는 핵심 중의 핵심
  • 수학의 함수는 “입력(input)”을 받아 “출력(output)”을 내보내는 일련의 과정을 정의한 것
    • f(x, y) = x + y 라는 함수를 정의하고 이 함수에 입력 2, 5를 전달하면 함수는 정의된 일련의 과정, 즉 x + y를 싫애하여 7을 출력
  • 프로그래밍 언어의 함수도 수학의 함수와 같은 개념
  • 함수 f(x, y) = x + y를 자바스크립트의 함수로 표현
  • // f(x, y) = x + y function add(x, y) { return x + y } add(2, 5) // 7
  • 함수는 일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것
  • 함수 내부로 입력을 전달 받은 변수를 매개 변수, 입력을 인수, 출력을 반환값이라 한다.

12.2 함수를 사용하는 이유

  • 함수는 필요할 때 여러번 호출할 수 있다.
    • 몇 번이든 재사용이 가능
  • 코드의 중복을 억제하고 재사용성을 높이는 함수는 유지보수의 편의성을 높이고 실수를 줄여 코드의 신뢰성을 높이는 효과가 있다.
  • 함수는 객체 타입의 값이다.
    • 이름(식별자)를 붙일 수 있다.
    • 적절한 함수 이름은 함수의 내부 코드를 이해하지 않고도 함수의 역활을 파악할 수 있게 돕는다.(코드 가독성 향상)

12.3 함수 리터럴

  • 자바스크립트의 함수는 객체 타입의 값이다.
    • 함수도 함수 리터럴로 생성할 수 있다.
  • 함수 리터럴은 function 키워드, 함수 이름, 매개 변수 목록, 함수 몸첼 구성된다.
  • var f = function add(x, y) { return x + y }
  • 함수 리터럴의 구성 요소
    • 함수 이름
      • 함수 이름은 식별자다. 따라서 식별자 네이밍 규칙을 준수해야 한다.
      • 함수 이름은 함수 몸체 내애서만 참조할 수 있는 식별자다.
      • 함수 일므은 생략할 수 있다. 이름이 있는 함수를 기명 함수, 이름이 없는 함수를 무명/익명 함수라 한다.
    • 매개변수 목록
      • 0개 이상의 매개변수를 소괄호로 감싸고 쉼표로 구분한다.
      • 각 매개변수에는 함수를 호출할 때 지정한 인수가 순서대로 할당된다.
        • 매개변수 목록은 순서에 의미가 있다.
      • 매개변수는 함수 몸체 내에서 변수와 동일하게 취급된다.
        • 매개변수도 변수와 마찬가지로 식별자 네이밍 규칙을 준수해야 한다.
    • 함수 몸체
      • 함수가 호출되었을 때 일괄적으로 실행될 문들을 하나의 실행 단위로 정의한 코드 블록이다.
      • 함수 몸체는 함수 호출에 의해 실행된다.
  • 함수는 객체지만 일반 객체와는 다르다
    • 일반 객체는 호출할 수 없지만 함수는 호출할 수 있다.
    • 일반 객체에는 없는 함수 객체만의 고유한 프로퍼티를 갖는다.

12.4 함수 정의

  • 함수를 정의하는 방법에는 4가지가 있다.
    • 함수 선언문
    • function add(x, y) { return x + y }
    • 함수 표현식
    • var add = function(x, y) { return x + y }
    • Function 생성자 함수
    • var add = new Function('x', 'y', 'return x + y')
    • 화살표 함수(ES6)
    • var add = (x, y) => x + y
  • 모든 함수 정의 방식은 함수를 정의한다는 면에서는 동일하다.
    • 미묘하지만 중요한 차이가 있다.

<aside> 💡 변수는 ‘선언'한다고 했지만 함수는 ‘정의'한다고 표현했다. 함수 선언문이 편가되면 식별자가 암묵적으로 생성되고 함수 객체가 할단된다. 따라서 ECMAScript 사양에서도 변수에는 선언. 함수에는 정의라고 표현한다.

</aside>

12.4.1 함수 선언문

  • 함수 선언문을 사용해 함수를 정의하는 방식
  • function add(x, y) { return x + y } console.dir(add) // ƒ add(x, y) console.log(add(2, 5)) // 7
  • 함수 리터럴은 함수 이름을 생략할 수 있으나 함수 선언문은 함수 이름을 생략할 수 없다.
  • function (x, y) { return x + y } // Uncaught SyntaxError: Function statements require a function name
  • 함수 선언문은 표현식이 아닌 문이다.
  • 함수 선언문도 표현식이 아닌 문이므로 변수에 할당할 수 없다.
    • 예제를 실행해보면 함수 선언문이 변수에 할당되는 것처럼 보인다.
    var add = function add(x, y) {
    	return x + y
    }
    console.log(add(2, 5))
    
    • 자바스크립트 엔진이 코드의 문맥에 따라 동일한 함수 리터럴을 표현식이 아닌 문인 함수 선언문으로 해석하는 경우와 표현식인 문인 함수 리터럴 표현식으로 해석하는 경우가 있기 때문
    • 함수 선언문은 함수 이름을 생략할 수 없다는 점을 제외하면 함수 리터럴과 형태가 동일하다.
      • 함수 이름이 있는 기명 함수 리터럴은 함수 선언문 또는 함수 리터럴 표현식으로 해석될 가능성이 있다는 의미
  • ??
  • 자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.
  • 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가르키는 식별자로 호출한다.

12.4.2 함수 표현식

  • 함수는 값처럼 변수에 할당할 수 있고 프로퍼티 값이 될 수도 있으며 배열의 요소가 될 수도 있다.
  • 자바스크립트의 함수는 일급 객체이다.
  • 함수 선언문으로 정의한 add 함수를 함수 표현식으로 바꿔서 정의
  • var add = function(x, y) { return x + y } console.log(add(2, 5))
  • 함수 리터럴의 함수 이름은 생략할 수 있다.
    • 이러한 함수를 익명 함수라 한다.
  • 함수를 호출할 때는 함수 이름이 아니라 함수 객체를 가르키는 식별자를 사용해야한다.
    • 함수 이름은 함수 몸체 내부에서만 유효한 식별자이므로 함수 이름으로 함수를 호출할 수 없다.
    var add = function foo(x, y) {
    	return x + y
    }
    
    console.log(add(2, 5))  // 7
    console.log(foo(2, 5))  // Uncaught ReferenceError: foo is not defined
    
  • 함수 선언문은 “표현식이 아닌 문"이고 함수 표현식은 “표현식인 문"이다.
    • 미묘하지만 중요한 차이가 있다.

12.4.3 함수 생성 시점과 함수 호이스팅

console.log(add)         // ƒ add(x, y) 
console.log(sub)         // undefined

console.log(add(2, 5))   // 7
console.log(sub(2, 5))   // Uncaught TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
	return x + y
}

// 함수 표현식
var sub = function (x, y) {
	return x + y
}
  • 함수 선언문으로 정의한 함수는 함수 선언문 이전에 호출 할 수 있다.
  • 함수 표현식으로 정의한 함수는 함수 표현식 이전에 호출 할 수 없다.
  • 함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르기 때문이다.
  • 함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다.
    • 자바스크립트 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당한다.
    • 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 함수 호이스팅이라 한다.
  • var 키워드로 선언된 변수는 undefined로 초기화되고, 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화된다.
    • var 키워드를 사용한 변수 선언문 이전에 변수를 참조하면 변수 호이스팅에 의해 undefined로 평가되지만 함수 선언문으로 정의한 함수를 함수 선언문 이전에 호추랗면 함수 호이스팅에 의해 호출이 가능하다.
  • 변수 할당문의 값은 할당문이 실행되는 시점, 즉 런타임에 평가되므로 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다.
  • 함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생한다.
  • 함수 호이스팅은 함수를 호출하기전에 반드시 함수를 선언해야 한다는 당연한 규칙을 무시한다.
    • 더글라스 크락포드는 함수 선언문 대신 함수 표현식을 사용할 것을 권장

12.4.4 Function생성자 함수

  • 자바스크립트가 기본 제공하는 빌트인 함수인 Function 생성자 함수에 매개변수 목록과 함수 몸체를 문자열로 전달하면서 new 연산자와 함께 호출하면 함수 객체를 생서애서 반환한다.<aside> ⛔ Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src chrome://resources chrome://test chrome://webui-test 'self'".
  • </aside>
  • var add = new Function('x', 'y', 'return x + y') console.log(add(2, 5))
  • Function 생성자 함수로 함수를 생성하는 방식은 일반적이지 않으며 바람직하지도 않다.
  • Function 생성자 함수로 생성한 함수는 클로저를 생성하지 않는 등. 함수 선언문이나 함수 표현식으로 생성한 함수와 다르게 동작한다.
  • var add1 = (function () { var a = 10 return function (x, y) { return x + y + a } }()) console.log(add1(1, 2)) // 13 var add2 = (function () { var a = 10 return new Function('x', 'y', 'return x + y + a') }()) console.log(add2(1, 2)) // Uncaught EvalError: Refused to evaluate a string as JavaScript because

12.4.5 화살표 함수

  • ES6에서 도입된 화살표 함수는 function 키워드 대신 화살표 ⇒를 사용해 좀더 간략한 방법으로 함수를 선언할 수 있다.
  • 화살표 함수는 항상 익명 함수로 정의한다.
  • const add = (x, y) => x + y console.log(add(2, 5)) // 7
  • 화살표 함수는 기존의 함수 선언문 또는 함수 표현식을 완전히 대체하기 위해 디자인된 것은 아니다.
  • 화살표 함수는 기존 함수보다 표현만 간단한 것이 아니라 내부 동작 또한 간략화되어 있다.
    • 화살표 함수는 생성자 함수로 사용할 수 없음
    • 기존 함수와 this 바인딩 방식이 다름
    • prototype 프로퍼티가 없음
    • arguments 객체를 생성하지 않음

12.5 함수 호출

12.5.1 매개변수와 인수

  • 함수를 실행하기 위해 필요한 값을 함수 외부에서 함수 내부로 전달할 필요가 있는 경우, 매개변수를 통해 인수를 전달한다.
  • 인수는 값으로 평가될 수 있는 표현식이여야한다.
  • 인수는 함수를 호출할 때 지정하며, 개수와 타입에 제한이 없다.
  • function add(x, y) { return x + y } var result = add(1, 2)
  • 매개변수는 함수 몸체 내부에서만 참조할 수 있고 함수 몸체 외부에서는 참조할 수 없다.
  • function add(x, y) { console.log(x, y) // 2 5 return x + y } add(2, 5) console.log(x, y) // Uncaught ReferenceError: x is not defined
  • 함수는 매개변수의 개수와 인수의 개수가 일치하는지 체크하지 않는다.
    • 인수가 부족해서 인수가 할당되지 않은 매개변수의 값은 undefined 이다.
    function add(x, y) {
    	return x + y
    }
    
    console.log(add(2))  // NaN
    
  • 매개변수보다 인수가 더 많은 경우 초과된 인수는 무시된다.
    • 초과된 인수는 그냥 버려지는 것은 아님
    • 모든 인수는 암묵적으로 arguments 객체의 프로퍼티로 보관된다.
    function add(x, y) {
    	console.log(arguments)   // Arguments(3) [2, 5, 10, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    	return x + y
    }
    
    console.log(add(2, 5, 10))  // 7
    

12.5.2 인수 확인

  • 자바스크립트의 경우 함수를 정의할 떄 적절한 인수가 전달되었는지 확인할 필요가 있다.
  • function add(x, y) { if (typeof x !== 'number' || typeof y !== 'number') { throw new TypeError('인수는 모든 숫자 값이어야 합니다.') } return x + y } console.log(add(2)) // Uncaught TypeError: 인수는 모든 숫자 값이어야 합니다. console.log(add('a', 'b')) // Uncaught TypeError: 인수는 모든 숫자 값이어야 합니다.
  • 단축 평가를 사용해 매개변수에 기본값을 할당하는 방법도 있다.
  • function add(a, b, c) { a = a || 0 b = b || 0 c = c || 0 return a + b + c } console.log(add(1, 2, 3)) // 6 console.log(add(1, 2)) // 3 console.log(add(1)) // 1 console.log(add()) // 0
  • ES6에서 도입된 매개변수 기본값을 사용하면 함수 내에서 수행하던 인수 체크 및 초기화를 간소화할 수 있다.
  • function add(a = 0, b = 0, c = 0) { return a + b + c } console.log(add(1, 2, 3)) // 6 console.log(add(1, 2)) // 3 console.log(add(1)) // 1 console.log(add()) // 0

12.5.3 매개변수의 최대 개수

  • ECMAScript 사양에서는 매개변수의 최대 개수에 대한 명시적으로 제한하고 있지 않다.
  • 물리적 한계는 있으므로 자바스크립트 엔진마다 매개변수의 최대 개수에 대한 제한이 있겠지만 충분히 많은 매개변수를 지정할 수 있다.
  • 매개변수는 최대 몇개까지 사요앟는 것이 좋을까?
    • 이상적인 매개변수 개수는 0개이며 적을 수록 좋다
    • 매개변수는 최대 3개 이상을 넘지 않는 것을 권장
    • 그 이상의 매개변수가 필요하다면 하나의 매개변수를 선언하고 객체를 인수로 전달하는 것이 유리하다.
  • 이상적인 함수는 한가지 일만 해야하며 가급적 작게 만들어야 한다.

12.5.4 반환문

  • 함수는 return 키워드와 표현식으로 이뤄진 반환문을 사용해 실행 결과를 함수 외부로 반환할 수 있다.
  • function multiply(x, y) { return x * y } var result = multiply(3, 5) console.log(result) // 15
  • 반환문은 두가지 역활을 한다.
    • 반환문은 함수의 실행을 중단하고 함수 몸체를 빠져나간다.
    • function multiply(x, y) { return x * y console.log('실행되지 않는다.') } console.log(multiply(3, 5)) // 15
    • 반환문은 return 키워드 뒤에 오는 표현식을 평가해 반환한다.
      • return 키워드 뒤에 반환값으로 사용할 표현식을 명시적으로 지정하지 않으면 undefined가 반환된다.
      function foo() {
      	return 
      }
      console.log(foo())     // undefined
      
    • 반환문은 생략할 수 있다.
      • 함수 몸체의 마지막까지 실행한 후 암묵적으로 undefined를 반환한다.
      function foo() {
      
      }
      console.log(foo())     // undefined
      
    • return 키워드와 반환값으로 사용할 표현식 사이에 줄바꿈이 있으면 세미콜론 자동 삽입 기능에 의해 의도치 않은 결과가 발생할 수 있다.
    • function multiply(x, y) { return x * y } console.log(multiply(3, 5)) // undefined

12.6 참조에 의한 전달과 외부 상태의 변경

  • 원시 값은 값에 의한 전달, 객체는 참조에 의한 전달 방식으로 동작
  • changeVal 함수는 매개변수를 통해 전달받은 원시 타입 인수와 객체 타입 인수를 함수 몸체에서 변경한다.
    • primitive의 경우 원시 값은 변경 불가능한 값이므로 직접 변경할 수 없기 때문에 재할당을 통해 할당된 원시값을 새로운 원시 값으로 교체
    • obj의 경우 객체는 변경 가능한 값이므로 직접변경할 수 있기 때문에 재할당 없이 직접 할당된 객체를 변경했다.
function changeVal(primitive, obj) {
	primitive += 100
	obj.name = 'Kim'
}

var num = 100
var person = { name: 'Lee' }

console.log(num)         // 100
console.log(person)      // {name: 'Lee'}

changeVal(num, person)

console.log(num)         // 100
console.log(person)      // {name: 'Kim'}

12.7 다양한 함수의 형태

12.7.1 즉시 실행 함수

  • 함수 정의와 동시에 즉시 호출되는 함수를 즉시 실행 함수라 한다.
    • 즉시 실행 함수는 단 한번만 호출되면 다시 호출할 수 없다.
    (function () {
    	var a = 3
    	var b = 5
    	return a * b
    }())              // 15
    
  • 즉시 실행 함수는 함수 이름이 없는 익명 함수를 사용하는 것이 일반적이다.
    • 함수 이름이 있는 기명 즉시 실행 함수도 사용할 수 있다.
    • 그룹 연산자 (…) 내의 기명 함수는 함수 선언문이 아니라 함수 리터럴로 평가되며 함수 이름은 함수 몸체에서만 참조할 수 있는 식별자이므로 즉시 실행 함수를 다시 호출할 수 는 없다.
    (function foo() {
    	var a = 3
    	var b = 5
    	return a * b
    }())              // 15
    
    foo()             // Uncaught ReferenceError: foo is not defined
    
  • 즉시 실행 함수는 반드시 그룹 연산자(…)로 감싸야 한다.
    • 그룹 연산자가 없으면 오류 발생
    function () {
    	var a = 3
    	var b = 5
    	return a * b
    }()                 // Uncaught SyntaxError: Function statements require a function name
    
  • 즉시 실행 함수도 일반 함수처럼 값을 반환할 수 있고 인수를 전달할 수도 있다.
  • var res = (function () { var a = 3 var b = 5 return a * b }()) console.log(res) // 15 res = (function (a, b) { return a * b }(3, 5)) console.log(res) // 15

12.7.2 재귀 함수

  • 함수가 자기 자신을 호출하는 것을 재귀 호출이라 한다.
  • 재귀 함수는 반복되는 처리를 위해 사용한다.
  • function countdown(n) { for (var i = n; i >= 0; i--) { console.log(i) } } countdown(10)
  • 재귀 함수를 사용하여 만들어보기
  • function countdown(n) { if (n < 0) return console.log(n) countdown(n - 1) } countdown(10)
  • 재귀 함수를 사용하면 반복되는 처리를 반복문 없이 구현 할 수 있다.
    • 팩토리얼은 재귀 함수로 간단히 구현할 수 있다.
    • function factorial(n) { if (n <= 1) { return 1 } return n * factorial(n - 1) } console.log(factorial(0)) // 1 console.log(factorial(1)) // 1 console.log(factorial(2)) // 2 console.log(factorial(3)) // 6 console.log(factorial(4)) // 24 console.log(factorial(5)) // 120 console.log(factorial(6)) // 720 console.log(factorial(7)) // 5040
  • 재귀 함수는 반복되는 처리를 반복문 없이 구현할 수 있는 장점이 있지만 무한 반복에 빠질 위험이 있고 이로 인해 스택 오버플로 에어를 발생시킬 수 있으므로 주의해서 사용해야한다

12.7.3 중첩 함수

  • 함수 내부에 정의된 함수를 중첩 함수 또는 내부 함수라 한다.
  • 중첩 함수를 포함하는 함수는 외부 함수라 부른다.
  • 중첩 함수는 외부 함수 내부에서만 호출 할 수 있다.
  • 일반적으로 중첩 함수는 자신을 초함하는 외부 함수를 돕는 헬퍼 함수의 역활을 한다.
  • function outer() { var x = 1 function inner() { var y = 2 console.log(x + y) // 3 } inner() } outer()
  • ES6부터 함수 정의는 문이 위치할 수 있는 문맥이라면 어디든지 가능하다.
  • ES6이전에는 코드의 최상위 또는 다른 함수 내부에서만 정의할 수 있어으나 ES6부터는 if 문이나 for문 등의 코드 블록내에서도 정의할 수 있다.
  • 호이스팅으로 인해 혼란이 발생할 수 있으므로 if 문이나 for 문 등의 코드 블록에서 함수 선언문을 통해 함수를 정의하는 것은 바람직하지 않다.

12.7.4 콜백 함수

  • 어떤 일을 반복 수행하는 repeat 함수를 정의해 보자
  • function repeat(n) { for (var i=0; i<n; i++) { console.log(i) } } repeat(5)
  • repeat 함수의 반복문 내부에서 다른 일을 하고 싶다면 함수를 새롭게 정의해야 한다.
  • 함수의 변하지 않는 공통 로직은 미리 정의해 두고, 경우에 따라 변경되는 로직은 추상화해서 함수외부에서 함수 내부로 전달
    • 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백 함수라고 하며, 매개 변수를 토해 함수의 외부에서 콜백 함수를 전달받은 함수를 고차 함수라고 한다.
    function repeat(n, f) {
    	for (var i=0; i<n; i++) {
    		f(i)
    	}
    }
    
    var logAll = function(i) {
    	console.log(i);
    }
    
    repeat(5, logAll)
    
    var logOdds = function(i) {
    	if (i % 2) {
    		console.log(i)
    	}
    }
    
    repeat(5, logOdds)
    
  • 고차 함수는 콜백 함수를 자신의 일부분으로 합성한다.
    • 고차 함수는 매개변수를 통해 전달받은 콜백 함수의 호출 시점을 결정해서 호출 한다.
    • 콜백 함수는 고차함수에 의해 호출되며 고차함수는 필요에 따라 콜백 함수에 인수를 전달할 수 있다.
    // 익명 함수 리터럴을 콜백 함수로 고차 함수에 전달
    repeat(5, function(i) {
    	if (i % 2) {
    		console.log(i)
    	}
    })
    
  • 콜백 함수는 함수평 프로그래밍 패러다임뿐만 아니라 비동기 처리(이벤트 처리, Ajax 통신, 타이머 함수 등)에 활용되는 중요한 패턴이다.
  • document.getElementById('myButton').addEventListener('click', function() { console.log('button clicked!') }) setTimeout(function () { console.log('1초 경과') }, 1000);
  • 콜백 함수는 비동기 처리 뿐만 아니라 배열 고차 함수에서도 사용된다.
  • var res = [1, 2, 3].map(function (item) { return item * 2 }) console.log(res) // [2, 4, 6] res = [1, 2, 3].filter(function (item) { return item % 2 }) console.log(res) // [1, 3] res = [1, 2, 3].reduce(function (acc, cur) { return acc + cur }) console.log(res) // 6

12.7.5 순수 함수와 비순수 함수

  • 함수형 프로그래밍에서는 어떤 외부 상태에 의존하지도 않고 변경하지도 않는 부수 효과가 없는 함수를 순수 함수라고 한다
    • 순수 함수는 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수다
    var count = 0
    function increase(n) {
    	return ++n
    }
    
    count = increase(count)
    console.log(count)
    
    count = increase(count)
    console.log(count)
    
  • 외부 상태에 의존하거나 외부 상태를 변경하는 부수효과가 있는 함수를 비 수순수 함수라고 한다.
    • 함수가 외부 상태를 변경하면 상태 변화를 추적하기 어려워 진다.
    • 함수 외부 상태의 변경을 지양하는 순수 함수를 사용하는 것이 좋다
    var count = 0
    function increase() {
    	return ++count
    }
    
    increase(count)
    console.log(count)
    
    increase(count)
    console.log(count)
    
728x90

'자바스크립트 > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글

전역 변수의 문제점  (1) 2023.11.15
스코프  (0) 2023.11.15
원시 값과 객체의 비교  (0) 2023.11.15
객체 리터럴  (0) 2023.11.15
타입 변환과 단축 평가  (0) 2023.11.15