'프로그래밍/Javascript' 카테고리의 글 목록 :: 잡다한 프로그래밍
반응형

자바스크립트의 호이스팅에 대해 알아보는 시간을 가진다.


1. 호이스팅 (Hoisting)

- 자바스크립트에서 선언하는 변수값은 모두 유효 범위의 최상단으로 선언된다 = 즉 나는 밑에서 선언했지만 제일 상단에서 선언한것처럼 동작한다. 라는 의미를 가진다.

  • 자바스크립트 Parser가 함수 실행 전 해당 함수를 한번 훑는과정을 거친다.
  • 함수 안에 존재하는 변수/함수 선언에 대한 정보를 내부적으로 끌어올려서 처리한다(코드상의 변화가 있지는 않음)

 호이스팅의 대상

  • var 변수 선언, 함수 선언문에서 호이스팅이 일어난다.
    • let, const 에서는 호이스팅이 일어나지 않음 (ES6에서 개선) ※ 호이스팅은 일어나나, 발생하지 않는것처럼 참조 에러가 발생함

변수는 어떤식으로 생성 될까?

1. 변수의 선언

  • 변수를 실행 컨텍스트의 변수 객체에 등록함.

2. 초기화 단계

  • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다.
  • 이때 변수는 undefined로 초기화 된다.

3. 할당 단계

  • 실제 undefined로 초기화된 변수에 값을 할당한다.

 

앞서 말한 var키워드는 선언, 초기화가 한번에 이루어진다. 즉 스코프에 변수를 등록하고 공간을 확보한 후 undefined로 초기화한다. 하지만 let키워드는 선언과 초기화가 분리되어 진행되므로, 초기화 이전에 접근하면 에러가 발생한다.

 

- 앞서 이론적인 부분을 코드적으로 이해해보도록 하자

변수 선언에서의 호이스팅 예시

console.log(val); //선언 + 초기화
val = 'text'; //선언 + 초기화 + 할당
var val = 'hi';

- 해당 코드를 js가 아닌 다른 언어로 생각했을경우 1 번째 line에서 에러가 발생해야한다 하지만 결과는 undefined값이 찍힌다. 이유는 앞선 선언 + 초기화가 되어있기 때문이다

console.log(val); // 호이스팅에 의해 끌어올려졌지만 초기화는 안된 상태
let val = 'hi'

let을 사용하게되면 선언만 이루어지고 초기화는 되지않아서 에러가 발생한다.

 

함수 선언에서의 호이스팅 예시

test(); // 함수 선언문 정상동작 호이스팅 O
test2(); // 함수 표현식 오류 발생 호이스팅 X 

function test() {
	console.log('test');
}

var test2 = function() {
	console.log('test2');
}

- 함수 선언문같은 경우 호이스팅이 된다. 하지만 함수 표현식의 경우 호이스팅이 이루어지지 않는다.

함수 선언문의 경우 = 함수 전체가 최상단으로 호이스팅 된다. 하지만 함수 표현식의 경우 변수가 호이스팅 되기때문에 에러가 발생한다

 

클래스의 호이스팅

그렇다면 ES6에 추가된 클래스는 어떨까? (let, const가 변수 선언 전에 사용하면 에러가발생하듯 class의 경우도 오류가 발생할까?)

let test = new Test('hi'); // ReferenceError: Person is not defined
console.log(peter);

class Test {
  constructor(val) {
    this.val = val;
  }
}

생각한 대로 클래스는 ReferenceError를 내뱉는다. 함수 선언문의 경우 호이스팅 되어 이전에 사용할 수 있었지만. ES6에서 추가된 클래스의 경우는 호이스팅 되어도 초기화가 되지않기 때문에 (let, const 처럼) 에러를 내뱉는다.

 

- 마찬가지로 클래스 표현식 let val = class Test {....} 로 정의할 경우도 에러를 발생시킨다.

 

이상 간단한 호이스팅 정리였다.

반응형
반응형

자바스크립트의 프로토 타입, 클래스에 대해 알아보는 시간을 가진다.


1. 프로토타입 (prototype)

