# 모던 자바스크립트 Deep dive

ref

모던 자바스크립트 Deep dive (이웅모 저 / 위키북스)
상기 서적을 읽은 뒤 나름의 방식대로 요약 정리한 내용입니다.
담당 챕터가 아닌 부분은 읽으며 기억해두고 싶은 부분만 발췌 메모해두었습니다.

# 1장. 프로그래밍

프로그래밍이란 문제(=요구사항)를 해결하기 위해 컴퓨터에게 프로그램의 실행을 요구하는 일종의 커뮤니케이션이다. 컴퓨터가 사고하는 방식은 인간과 다르게 직관이나 직감이 존재하지 않기 때문에 우리 머릿속에 있는 의도를 배제하고 정확하고 상세하게 요구사항을 설명할 줄 알아야 한다.
이러한 사고 과정에서 필요한 것이 비로 Computational thinking(컴퓨팅 사고)이다.

이 단계에서 분명히 알고 넘어가야 하는 것은 컴퓨터와 사람의 사고, 인지의 방식이 다르다는 것이다. 따라서 프로그래밍을 하기 위해서는 컴퓨터의 관점에서 문제를 사고해야 한다. 여기에는 논리적 수학적 사고가 필요하며, 해결 과제를 작은 단위로 분해하고 패턴화해서 추출해야하고, 프로그래밍 내에서 사용될 모든 개념은 평가 가능하도록 정의되어야 한다.

  • 기계어(Machine code) : 컴퓨터가 이해할 수 있는 언어.
    • 기계어는 비트 단위로 기술되어있어 사람이 직접 작성하여 명령을 전달하기 힘들다.
  • 프로그래밍 언어(Programming language) : 사람이 이해할 수 있는 약속된 구문으로 구성된 언어.
    • 프로그래밍 언어로 명령을 작성한 후, 일종의 번역기에 해당하는 컴파일러(Compiler)나 인터프리터(Interpreter)를 이용해 기계어로 변환할 수 있다.

프로그래밍이란 이러한 프로그래밍 언어를 사용해 컴퓨터에게 실행을 요구하는 일종의 커뮤니케이션이다. 이 프로그래밍 언어는 구문(syntax)의미(semantics)의 조합으로 표현된다.

언어의 의미는 문맥에 있는 것이지 문법에 있는 것이 아니다. -노엄 촘스키

문법에 부합하는 것은 물론이고 수행하고자 하는 바를 정확한 의미로 수행하는 프로그래밍 언어가 비로소 의미가 있다. 물론 이러한 문제 해결을 적절하게 수행하기 위해서는 문법의 이해가 필수적이다. 적절한 자료구조와 함수의 흐름을 제어해 요구사항의 집합을 해결하는 것이 프로그래밍의 목적이라고 볼 수 있다.

# 2장. 자바스크립트란?

# ECMAScript

넷스케이프 커뮤니케이션즈에서 비영리 표준화 기구인 ECMA 인터내셔널에 자바스크립트의 표준화를 요청해 만든 표준화 사양. 2015년에 공개된 ECMAScript 6(ECMAScript 2015, ES6)는 let/const 키워드, 화살표 함수, 클래스, 모듈 등과 같이 범용 프로그래밍 언어로서 갖춰야 할 기능들을 대거 도입하는 큰 변화가 있었다. ES6 이후의 ECMAScript 들은 보통 연도를 붙여서 부른다. (ECMA 2020 등..)

ECMAScript는 JS의 뼈대가 되는 표준 사양으로, 자바스크립트는 이러한 ECMAScript와 브러우저가 별도 지원하는 클라이언트 사이드 Web API로 이루어져 있다.

  • 클라이언트 사이드 Web API란?
    • DOM, BOM, Canvas, XMLHttpRequest, fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 등
    • ECMAScript와는 별도로 월드 와이드 웹 콘소시엄(World Wide Web Consortium, W3C)에서 별도의 사양으로 관리하고 있다.

# 자바스크립트 성장의 역사

