은닉을 향한 자바스크립트의 여정

클래스 필드 스펙 Stage3까지 올랐다고한다. 곧 Stage4가 표준 스펙이 될거라는데??

타입스크립트 3.8부터 private를 지원, 공부 중에 잠깐 확인한 적이 있었다.

 

  • 표준 스펙이 될 것이다.

    • 스펙이 업데이트될 수 있다.

  • private와 같은 키워드를 사용하지 않고 #을 사용한다.

    • 키워드가 아닌 프리픽스

  • public과 다르게 클래스의 필드 선언을 통해서만 만들 수 있다.

    • 동적으로 객체에 추가할 수 없다.

  • 메서드에는 제한적이며 메서드 선언으로 사용 불가

    • 함수 표현식으로 정의

  • 객체 초기화 구문은 계산된 속성명(computed property name)을 사용할 수 없다.

  • 모든 private 필드는 소속된 클래스에 고유한 스코프를 갖는다.

    • getter 함수를 만들어서 public하게 노출해서 값에 접근 할 수 있다.

    • private를 정의한 클래스를 제외하고 어디에서든 접근이 불가능하다.

 

자바스크립트는 private 속성을 지원하지 않아서 코드를 짤 때 private하게 하기 위해 꼼수를 사용해왔다.

보통 클로저를 통해 캡슐화, 은닉화를 통해 private하게 만들었고,

그렇지 않고서는 언더스코어(_) 프리픽스를 통해 컨벤션으로 이것은 private야라고 해서 쓰기도 했다.


하지만 이게 컨벤션일뿐 모르는 사람이 그냥 외부에서 접근했을때에는 그냥 public이다.

그 후에는 JSDoc을 통해 @private를 표현했다고 한다. 

언더스코어보다 훨씬 명시적이로 문서도 자동화가 되니 자연스럽게 언더스코어의 사용은 줄었고,

글쓴이도 컨벤션에서 제하는것에 찬성했다고 한다. 

나도 글을 보니 사용을 지양하는 것이 좋겠다고 생각했다.

 

원본 글에서 가져온 코드다.
es6를 사용하지 못하는 프로젝트에서 캡슐화 시켜서 private하게 코딩할 때 모듈 패턴을 사용하는데,

이것도 생성자의 인스턴스 컨텍스트별로 private하게 하지 못하기 때문에 도움이 되지 않는다.

function SomeModule() {
  const privateProp = 'dont touch this';
  const publicProp = 'you can touch this';

  _doSomethingWithPrivateProp = () => { ... }

  const publicMethod = () => {
    _doSomethingWithPrivateProp();
    // ...
  }

  return {
    publicProp,
    publicMethod
  }   
}

- 코드 출처 원본 글

 

아래는 symbol에 대해 공부 의지를 불태워 줄 좋은 자료의 코드이다.

es6에서는 더 멋진 꼼수로 private하게 만들 수 있다는 예시라고 하는데, 

(하지만 이제 private를 정식으로 지원한다고 하니까.)

다음에 공부하게 참고해야지.!!

const privateMethodName = Symbol();
const privatePropName = Symbol();

class SomeClass {
  [privatePropName] = 'dont touch this';;
  publicProp = 'you can touch this';

  [privateMethodName]() {
    console.log('private method');
  }

  publicMethod() {
    this[privateMethodName](this[privatePropName]);
  }
}

- 코드 출처 원본 글

 


원본, 코드 출처

https://meetup.toast.com/posts/228

JSON.stringify () 기능

JSON.stringify를 간단히 JSON문자열로 변환할때만 사용할 때 썼었는데, 몰랐던 기능들이 있습니다.

 

 

1. 찾고자하는 키 값을 두번째 인수에 넣어 전달하면 원하는 키의 배열만 리턴받을 수 있다.

{"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"},{"id":"1003","type":"Blueberry"},{"id":"1004","type":"Devil’s Food"}]},"topping":[{"id":"5001","type":"None"},{"id":"5002","type":"Glazed"},{"id":"5005","type":"Sugar"},{"id":"5007","type":"Powdered Sugar"},{"id":"5006","type":"Chocolate with Sprinkles"},{"id":"5003","type":"Chocolate"},{"id":"5004","type":"Maple"}]}