- 프로토 타입은 JS에 클래스가 생기기전 객체를 다를 객체로 상속하기 위해 사용하는 개념이다 (ES6의 클래스는 타 언어의 클래스와 거의 흡사하고, 내부적으로는 prototype을 따른다고 함)

 

- 앞서 JS에서 객체 생성자란 무엇인지, 상속은 어떤방식으로 하는지 간단하게 확인해보자.

function People(name, age) {
  this.name = name;
  this.age = age;
  this.info = function() {
    console.log('이름: ' + name);
    console.log('나이: ' + age);
  }
}

const test = new People('A', '30');
const test2 = new People('B', '20');

test.info();
test.info();

- 결과는 예상한대로 이름 : A, 나이 :30 이름: B, 나이: 20이 나온다.

 

여기서 프로토타입을 사용하면 다음과 같이 바뀐다.

function People(name, age) {
  this.name = name;
  this.age = age;
}

People.prototype.info = function() {
    console.log('이름: ' + this.name);
    console.log('나이: ' + this.age);
}

const test = new People('A', '30');
const test2 = new People('B', '20');

test.info();
test.info();

그렇다면 프로토타입을 사용했을때 무엇이 달라질까?

 

- 프로토 타입을 사용하지 않은경우 객체하나를 생성할때마다 info라는 메소드가 할당된다. 즉 2개의 객체를 생성하면 2개의 info가 할당되는 셈이다

 

- 반면 프로토타입을 사용한경우 People객체는 하나의 info메소드를 생성하고 객체에서 참조하여 사용하게 된다.

즉 2개의 객체를 생성했지만 info 메소드는 1개만 생성되는 차이가 있다.

 

- 이로서 프로토 타입은 불필요한 메모리 낭비를 막을 수 있는 중요한 개념이다.

 

프로토타입을 이용한 상속은 다음과 같다.

function People(name, age) {
    this.name = name;
    this.age = age;
}

People.prototype.info = function() {
    console.log('이름: ' + this.name);
    console.log('나이: ' + this.age);
}

function Child (name, age) {
    People.call(this, name, age);
}

Child.prototype = People.prototype;

const child = new Child('test', '30');

child.info();

2. 클래스

- 타언어의 클래스와 매우 유사하다 (JAVA, C...등)

ES6에서 새로 생긴 문법으로 기존 prototype을 활용한 객체 생성자를 클래스로 더 쉽게 표현할 수 있다.

class People {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    this.info = function() {
      console.log('이름 :' + this.name);
      console.log('나이 :' + this.age);
    }
  }
}

const people = new People('A', '10');
people.info();

- 클래스 상속은 다음과 같다.

class People {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    this.info = function() {
      console.log('이름 :' + this.name);
      console.log('나이 :' + this.age);
    }
  }
}

class Child extends People {
  constructor(name, age) {
    super(name, age);
  }
}


const child = new Child('A', '10');
child.info();
반응형
반응형

V자바스크립트의 실행 컨텍스트에 대해 간단하게 알아보는 시간을 가진다.

- 먼저 실행 컨텍스트란 왜 자바스크립트가 그렇게 동작하는지를 의미한다.


1. 실행 컨텍스트

function sum(a, b) {
	let res = a + b;
    return res;
}

let num = sum(1,2);

- 같은 코드가 존재한다고 가정했을때 동작 순서는 다음과 같다.


2. 콜 스택

- 코드가 실행될때 호출 스택이 쌓이는 부분

function sum(a, b) {
	let r = a + b;
    return r;
}

function calc(a, b, expr) {
	let result = expr(a, b);
    return result;
}

let num = calc(1, 2, sum);

- 다음과 같은 실행 순서로 동작한다

- 16번 후 expr() pop되어 제거
- 17번 후 calc() pop되어 제거

 


3. 스코프

- 현재 접근할 수 있는 변수들의 범위를 의미함

반응형

'프로그래밍 > Javascript' 카테고리의 다른 글

[JS] 호이스팅, Hoisting 이란?  (0) 2022.06.01
[JS] 프로토타입, 클래스란?  (0) 2022.05.26

+ Recent posts