자바스크립트 인터프리터가 함수의 선언, 할당, 실행을 나눠해서 모든 선언이 코드의 선두로 끌어올려진 것처럼 동작하는 현상의 개념

즉, 자바스크립트 엔진이 실행컨텍스트가 활성화 될 때 변수정보를 수집하는데 

이때 실제 끌어올려지지는 않았지만 수집과정에서 엔진이 수집된 정보를 토대로 변수들을 알고 있기 때문에 끌어올려진 것으로 간주하는 개념 

 

설명보기

Q. var, let 둘 다 호이스팅이 된다? 

- 정답은 둘 다 호이스팅되나 동작때문에 var만 실행 시 에러가 나지 않는다. 이때문에 var만 호이스팅된다고 착각할 수 있다.

 

설명

var는 선언과 할당을 동시에 실행하므로 호이스팅되었을때, undefined가 메모리에 저장된다.

let은 선언과 할당을 별도로 실행한다.

따라서 호이스팅되었을때, 선언은 되었지만 할당은 되지 않아서 메모리에 저장되지 않으며 TDZ(Temporary Dead Zome)에 들어간다. 따라서 호출 시 초기화 전에는 엑세스할 수 없다는 에러가 뜨는데, 이것때문에 호이스팅 되지 않았다고 착각할 수 있다.

 

 

 

 

 

실행 컨텍스트는 실행한 코드에 제공 할 환경 정보들을 모아놓는 객체라고 생각하자.

콜 스택에 쌓아서 전체 코드를 관리하고 있어서 환경과 순서를 보장한다.

동작

실행 컨텍스트는 크게 3가지 동작을 한다.

  1. 내부 환경 정보 기록: 실행컨텍스트가 활성화 되는 시점(실행)에 선언된 변수를 수집한다. 
  2. 외부 환경 정보를 구성한다.  
  3. this 값을 설정하는 동작 구성

 

수집 정보

- 자바스크립트 엔진이 활용할 목적으로 생성할 뿐, 개발자가 코드에 접근 할 수 없다.

Variable Environment

  • 선언 시점의 Lexical Environment의 스냅샷이므로 변경사항이 반영되지 않는다.
  • Variable Environment를 생성하여 정보를 담고 복사하여 Lexical Environment를 만든다.

Lexical Environment

처음엔 Variable Environment와 같으나 변경사항이 실시간으로 반영된다. (이후에는 Lexical을 사용하는 이유)

  1. Environment Record (환경 기록)
    • 현재 컨텍스트내의 식별자(변수명, 함수명, 매개변수명....) 들에 대한 정보를 순서대로 저장한다.
    • 이때 정보의 수집을 마치게되면 실행컨텍스트가 관여할 코드들은 실행전이지만, 자바스크립트 엔진은 이미 해당 환경에 속해 있는 정보(변수명..)들을 알고 있기 때문에 '호이스팅'이 발생 할 수 있다.
  2. Outer-Environment Reference (외부 환경 참조)
    • 현재 호출된 함수가 선언된 당시 상위의 Lexical Environment를 참조한다.
    • 스코프 체인이 가능하게 하는 수집자료 (중첩된 자바스크립트 코드에서 스코프 탐색을 하기위해 사용)

This Binding

  • this 식별자가 바라봐야 할 대상 객체
  • 실행 컨텍스트 활성화 당시에 this로 지정된 객체가 저장된다. (this는 함수호출 방식 및 전역 여부에 따라 결정)



 

Nuxtjs + Typescript 프로젝트를 진행하고 있는데, 초반 설정부터 많은 문제가 생겼다.

이전에 작업할 때는 내가 린트 설정한 적이 없어서 생기는 문제인지, (내 머리탓)

아니면 버전(현재 v2.15.8)이 달라져서 혹은 Typescript 설정으로 생기는 문제인지 모르겠으나.

결론은 골치아픈 린트 설정 문제였다.

 

그래서 이렇게 골치아픈 김에 이것저것 검색해보고 설정하는데 꽤나 시간을 들이고 있다. (eslint, prettier, stylelint....)

덕분에 설정에만 시간을 엄청 쏟고 있다.

뻘짓에 대한 기록글과 해결한 방법 (은 하단에!)

 

과정에 대한 글

.stylelintrc.js - 실패

이렇게 더러운걸 커밋했다고? ㅎㅎㅎㅋㅋㅋㅋ

module.exports = {
  customSyntax: "postcss-html",
  extends: "stylelint-config-standard",
  plugins: ["stylelint-scss", "stylelint-order"],
  rules: {
    "string-quotes": "single",
  },
  overrides: [
    {
      files: [
        '**/**/*.scss',
        '**/**/**/*.scss',
      ],
      customSyntax: "postcss-scss",
      extends: "stylelint-config-standard-scss",
      rules: {
        "no-eol-whitespace": true, // 줄 끝, 닫는 중괄호 뒤 공백 허용 여부
        "color-hex-length": "long", // 16진수 색상에 대해 표기법 지정
        "declaration-block-trailing-semicolon": "always", // 선언 블록 내 후행 세미콜론을 요구
        "color-no-invalid-hex": true, // 잘못된 16진수 색상을 허용 여부
        "font-family-no-duplicate-names": true, // 중복 폰트 선언 여부
        "declaration-block-no-duplicate-properties": true, // 같은 선언 내 중복 속성 선언 여부
        "declaration-block-no-duplicate-custom-properties": true, // 같은 선언 내 중복 사용자 속성 선언 여부
        "no-duplicate-at-import-rules": true, // 중복 @import 규칙을 허용 여부
        "media-query-list-comma-newline-after": "always", // 미디어 쿼리 목록 쉼표 뒤 줄 바꿈이나 공백

        // 개행
        "rule-empty-line-before": "always-multi-line", // 규칙 앞에 빈줄 속성
        "block-opening-brace-newline-before": "never-single-line", // 여는 중괄호 앞 (선택자와 괄호 사이)
        "block-opening-brace-newline-after": "always", // 여는 중괄호 다음 개행
        "block-closing-brace-newline-after": "always", // 닫는 중괄호 뒤
        "block-closing-brace-newline-before": "always", // 닫는 중괄호 앞
        "block-opening-brace-space-before": "always", // 여는 중괄호 앞
      },
    }
  ]
}

 