console.log(JSON.stringify(product,['name']);

// RESULT
{"name" : "Cake"}

 

 

2. 두번째 인수에 함수를 넣어 원하는 값을 리턴 받을 수 있다.

undefined일 경우에는 리턴되지 않는다.

const user = {
	"name" : "Prateek Singh",
	"age" : 26
}

JSON.stringfy(user, (key, value) => {     
	if(typeof value == 'string'){
        return undefined;
    }
    return value;
});

// RESULT
{ "age": 26}

 

 

3. 세번째 인수가 '숫자'일 경우 문자열의 간격을 제어할 수 있다.

4. 세번째 인수가 '문자'일 경우 공백 대신 문자를 삽입할 수 있다.

 

 

5. toJson

키값에 따라 객체를 바로 리턴하지 않고 메서드를 통해 원하는 키 값을 합쳐서 반환할 수 있다.

const user = {
	firstName : "Prateek",
    lastName : "Singh",
    age : 26,
    toJSON() {
    	return {
        	fullName: `${this.firstName} + ${this.lastName}`
        };
	}
}

console.log(JSON.stringify(user));

// RESULT
"{ "fullName" : "Prateek Singh"}"

 


원본, 코드 출처

https://medium.com/javascript-in-plain-english/5-secret-features-of-json-stringify-c699340f9f27

 

하루에 1000번 배포하는 조직되기

 

잦은 배포는 많은 비즈니스 충족을 뜻하고 사용자에게 더 많은 가치를 빠르게 전달할 수 있다는 것을 의미하며 
빠른 성장과 높은 가치를 인정받게될 수 있다.
실제로 유명한 스타트업, 테크 기업들은 하루 1000번 이상의 크고 작은 배포가 이루어지고 있다고한다.

 

gitflow

하나의 repository에서 메인테이너들이 동시에 작업할 경우 큰 장점이 있는 모델
총 5가지의 브랜치로 이루어져있다.
- master, release, develop, hotfixes, feature

 

흐름

- develop에서 feature 브랜치를 생성, feature에서 개발 -> develop에 병합
- develop에서 release 브랜치 생성, release에서 배포에 핃요한 문서 작업 혹은 버그 수정 등을 진행
- release 준비가 완료되면 release 브랜치를 master와 develop에 병합

 


잦은 배포에서 더이상 git-flow를 따를 필요가 없다.
브랜치를 생성하고 병합하고의 절차가 너무 많았기 떄문에 복잡한 프로세스를 줄일 필요가 있다고 생각했으며
여러명이 동시 작업 후 배포를 진행했을 경우 특정 기능에 장애가 나면 tag기반으로 롤백할 때 전체를 할 수 밖에 없는 상황이 있었기에 배포 정책을 수정할 필요를 느꼈다고한다.
따라서 최소한의 브랜치를 생성하여 작업을 하게되었다고하는데,
master만이 존재하며 작업 시 master에서 브랜치를 생성 (브랜치 네이밍은 명확히) 후 작업하고 master에 병합
(안전하지 않아보인다면 원본 글을 읽고오세요, 병합 전 절차들이 있습니다.)

 

- 병합할때는 squash and merge 방식을 사용한다고한다.

- 브랜치의 모든 커밋을 squash하여 하나의 커밋으로 만들고 이 브랜치를 병합한다.
- 병합을 요청하는 단위는 배포가능한 단위여야하고 작을 수록 좋다.

- git flow와 가장 큰 차이는 master에 병합될때마다 커밋들을 배포하지 않고 여러 커밋을 모아서 배포
  ㄴ 사이드이펙트나 커뮤니케이션의 비용문제로 빠르게 배포하는 것을 권장
  ㄴ 여러 기차가 정차해 있다가 출발하는 모양과 비슷하다고 해서 commit-Train based deployment라고 한다.

 

그 아래 배포 툴에관한 내용 잘 몰라서 읽고 넘어가자

 


결론은 ... 
하루에 1000번의 배포를 할 수 있는가?
모니터링 툴과 장애 대응 프로세스, 조직의 비즈니스 역량이 있어야 가능하며 판단할 수 있는 지표가 될 수 있다.

 


 

원본 글

https://blog.banksalad.com/tech/become-an-organization-that-deploys-1000-times-a-day/

let, const와 블록 레벨 스코프

ES6부터 let, const를 사용하게 되는데, var와는 여러가지 차이가 있다.

선언은 프로그래밍에서 필수기때문에 var와 let, const차이를 이해하고 넘어가지 않으면 많은 프로그래밍적 오류를 발생시킬수 있다.

 

 

변수 호이스팅 단계

  1. 선언단계(Declaration phase)

    • 변수를 실행시키는 실행 컨텍스트의 변수 객체에 등록, 이 객체는 스코프가 참조하는 대상이됨
  2. 초기화단계(Initialization phase)

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

  3. 할당 단계(Assignment phase)

    • undefined로 초기화 된 변수에 실제 값 할당

 

var

  • var 생략 시 전역변수로 선언

    • 의도하지 않게 선언된 전역변수는 변경이 일어날 확률이 높음

  • 변수 선언 이전에 참조 가능

    • 호이스팅 시 선언 단계에서 초기화 단계까지 한번에 이루어짐

  • 함수레벨 스코프

    • for문내에서 선언한 변수를 for외부에서 참조가능

 

사용이 편리한 var, 스코프가 넓어서 의도치 않은 변경이 생길 수 있고 복잡성이 증가될 수 있다.

때문에 변수의 스코프가 좁을수록 좋으며 불가피한 상황외에는 사용하지 않는것이 좋다.

 

 

let

  • const와 달리 재할당 가능

    • 명시적으로 객체 타입 변수의 주소값을 재할당 해야한다면 let을 사용한다  

  • 블록 레벨 스코프

    • 모든 코드 블록 내에서 코드가 유효, 블록 외부에서 참조할 수 없음

    • 전역 변수에서 사용하는 경우 전역객체의 프로퍼티가 아니다.

      • window.foo 같이 접근 불가

      • 보이지 않는 개념적인 블록내에서 존재

  • var는 같은 네이밍으로 중복 선언할 수 있었지만 let은 불가

  • 선언문 이전에 참조하면 참조에러

    • 스코프 시작부터 변수의 선언까지 일시적 사각지대(Temporal Dead Zone; TDZ)가 생기기때문이다.

    • 호이스팅 시 선언단계와 초기화 단계가 분리되어 진행

      • 선언단계 - 일시적 사각지대(TDZ) - 초기화단계 - 할당 단계

const

  • let과 달리 재할당 금지

    • 상수

    • 객체의 대한 참조를 변경하지 못하지만 객체의 프로퍼티는 보호되지않는다

      • 할당된 객체의 내용(프로퍼티 추가, 삭제, 변경)은 수정될 수 있다

      • 객체의 내용이 변경되더라도 객체 변수의 주소값이 변경되지 않는다.

      • 객체타입에는 const를 사용하는 것이 좋다

      • 만약 명시적으로 객체 타입 변수의 주소값을 재할당 해야한다면 let을 사용한다

  • 선언과 동시에 할당이 이루어져야한다

  • 블록 레벨 스코프(let 참고)

 

ES6 이상에서는 var 키워드를 사용하지 않는다.

let과 const를 사용하며 원시 값(상수)이나 객체에는 가급적 const를 사용한다.

let을 사용할때는 스코프를 최대한 좁게 만든다.

객체의 재할당이 확정되지 않았을 경우 const로 먼저 선언하고 추후 let으로 변경하자

 


참고

let, const와 블록 레벨 스코프

 

참고에 자료로 명시되어있는 사이트

ECMAScript 6

ECMAScript 6 New Features: Overview & Comparison

ES6 compat table

Temporal dead zone and errors with let

Are variables declared with let or const not hoisted in ES6?

 

+ Recent posts