Ajax -> jQuery -> V8 자바스크립트 엔진 -> Node.js -> SPA 프레임워크

# 자바스크립트의 특징

  • 인터프리터 언어
  • 웹 브라우저에서 동작하는 유일한 프로그래밍 언어
  • 명령형(Imperative), 함수형(Functional), 프로토타입 기반(Prototype-based) 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어

# 4장. 변수

# 변수란 무엇인가?

애플리케이션이 다루는 데이터는 컴퓨터에 저장되고 연산에 이용된다. 컴퓨터는 CPU를 이용하여 연산을 수행하고, 메모리를 사용해 데이터를 기억(=저장) 한다.
이 때, 데이터를 저장할 수 있는 메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체이다. 메모리 셀 하나는 1바이트의 크기를 가지고 있으며 고유의 메모리 주소를 가지고 있다.
하지만 자바스크립트와 같은 언매니지드 언어는 안전상의 이유로 개발자가 메모리에 직접 접근하는 것을 허용하지 않으며, 따라서 이미 메모리 셀을 차지하고 있는 데이터를 다시 끌어 와 사용하기 위해서는 해당 공간을 식별하기 위한 별도의 이름 을 붙여줘야 한다. 이러한 식별자를 변수라고 한다.

간단하게 요약해보자면 다음과 같다.

  • 변수: 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름
  • 식별자: 어떠한 값을 구별해서 식별할 수 있는 고유한 이름으로, 변수 이름은 식별자의 일종이다.

변수 뿐 아니라 함수, 클래스 등의 이름은 모두 식별자에 해당한다.

# 변수의 선언과 할당

변수를 사용하기 위해서는 선언(declaration)할당(assignment) 이라는 두 단계를 거쳐야 한다.

  • 변수 선언
    • 변수를 생성하는 것
    • 값을 저장하기 위한 메모리 공간을 확보하고, 변수 이름과 확보된 메모리 공간의 주소를 연결하는 것
    • 변수를 선언하면 확보한 메모리 공간의 값을 초기화하여 undefined로 만든다.
    • 변수 선언을 위해 var, let, const 키워드를 사용할 수 있다.
  • 변수 할당
    • 해당 변수에 값을 할당한다.
    • 할당 연산자 = 를 이용하여 변수에 값을 할당할 수 있다.

이 때 주의할 점이 있는데, 변수의 선언과 할당이 하나의 문으로 이루어져 있어도 자바스크립트는 이것을 선언과 할당으로 분리하여 각각 실행한다는 것이다. 그리고 변수의 선언과 할당은 서로 다른 시점에 실행된다.
변수의 선언은 런타임 이전 소스코드의 평가 단계에서 먼저 이루어진다. 그리고 실제 소스코드가 순차적으로 실행되는 시점(=런타임)에 할당이 이루어진다.
변수의 선언이 런타임 이전에 끌어올려져 먼저 실행되는 것을 호이스팅 이라 하며, 호이스팅은 자바스크립트가 가지고 있는 고유한 특징 중 하나이다.

# 값의 재할당과 가비지 콜렉터

변수는 재할당을 이용해 값을 변경할 수 있다.
이 때 값을 변경할 수 없는, 즉 고정된 값을 가지는 식별자는 변수가 아니라 상수(constant)라고 한다.

var score;
score = 80;
score = 90;

위와 같은 자바스크립트 코드를 실행하면, score라는 변수에 90이라는 값이 재할당되며 이전에 할당되었던 초기값 undefined와 80은 더 이상 아무런 식별자와도 연결되어있지 않는 값이 된다. 즉, 아무도 사용하고 있지 않은 상태 가 되는 것이다. 이러한 불필요한 값들은 가비지 콜렉터(Garbage collector)에 의해 메모리에서 자동 해제 된다.

가비지 콜렉터란?