postCSS를 제거하고 SCSS로 작업하려고 했더니, 종속성때문에 에러가 났다.

그래서 그냥 삭제하지 않고 customSyntax 설정만 제거했는데 이때도 에러가 났다.

그래서 위와 같이 overrides를 통해 files에서 scss파일만 추가해서 작업했다.

이때 생기는 문제는 vue파일에서 상단 postcss-html이 적용되고 있어서 어쩔수 없이 룰에 string-quotes를 single를 추가해야했다. (이때 .vue 파일때문이 아닐까?? 생각했다. 생각해보니 검색법이 잘못된듯 postCSS를 사용한다는 전제로 검색했던 것인가 휴.)

폴더 구조

이렇게 작업을 하고 나니까 생각해보니 vue파일을 ignore 시키면 될 것 같아서 stylelint의 ignore 설정법을 찾아봤고,,,

https://stylelint.io/user-guide/ignore-code

 

Ignoring code | Stylelint

You can ignore:

stylelint.io

 

결론

.stylelintrc.js

module.exports = {
  extends: "stylelint-config-standard-scss",
  plugins: ["stylelint-scss", "stylelint-order"],
  rules: {
  	"order/properties-alphabetical-order": true, // 알파벳 정렬
    "no-eol-whitespace": true, // 줄 끝, 닫는 중괄호 뒤 공백 허용 여부
    "color-hex-length": "long", // 16진수 색상에 대해 표기법 지정
    "declaration-block-trailing-semicolon": "always", // 선언 블록 내 후행 세미콜론을 요구
    "color-no-invalid-hex": true, // 잘못된 16진수 색상을 허용 여부
    "font-family-no-duplicate-names": true, // 중복 폰트 선언 여부
    "declaration-block-no-duplicate-properties": true, // 같은 선언 내 중복 속성 선언 여부
    "declaration-block-no-duplicate-custom-properties": true, // 같은 선언 내 중복 사용자 속성 선언 여부
    "no-duplicate-at-import-rules": true, // 중복 @import 규칙을 허용 여부
    "media-query-list-comma-newline-after": "always", // 미디어 쿼리 목록 쉼표 뒤 줄 바꿈이나 공백

    // 개행
    "rule-empty-line-before": "always-multi-line", // 규칙 앞에 빈줄 속성
    "block-opening-brace-newline-before": "never-single-line", // 여는 중괄호 앞 (선택자와 괄호 사이)
    "block-opening-brace-newline-after": "always", // 여는 중괄호 다음 개행
    "block-closing-brace-newline-after": "always", // 닫는 중괄호 뒤
    "block-closing-brace-newline-before": "always", // 닫는 중괄호 앞
    "block-opening-brace-space-before": "always", // 여는 중괄호 앞
  },
}

 

.stylelintignore

루트에 파일 생성

*.vue

그렇다 걍 vue 파일을 ignore시키면 되는 것이었다. 

(postcss, postcss-html, postcss-scss 모두필요엄슴 uninstall)

 

stylelint 적용

 

isUndefined와 isEmpty 비교

    console.log('빈 배열', `isUndefined: ${isUndefined([])} / isEmpty: ${isEmpty([])}`);
    console.log('빈 오브젝트', `isUndefined: ${isUndefined({})} / isEmpty: ${isEmpty({})}`);
    console.log('빈 문자열', `isUndefined: ${isUndefined('')} / isEmpty: ${isEmpty('')}`);
    console.log('null', `isUndefined: ${isUndefined(null)} / isEmpty: ${isEmpty(null)}`);
    console.log('undefined', `isUndefined: ${isUndefined(undefined)} / isEmpty: ${isEmpty(undefined)}`);

    console.log('숫자', `isUndefined: ${isUndefined(1234)} / isEmpty: ${isEmpty(1234)}`);
    console.log('문자열', `isUndefined: ${isUndefined('hello')} / isEmpty: ${isEmpty('hello')}`);
    console.log('불린 값: true', `isUndefined: ${isUndefined(true)} / isEmpty: ${isEmpty(true)}`);
    console.log('불린 값: false', `isUndefined: ${isUndefined(false)} / isEmpty: ${isEmpty(false)}`);

 

console.log로 확인 한 값

isUndefined와 isEmpty 비교

 

정리

빈 배열, 오브젝트, 문자열, null 확인: isEmpty

null 확인 : isEmpty (-> ?? (Nullish coalescing operator) 등으로 해결)

undefined 확인: 둘다 값으로 인식 (-> value === undefined 등으로 해결)

숫자 확인: isEmpty는 숫자를 넣으면 비어있다고 인식하는 버그(?)가 있다.

불린 값 확인: isUndefined는 둘다 비어있다고 인식한다. (-> value, !value 등으로 해결)

 


lodash doc: https://lodash.com/docs/4.17.15

+ Recent posts