상권's

TIL 11 (2021.10.17) 본문

~2022 작성 글/TIL

TIL 11 (2021.10.17)

라마치 2021. 10. 17. 16:19

해당 블로그에서 스코프에 대해서 학습한 적이 있습니다. 

간단하게 설명하면, 바깥 범위(전역스코프)에서 선언된 변수는 안의 범위(지역스코프)에서도 접근이 가능하지만, 반대로 안의 범위(지역스코프)에서 선언된 변수에는 바깥(전역스코프)에서 접근할 수 없습니다. 

 

전역 변수나 전역 함수를 많이 생성될 경우, 변수 이름, 함수가 겹치는 경우가 발생할 수 있습니다. 여러 사람들과 함께 프로그램을 만들 경우, 겹침으로써 문제가 발생할 수 있습니다.

 

이러한 문제를 해결할 수 있는 방법으로, 전역 변수를 이용하지 않고 함수 안에 넣어서 지역변수로써 이용할 수 있습니다. 아니면 객체 안에 넣어 이용할 수 있습니다.

var obj = {
    name: "sangkwon",
    city: "daegu",
    자기소개 : function() {
        alert(`안녕하세요. 제 이름은 ${this.name} 입니다.`)}
}

obj.name
'sangkwon'

obj.자기소개()

이렇게 객체를 만들게 되면, 접근을 하려면 obj.name, obj.자기소개() 이런 식으로 입력을 해야되기 때문에 obj를 덮어쓰지 않는 이상 변하지 않고, 전역 변수를 줄일 수 있습니다.

 

이러한 방법을 네임스페이싱이라고 할 수 있습니다. 

 

네임스페이싱(namespacing)은 객체나 변수가 겹치지 않는 안전한 소스코드를 만드는 개념입니다. 하지만 JavaScript는 아직까지 네임스페이싱을 위한 기능을 지원하지 않기 때문에 다음의 특성을 통해 네임스페이스와 비슷한 효과를 얻을 수 있습니다.

  • JavaScript의 모든 객체는 프로퍼티를 가집니다.
  • 그 프로퍼티는 다시 다른 객체를 담을 수 있습니다.

네임스페이싱 코딩 기법들을 네임스페이스 패턴(namespace pattern)이라고 합니다.

 

하지만 이러한 방법은

obj.name = 'gildong'

이러한 방식으로 고의적으로 변경을 할 수 있습니다.

 

var whoAmi = function() {
	var name = "sangkwon"
    function 자기소개() {
    	alert(`안녕하세요. 제 이름은 ${name} 입니다.`)
	}
    return {자기소개 : 자기소개()}
}

var doSangkwon = whoAmi()
doSangkwon
{자기소개: ƒ}
doSangkwon()

이처럼 doSangkwon = whoAmi를 할 경우 자기소개:자기소개() 가 저장이 됩니다. 이제 doSangkwon라는 네임스페이스를 통해서 자기소개에 접근할 수 있습니다. name은 접근할 수 없죠. 위처럼 함수로 감싼 후 return을 통해 공개할 변수(자기소개에)만 공개하고 비공개할 변수(name)는 비공개하는 방법을 취할 수 있습니다. 즉, return하는 변수는 공개 변수고, 다른 것은 비공개 변수인거죠.

 

var doSangkwon = (function() {
var name = "sangkwon"
    function 자기소개() {
    	alert(`안녕하세요. 제 이름은 ${name} 입니다.`)
	}
    return {자기소개 : 자기소개()}
})();

간략하게 코드를 구현하면 이렇게 가능합니다.

 

여기서 코드를 구현하자마자 바로 실행하는 것을 IIFE(즉시 호출 함수 표현식)이라고도 하고, 모듈 패턴이라고도 합니다.

 

이러한 모듈패턴은 독립된 함수이며, 자체적인 변수와 함수(비공개변수)를 가지고 있습니다.

var module = (function () {
  //비공개 함수 , 비공개 변수
  var privateVal =0;
  function privateaFunc(){
    return ++privateVal;
  }
  //공개 변수 및 함수 
  return{
    publickFunc(){
      return privateaFunc(); //비공개함수 접근
    }
  }
})();
console.log(module.publickFunc()); // 1
console.log(module.publickFunc()); // 2

이렇게도 이용 할 수 있습니다

 

함수를 function() {}로 선언하면서 동시에 ()를 붙이니까 즉시 실행됩니다. 이 구문이 라이브러리를 만들 때 기본입니다. 많은 라이브러리가 이 구문을 활용하고 있습니다. 비공개 변수가 없는 자바스크립트에 비공개 변수 기능을 만들어주기 때문입니다. 


자바스크립트 싱글턴 패턴이란 ,

1. 하나의 인스턴스

2. 여러개의 인스턴스는 최초의 인스턴스를 사용.

3. 객체에 대한 접근자(비공개 맴버: 클로저)를 이용해서 해당 객체를 공유.

 

싱글턴의 싱글은 혼자의 싱글이 맞습니다. 객체를 만들 때, 하나의 생성자로 여러 객체를 만들 수 있었습니다. 하지만 싱글턴은 필요에 의해 단 하나 객체만을 만들 때 사용합니다 객체 리터럴이 바로 싱글턴 패턴의 대표적인 예입니다. 하지만 일반적으로 만드는 객체의 경우에는, 바깥에서 접근을 할 수 있기 때문에 제대로 된 싱글턴 패턴은 비공개가 되어야 합니다.

var singleton = (function() {
  var instance;
  var a = 'hello'; // 비공개 변수
  function initiate() {
    return {
      a: a,
      b: function() {
        alert(a);
      }
    };
  }
  return {
    getInstance: function() {
      if (!instance) {
        instance = initiate();
      }
      return instance;
    }
  }
})();


var first = singleton.getInstance();
var second = singleton.getInstance();
console.log(first === second); // true;

먼저, IIFE 비공개 변수를 가질 수 있게 만들어줍니다. 그리고 그 안에 instance변수와 initiate 함수를 만들어줍니다. initiate 함수 안의 내용이 실제 객체의 내용입니다.

 

IIFE로 즉시 반환되는 부분(return)을 보게되면,  getInstance라는 메소드를 가진 객체를 반환하는데, getInstance 함수를 호출하는 순간 내부적으로 initiate 함수가 호출되고, instance에 아까 그 객체의 내용이 저장되고 동시에 반환됩니다.

 

getInstance가 여러 번 호출됐을 경우에는 코드를 보시면 이미 instance 객체가 있는 경우에는 initiate를 거치지 않고 바로 반환하는 것을 알 수 있습니다.

 

first와 second 변수를 보면 두 번 다 getInstance 함수를 호출합니다. 결과적으로 두 변수는 같습니다.

 

first 때 initiate된 객체를 second 때도 똑같이 반환받았기 때문입니다. 즉, 아무리 호출해도 기존에 있던 객체는 복사되는 것도 아니고 그냥 그대로 반환됩니다. 싱글턴 패턴은 모듈 패턴을 변형한 디자인 패턴입니다.


원문 1

원문 2

원문 3

원문 4

 

 

 

'~2022 작성 글 > TIL' 카테고리의 다른 글

TIL 13 (2021.10.19)  (0) 2021.10.19
TIL 12 (Redux, sort(), HTTP, 멱등성)(2021.10.18)  (0) 2021.10.18
TIL 10 코드 리뷰 (2021.10.08)  (0) 2021.10.16
TIL 9 (2021.10.15)  (0) 2021.10.15
TIL 8 (2021.10.14)  (0) 2021.10.14
Comments