애플리케이션이 메모리 공간을 주기적으로 검사하여 더이상 사용되지 않는 메모리를 해제하는 기능이다. 여기서 더이상 사용되지 않는 메모리란 어떤 식별자도 참조하지 않는 메모리 공간을 의미한다. 자바스크립트는 가비지 콜렉터를 내장하고 있으며, 가비지 콜렉터를 통해 메모리 누수(Memory leak)를 방지한다.

매니지드 언어와 언매니지드 언어

프로그래밍 언어는 메모리 관리 방식에 따라 매니지드 언어와 언매니지드 언어로 분류할 수 있다.

📌 언매니지드 언어: 개발자가 명시적으로 메모리를 할당하고 해제하기 위해 저수준 메모리 제어 기능을 이용할 수 있는 언어. 개발자의 역량에 따라 최적의 성능을 확보할 수 있지만, 반대로 개발자의 역량에 따라 치명적인 오류를 생산할 가능성도 있다. 대표적인 예시는 C언어.

📌 매니지드 언어: 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하는 언어. 개발자의 직접적인 메모리 제어를 허용하지 않는다. 매니지드 언어는 개발자의 역량에 의존하는 부분이 상대적으로 작아져 어느 정도 일정한 생산성을 확보할 수 있다는 장점이 있다, 하지만 성능 면에서 어느 정도의 손실은 감수할 수 밖에 없음.

# 식별자 네이밍 규칙

자바스크립트의 식별자 네이밍에는 다음과 같은 규칙이 있다.

  • 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러기호($)를 포함할 수 있다.
  • 단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다.
  • 예약어는 식별자로 사용할 수 없다.
  • 자바스크립트의 예약어는 다음과 같아.
await, break, case, catch, class, const ,continue, debugger, default, delete, do, else, enum, export, extends, false, finally, for, function, if, implements, import, in, instanceof, interface, let, new, null, package, private, protected, public, return, super, static, switch, this, throw, true, try, typeof, var, void, while, with, yield

식별자 이름을 정할 때에는 일정한 네이밍 컨벤션을 가지고 명명하는 것이 좋다. 보편적으로 사용되는 네이밍 컨벤션에는 다음과 같은 것들이 있다.

// 카멜 케이스 (camelCase)
let firstName;

// 스네이크 케이스 (snake_case)
let first_name;

// 파스칼 케이스 (PascalCase)
let FirstName;

// 헝가리안 케이스 (typeHungarianCase)
let strFirstName; // type + identifier
let $elem = document.getElementById("myId"); // DOM 노드
let observable$ = fromEvent(document, "click"); // RxJS 옵저버블

일관성을 유지한다면 어떤 네이밍 컨벤션을 사용해도 상관없으나, 자바스크립트에서는 일반적으로 변수나 함수의 이름에는 카멜케이스를, 생성자 함수나 클래스의 이름에는 파스칼 케이스를 사용한다.

# 10장. 객체 리터럴

# 객체란?

자바스크립트를 구성하는 거의 모든 것 이 객체이다. 원시값을 제외한 나머지 값(함수, 배열, 정규 표현식 등)은 모두 객체라고 볼 수 있다.

  • 원시 타입: 단 하나의 값
  • 객체 타입: 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료 구조

📌 Point! 그렇다면 함수는?
자바스크립트의 함수는 일급 객체 이므로 값을 취급할 수 있다. 즉, 함수도 객체의 프로퍼티 값으로 사용할 수 있다는 뜻. 프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드(mothod) 라고 부른다.

객체는 프로퍼티와 메서드로 구성된 집합체다.

  • 프로퍼티: 객체의 상태를 나타내는 값, data.
  • 메서드: 프로퍼티를 참조하고 조작할 수 있는 동작, behavior

객체는 객체의 상태를 나타내는 값프로퍼티를 참조하고 조작할 수 있는 동작을 모두 포함할 수 있다. 상태와 동작을 하나의 단위로 구조화할 수 있어 유용하며, 이러한 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임을 객체지향 프로그래밍 이라 한다.

# 객체 리터럴

프로토타입 기반 객체지향 언어인 자바스크립트는 다양한 객체 생성 방법을 지원한다.

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.create 메서드
  • 클래스 (ES6 이후)

이러한 방법 중 가장 일반적이고 간단한 방법은 객체 리터럴을 사용하는 방법이다. 객체 리터럴이란 약속된 기호를 사용하여 객체를 생성하기 위한 표기법으로, 중괄호 안에 0개 이상의 프로퍼티를 정의하는 형식으로 객체를 생성할 수 있다.

// 객체 리터럴 예시
const person = {
  name: "Lee",
  sayHello: function () {
    console.log(`Hello! My name is ${this.name}`);
  },
};

console.log(typeof person); // object
console.log(person); // {name: "Lee", sayHello: ƒ }

// 중괄호 내에 프로퍼티를 정의하지 않다고 빈 객체가 생성된다.
const empty = {};
console.log(typeof empty); // object

주의!

객체 리터럴의 중괄호는 코드 블록을 의미하지 않기 때문에 닫는 중괄호 뒤에 세미콜론을 붙여주어야 한다. 객체 리터럴은 값으로 평가되는 표현식이라는 점에 유의.

객체 리터럴은 자바스크립트의 유연함과 강력함을 대표하는 객체 생성 방식으로, 객체를 생성하기 위해 클래스를 정의하고 new 연산자와 함께 생성자를 호출할 필요가 없다. 객체 리터럴에 프로퍼티를 포함시켜 객체를 생성하는 시점에 프로퍼티를 만들어 줄 수도 있고, 객체를 생성한 이후 프로퍼티를 동적으로 추가할 수도 있다.

# 프로퍼티

const person = {
  name: "Lee", // 프로퍼티 키는 name, 프로퍼티 값은 "Lee"
  age: 20, // 프로퍼티 키는 age, 프로퍼티 값은 20
};

객체에 담겨있는 데이터 하나하나가 프로퍼티이며, 프로퍼티는 쉼표(,)로 구분된다. 각각의 프로퍼티는 프로퍼티 키와 프로퍼티 값으로 구성되어 있다.
프로퍼티 키와 값으로 사용할 수 있는 값은 다음과 같다.

  • 프로퍼티 키: 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
  • 프로퍼티 값: 자바스크립트에서 사용할 수 있는 모든 값

주의점

  1. 식별자 네이밍 규칙을 준수하지 않는 식별자도 키로 사용할 수 있다.
  2. 프로퍼티 키는 문자열이므로 따옴표로 묶어야 한다. 단, 식별자 네이밍 규칙을 준수하는 경우에는 따옴표를 생략할 수 있다.
// 식별자 네이밍 규칙 준수 여부에 따른 차이 예시
const person = {
  firstName: "Joo-eun", // 식별자 네이밍 규칙을 준수하는 키
  "last-name": "Kang", // 식별자 네이밍 규칙을 준수하지 않는 키
};
  1. 빈 문자열을 프로퍼티 키로 사용하는 것도 가능하나 키로서의 의미를 갖지 못하므로 권장하지 않는다.
  2. var, function 등의 예약어도 프로퍼티 키로 사용이 가능하나, 예상치 못한 에러가 발생할 수 있으므로 권장하지 않는다.
  3. 이미 존재하는 프로퍼티 키를 중복 선언시 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어쓴다. 이 때 에러는 발생하지 않는다.

# 메서드

프로퍼티 값이 함수인 경우 일반 함수와 구분하기 위하여 메서드라 부른다. 즉, 메서드란 객체에 묶여 있는 함수이다. 이 때, this 키워드를 이용해 객체 자신을 참조할 수 있다. (자세한 내용은 22장 this에서 살펴볼 것)

# 프로퍼티 접근 방법 두 가지

프로퍼티에는 다음 두 가지 방법을 이용하여 접근할 수 있다.

  • 마침표 표기법

    • 마침표 프로퍼티 접근 연산자를 사용
    • 프로퍼티 키가 식별자 네이밍 규칙을 준수하는 경우에만 사용이 가능하다.
  • 대괄호 표기법

    • 대괄호 프로퍼티 접근 연산자를 사용
    • 프로퍼티 키가 식별자 네이밍 규칙을 준수하는 경우, 준수하지 않는 경우 모두 사용이 가능하다.
    • 대괄호 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다. (따옴표로 감싸지 않은 이름을 입력하는 경우, 해당 식별자를 찾을 수 없어서 ReferenceError가 뜬다.)
  • 예시

    const person = {
      'last-name': 'Lee'
    };
    
    person.'last-name'; // SyntaxError: Unexpected string
    person.last-name; // 브라우저 환경 -> NaN, Node,js 환경 -> ReferenceError: last is not defined
    person[last-name]; // RefereceError: last is not defined
    person['last-name']; // Lee
    

    단, 프로퍼티 키가 숫자로 이루어진 문자열일 경우 따옴표를 생략할 수 있다.

    const person = {
      'last-name': 'Lee'
      1: 10,
    };
    
    person[last-name]; // RefereceError: last is not defined
    person[1]; // 10
    

# 객체 리터럴의 기타 확장 기능

  1. 프로퍼티 값 갱신
    • 이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신된다.
  2. 프로퍼티 동적 생성
    • 존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.
  3. 프로퍼티 삭
    • delete 연산자를 이용해 객체의 프로퍼티를 삭제할 수 있다.
const person = {
  name: "Lee",
};

// 프로퍼티 값 갱신
person.name = "Kim";
console.log(person); // {name: "Kim"}

// 프로퍼티 동적 생성
person.age = 20;
console.log(person); // {name: "Kim", age: 20}

// 프로퍼티 삭제
delete person.age;
console.log(person); // {name: "Kim"}

// 프로퍼티 삭제 - 객체 내에 해당 프로퍼티가 존재하지 않는 경우
delete person.address;
console.log(person); //{name: "Kim"}
// delete 연산자를 이용하여 해당 프로퍼티를 삭제할 수 없으므로 person이라는 객체가 가지고 있는 데이터는 동일하다. 단, 이때 에러는 발생하지 않는다.

# ES6에서 추가된 객체 리터럴 확장 기능

  1. 프로퍼티 축약 표현 (Property shorthand)
    • 프로퍼티 값으로 변수를 사용하는 경우, 변수 이름과 프로퍼티 키가 동일한 이름일 때 키를 생략할 수 있다. ES6부터 제공하는 객체 리터럴의 확장 기능
let x = 1,
  y = 2;
const obj = { x, y };
console.log(obj); // {x: 1, y: 2}
  1. 메서드 축약 표현
    • 메서드를 정의할 때 function 키워드를 생략하고 축약해서 표현할 수 있다.
const obj = {
  name: "Lee",
  sayHi: function () {
    console.log("Hi!", this.name);
  },
};

// 위와 같은 표기 방식을 아래와 같이 축약할 수 있다.

const obj = {
  name: "Lee",
  sayHi() {
    console.log("Hi!", this.name);
  },
};
  1. 계산된 프로퍼티 이름
    • 문자열 또는 문자열로 타입 변환할 수 있는 값으로 평가되는 표현식을 이용해 프로퍼티 키를 동적으로 생성할 수도 있다.
const obj = {};
let i = 0;

const obj = {
  [`${prefix}-${++i}`]: i,
  [`${prefix}-${++i}`]: i,
  [`${prefix}-${++i}`]: i,
};

console.log(obj); // {prop-1: 1, prop-2: 2, prop-3: 3}

덧붙임

이 부분 예시의 표기 방식이 신기했다.
[ ++i => i = i + 1과 같음 ] 이라는 사실을 이용해서 마치 반복문처럼 i를 계속해서 증가시키고, 해당 내용을 프로퍼티의 키와 값에 할당하는 방식..

# 11장. 원시 값과 객체의 비교

# 원시 값

  1. 불변성(immutability)
    원시 값은 변경 불가능한 값이다. 변수 값을 변경해도 원시 값 자체가 변경되는 것이 아니라 새로운 메모리 공간에 원시 값을 할당하고 해당 변수와 연결해주는 것 뿐이다. 이러한 값의 특성을 불변성이라고 한다.
    불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.
  2. 문자열
    문자열은 길이에 따라 서로 다른 메모리 공간을 차지한다. 그래서 C나 자바 등에서는 문자열을 독립된 각 문자의 배열이나 String 객체 같은 형태로 처리하는데, 자바스크립트는 원시 타입인 문자열 타입을 제공한다. (자바스크립트의 장점!)
    자바스크립트의 문자열은 유사 배열 객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근할 수 있다.

이터러블

그래서 이터러블이 뭔데? 32장 '이터러블'에서 알아보자.

유사배열객체

마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체. 원시 값을 객체처럼 사용하는 경우 원시 값을 감싸는 래퍼 객체로 자동 변환된다. (이것도 차후에 살펴볼 내용이라고 함)

# 객체

  1. 객체 관리 방식
    자바, C++같은 클래스 기반 객체지향 프로그래밍 언어는 사전에 정의된 클래스에 없는 프로퍼티나 메서드를 객체(인스턴스)에 추가할 수 없다. 하지만 자바스크립트는 객체 생성 이후에도 동적으로 프로퍼티와 메서드를 추가할 수 있고, 이건 사용하기 편리하지만 생성과 프로퍼티 접근에 비용이 많이 들어가는 비효율적 방식이다. 때문에 V8 JS 엔진에서는 프로퍼티에 접근하기 위해 동적 탐색 대신 히든 클래스(Hidden class) 라는 방식을 사용해 프로퍼티 접근 시의 향상된 성능을 보장한다.
  2. 변경 가능한 값 (mutable value)
    참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체이다. 변수는 이 참조 값을 통해 객체에 접근할 수 있다. 때문에 객체를 할당한 변수의 경우 "변수는 객체를 참조하고 있다" 또는 "변수는 객체를 가리키고 있다"라고 표현한다.
    이 때 객체는 변경 가능한 값이므로, 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다. (프로퍼티 동적 추가, 갱신, 삭제 모두 가능하다는 뜻)
    -> 단, 이러한 구조 때문에 부작용이 발생한다. 바로 원시 값과는 다르게 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 것.

# 값에 의한 전달 & 참조에 의한 전달

  1. 값에 의한 전달 pass by value
  • 원시 값을 갖는 변수를 다른 변수에 할당하는 경우
  • 해당 원시 값이 복사되어 전달된다.
  • 복사한 값과 복사된 값은 같은 값이지만, 서로 다른 메모리 공간에 저장된 별개의 값이다.
  1. 참조에 의한 전달 pass by reference
  • 객체를 가리키는 변수를 다른 변수에 할당하는 경우
  • 원본의 참조 값이 복사되어 전달된다.
  • 복사한 값과 복사된 값이 동일한 참조 값을 가지게 된다. 즉, 두 개의 식별자가 하나의 객체를 공유하는 것. 원본과 사본 중 어느 한쪽에서 객체를 변경하면 서로 영향을 주고받게 된다.
  • 엄밀하게 말하면, 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사한다는 점에서 값에 의한 전달에 해당한다. 해당 값이 원시 값이 아니라 참조 값이라는 차이가 있을 뿐이다. 그렇기 때문에 '참조에 의한 전달'이 아니라 '공유에 의한 전달'이라고 표현할 수도 있다.

덧붙임

위와 같은 부분은 ECMAScript 사양에 정의된 JS 공식 용어는 아니다. 다만 여타 프로그래밍 언어에서 사용하는 언어를 가져와 표현하고 있을 뿐으로, 자바스크립트에는 포인터(pointer)가 존재하지 않기 때문에 포인터가 존재하는 다른 프로그래밍 언어의 '참조에 의한 전달'과 의미가 정확하게 일치하지 않는다.