[작성자:] 수수께끼

  • [VIM] VIM 명령어

    [VIM] VIM 명령어

    VIM 명령어 정리

    vi 실행

    명령어동작
    # vi filefile을 연다.
    # vi file1 file2file1 과 file2 를 차례로 연다.
    # view filefile을 읽기 모드로 연다.
    # vi -R filefile을 읽기 모드로 연다.
    # vi + filefile을 열때 커서가 file 본문의 마지막 행에 위치한다.
    # vi +n filefile을 열어 n행에 위치한다.
    # vi -r file손상된 파일 회복

    입력모드 전환

    명령어동작
    # i커서 있는데서 입력모드 전환
    # I커서 왼쪽, 행의 처음에 몬자 삽입
    # a커서 있는 줄 끝에서 입력모드 전환
    # A커서 오른쪽, 행의 끝에 문자 삽입
    # o커서 있는 줄 아래에 빈 줄 삽입
    # O커서 있는 줄 위에 빈 줄을 삽입
    # R덮어쓰기 모드로 전환

    커서 이동

    명령어동작
    # ^, 0줄의 처음으로 이동
    # $줄의 끝으로 이동
    # H화면 맨 위로 이동
    # M화면의 중간으로 이동
    # L화면 맨 아래로 이동
    # w다음 단어 끝으로 커서 이동
    # e다음 단어 앞으로 커서 이동
    # b이전 단어로 이동
    # shift + ↑한 페이지 앞으로 이동
    # shift + ↓한 페이지 뒤로 이동
    # 3l, 3G현재 커서 위치한 행에서 3번째 행으로 이동
    # ctrl + i한 화면 위로 이동
    # ctrl + b한 화면 아래로 이동
    # ctrl + d반 화면 위로 이동
    # ctrl + u반 화면 아래로 이동
    # ctrl + e한 줄씩 위로 이동
    # ctrl + y한 줄씩 아래로 이동

    삭제

    명령어동작
    # x한 문자 삭제
    # 5x커서가 있는 위치부터 5개의 문자를 삭제
    # d + ↑커서있는 줄, 윗줄 2줄 삭제
    # d + ↓커서잇는 줄, 아래줄 2줄 삭제
    # dw한 단어 삭제
    # dd한 줄 삭제
    # 5dd커서가 있는 라인부터 5개의 라인 삭제
    # db커서의 위치에서 거꾸로 한 단어 삭제
    # D한줄 내에서 커서있는 뒤 모두 삭제
    # u바로 전에 수행한 명령을 취소
    # :5,10 d5~10번째 행 삭제

    복사와 붙여넣기

    명령어동작
    # yy현재 줄을 버퍼로 복사
    # p버퍼에 있는 내용을 커서 뒤에 삽입
    # P버퍼에 있는 내용을 커서 앞에 삽입
    # 3y현재 줄에서부터 아래로 3줄 복사
    # :5, 10y5~10줄을 버퍼로 복사
    # :30pu30행에 버퍼 내용을 삽입
    # d현재 커서가 위치해 있는 단어 복사
    # 3yy현재 행을 기준으로 3번째 행까지 n행 복사

    문자열 찾기

    명령어동작
    # /namename 문자열 찾기
    # n다음 name으로 이동
    # Nn과 같으며 역방향으로 이동

    문자열 대체

    명령어동작
    # :s/str/rep현재 행의 str을 rep로 대체
    # :l,.s/str/rep/1부터 현재 행의 str을 rep로 대체
    # :%s/str/rep/g파일 전체 str을 rep로 전부 대체
    # :.$/aaa/bbb커서의 위치로부터 파일의 끝까지 있는 모든 aaa를 bbb로 대체

    파일 저장 및 불러오기

    명령어동작
    # :w지정된 파일에 저장
    # :wq, :x, ZZ지정된 파일에 저장하고 vi를 종료
    # :w php.iniphp.ini 파일에 저장
    # :q저장하지 않고 종료
    # :q!저장하지 않고 강제 종료
    # :wq php.iniphp.ini에 저장하고 vi를 종료
    # :r php.iniphp.ini의 내용을 현재 커서가 있는데로 불러온다.
    # :e php.ini현재의 화면을 지우고 새로운 파일 php.ini를 불러온다.
    # :5,10 w php.ini5~10 줄까지의 내용을 php.ini에 저장

    기타

    명령어동작
    # :set nu행 번호 보여주기
    # :set nonu행 번호 보여주기 취소
    # .바로 전에 실행한 명령어 재 실행
    # ctrl + l불필요한 화면 정리후 다시 표시

    References

    Linux 문서편집기 vi, vim 명령어 정리

  • [Jekyll] 깃허브 블로그(Jekyll) SEO 세팅

    [Jekyll] 깃허브 블로그(Jekyll) SEO 세팅

    검색 엔진 최적화(Search Engine Optimization)

    검색엔진이 이해하기 쉽도록 홈페이지 구조를 설정하여 포털 사이트 상위에 노출시키는 작업이다. jekyll으로 제작된 깃허브 블로그에 SEO 작업을 진행하겠다.

    Sitemap

    • 웹 크롤링 로봇이 이용할 수 있는 웹사이트의 접근 가능한 페이지의 목록
    • 사이트맵을 등록하면 구글에서 주기적으로 크롤링을 한 뒤 관련 검색어로 검색 시 해당 사이트가 노출이 된다.
    • sitemap.xml 파일을 사용하면 사이트 구조를 구글, 네이버, 다음 등 검색엔진에 손 쉽게 제출할 수 있다.
    • 검색엔진에 크롤링해야하는 URL을 알려줌으로써 색인을 생성하는 방법과 색인을 생성하는 방법을 제어한다.

    Sitemap.xml 생성하기

    sitemap.xml 파일을 만들고 root 경로 넣어준다.

    • 해당 파일을 커밋, 푸쉬 한다.
      블로그 주소/sitemap.xml 에 들어가서 제대로 사이트맵이 등록되었는지 확인해 보자
    • 홈페이지의 모든글의 정보를 담고있는 사이트맵이 출력되는 것을 알 수 있다. 추후에 블로그 포스팅을 푸쉬 하면 jekyll이 빌드하면서 사이트맵도 자동으로 갱신된다.
    • 사이트 맵에서 특정글의 정보를 변경하고 싶으면 아래와 같이 특정 글의 설정 값을 변경해 주면 된다. changefreq를 너무 짧게 하면 빈번한 접속으로 안좋은 영향을 미칠수 있다고 한다. 설정이 없을때 default 값은 사이트맵에 정의되어 있다.
    layout: post
    title: "제목"
    date: 0000-00-00 12:00:00 
    lastmod : 0000-00-00 12:00:00
    sitemap :
      changefreq : daily
      priority : 1.0
    ---
    
    • 참고로 /sitemap.xml을 실행했을 때 제대로 안나오는 경우가 있는데, 주소 링크에 특수문자가 들어간 경우이다. 깃허브 블로그의 경우 포스팅 파일명으로 링크가 생성되므로 포스팅 파일명은 특수문자 및 한글 사용을 안하도록 한다.

    RSS

    • RSS(Rich Site Summary)란 뉴스나 블로그 사이트에서 주로 사용하는 콘텐츠 표현 방식이며, 웹 사이트 관리자는 RSS 형식으로 웹 사이트 내용을 보여 준다.
    • RSS피드는 정기적으로 업데이트 되는 웹 콘텐츠를 전달해 주는 형태이며, 글의 전체 혹은 요약된 정보와 작성자 등의 정보가 포함되어 있다. 즉 블로그의 글을 작성하면 RSS피드에도 전달이 되고, 구글, 네이버, 다음 등을 통해 글을 검색하면, 검색 엔진은 블로그의 RSS피드로부터 글을 받게 되어 해당 블로그로 들어오게 된다.

    RSS feed.xml 생성하기

    • 사이트맵과 동일하게 feed.xml 파일을 만들고 root 경로에 넣어준다.
    • 해당 파일을 커밋, 푸쉬 하고 블로그 주소/feed.xml 에 제대로 등록되었는지 확인해 보자.

    robots.txt

    robots.txt는 로봇 배제 표준을 따르는 일반 텍스트 파일이다. 쉽게 표현하면 검색 엔진이 해당 사이트의 콘텐츠를 가져가도 허락하는 부분과 가져가면 안된다 라는 설정을 하는 부분이라고 보면 된다. 위와 동일하게 root 경로에 위치한다.

    robots.txt 생성

    • robots.txt 파일을 만들고 아래와 같이 입력한다.
    User-agent: *
    Allow: /
    
    Sitemap: https://recordboy.github.io/sitemap.xml
    
    • User-agent는 허용할 검색엔진 명을 넣게 된다. 따로 설정하지 않으면(*) 모든 검색엔진을 허용하게 된다. Sitemap은 본인 블로그 사이트맵 주소를 넣어 주면 된다.

    블로그 등록

    본인 블로그를 등록 해야 구글 및 네이버에서 검색이 가능하다.

    Google Search Console

    • Google Search Console에 접속한다. SEARCH CONSOLE 버튼을 클릭한다.
    • 속성 유형 선택화면이 나오면 URL 접두어 방식을 선택 후 해당 블로그 주소를 등록한다.
    • 메타 태그를 이용한 사이트 소유권을 확인한 뒤 사이트맵을 등록해주면 된다. (여기에 설명이 참 잘 되어있다.) 구글 애널리틱스에 같은 계정으로 가입이 되어있으면 자동으로 소유 확인이 된다.
    • 네이버 웹마스터 도구에 접속한다.
    • 로그인하고 블로그 주소를 등록해 사이트를 추가해 준다.
    • 웹마스터 도구에서 제공하는 html 파일을 다운받아 본인 블로그에 업로드하거나 메타태그를 이용하는 방법으로 사이트 소유권을 확인한다.
    • 왼쪽 요청 메뉴로 들어가 사이트맵을 제출해준다.
    • 깃허브에서 공식적으로 지원하는 jekyll블로그는 RSS2.0이 아닌, ATOM이라는 방식으로 feed.xml을 생산해준다. 그리고 ATOM방식으로 제작된 피드는 네이버 웹마스터도구에 등록이 안된다.

    References

    github blog를 google에서 검색되도록 설정하기
    구글(Google) 검색에 내 사이트 등록하기
    홈페이지 검색 잘 되도록 만들기
    RSS피드란?
    robots.txt 파일 만들기

  • [CentOS] CentOS7 깃 설치 및 로컬 세팅

    [CentOS] CentOS7 깃 설치 및 로컬 세팅

    초기 설치 환경

    서버

    • Centos7
    • Nginx
    • MySQL5.7
    • PHP7.1

    로컬

    • Homestead

    Git 설치

    원격 저장소 만들고 ssh 접속하여 root권한으로 변경

    # su root
    

    yum을 이용해서 git 설치

    # yum install git-core
    

    yum을 이용해서 git 설치

    # yum install git-core
    

    설치된 영카트 디렉토리로 이동

    # cd /data/web_htdocs/
    

    깃 초기화

    # git init
    

    파일 상태를 확인해 깃이 잘 설치되어 있는지 확인

    # git status
    

    전역 사용자 등록(원격 저장소에 있는 아이디와 메일이 일치하도록 설정)

    # git config --global user.name "사용자 이름"
    # git config --global user.email "사용자 메일"
    

    원격 저장소 url을 복사하여 git에 연동

    # git remote add origin `원격 저장소 url`
    

    로컬 소스트리 클론

    원격 저장소 url 복사

    # git remote add origin `원격 저장소 url`
    

    설치할 디렉토리 경로 맞춘 뒤 클론

    # git remote add origin `원격 저장소 url`
    

    로컬 세팅

    Homestead.ymal 파일 열고 site 부분에

    map: 로컬 도메인 주소
    to: vagrant 경로 추가
    
    $ vagrant reload --provision
    $ sudo service nginx restart
    // (nginx 백업 필수 설정 다시 해줄것!)
    

    host 파일에 로컬주소 추가(관리자권한으로 실행)
    C:\windows\system32\drivers\etc

    실서버 디비 백업

    $ mysqldump -p db명 > 저장할 파일이름.sql
    

    해당 파일 찾아서 local DB인 Homestead에 넣어주기
    symlink(): Protocol error 에러 뜰경우

    Git Bash 를 관리자 권한으로 실행 후

    $ php artisan storage:link
    

    또는 관리자 권한으로 실행 후

    $ vagrant up
    

    한 다음 새로고침 해볼것

    배포 해보기

    로컬에서 소스 수정 후 commit, push 하고 쉘 접속하여 수정 부분 받기

    $ cd /data/web_htdocs/
    $ git pull
    

    error cannot open .git/fetch_head permission denied 에러 날경우 .git 파일의 권한이 root 여서 오류남, 일반 계정으로 변경 해야함, 루트 계정으로 접속

    $ su root
    Password: 패스워드 입력
    chown -R webapp:webapp /data/web_htdocs/.git
    ls -al 해당 파일 변경해준 권한인지 확인
    exit
    

    다시 git pull, 그래도 안된다면

    $ git pull origin master
    

    또는

    $ git branch --set-upstream-to=origin/master master
    $ git pull
    
  • [Linux] 리눅스 MySQL 시작, 정지, 재시작, 상태확인

    [Linux] 리눅스 MySQL 시작, 정지, 재시작, 상태확인

    리눅스 MySQL 시작, 정지, 재시작, 상태확인

    작업우분투 명령어CentOS6 명령어CentOS7 명령어
    시작# service mysql start# service mysqld start# systemctl start mysqld
    정지# service mysql stop# service mysqld stop# systemctl stop mysqld
    재시작# service mysql restart# service mysqld restart# systemctl restart mysqld
    상태확인# service mysql status# service mysqld status# systemctl status mysqld

    References

    리눅스 MySQL 시작, 정지, 재시작, 상태확인

  • [Nginx] Nginx 명령어

    [Nginx] Nginx 명령어

    명령어동작
    # systemctl status nginx상태 확인
    # sudo systemctl stop nginx웹서버 정지
    # sudo systemctl start nginx웹서버 재시작
    # sudo systemctl reload nginx설정 리로드
  • [Terminal] 맥 터미널 쉘 접속

    [Terminal] 맥 터미널 쉘 접속

    윈도우에서는 Putty라는 프로그램으로 ssh접속을 하였지만 맥에서는 터미널로 바로 접속이 가능하다.

    $ ssh [ID]@[HOST]
    

    예를들어 webapp이 아이디이고 127.0.0.1가 호스트 번호 라면

    $ ssh webapp@127.0.0.1
    

    라고 입력한 뒤 패스워드를 입력하면 된다.

  • [JavaScript] 자바스크립트 싱글톤 패턴

    [JavaScript] 자바스크립트 싱글톤 패턴

    전체 시스템에서 하나의 인스턴스만 존재하도록 보장하는 객체 생성패턴을 의미한다. 대표적으로 $를 활용해서 DOM을 조작하고 이벤트도 다루는 jQuery가 있으며, 객체 리터럴도 싱글톤 패턴이라고 할수 있다.(자바스크립트에서 객체 리터럴로 생성한 객체는 다른 객체와 같을 수 없다. 객체 내부의 내용이 같더라도 참조하는 객체가 다르기 때문이다.) 객체 리터럴은 한계가 있는데 비공개 프로퍼티 및 함수를 선언할 수 없다.

    var obj = {
        name: 'myName',
        get: function() {
            return this.name;
        }
    }
    console.log(obj.get()); // myName
    

    비공개 프로퍼티 및 함수를 정의하려면 클로저(closure)를 활용해야 한다. 즉 제대로 된 싱글톤 패턴은 객체 리터럴 + 클로저의 조합이 필요하다고 할 수 있다. 아래 코드를 확인해보면

    var singleton = (function() {
    
        // 비공개 프로퍼티 정의
        var instance;
    
        // 비공개 메서드 정의
        function init() {
    
            // singleton 인스턴스 정의
            return {
    
                // 공개 프로퍼티 정의
                prop: 'value',
    
                // 공개 메서드 정의
                method: function() {
                    return 'hello'
                }
    
            };
    
        }
    
        // 공개 메서드인 getInstance를 정의한 객체, 비공개 프로퍼티 및 메서드에 접근 가능(클로저)
        return {
    
            getInstance: function() {
    
                // 인스턴스가 선언이 안되있는경우 인스턴스 생성
                if (!instance) {
                    instance = init();
                }
    
                // 인스턴스가 선언이 되있는 경우 인스턴스 반환
                return instance;
    
            }
        }
    })()
    
    var singleton1 = singleton.getInstance();
    console.log(singleton1.method());
    var singleton2 = singleton.getInstance();
    console.log(singleton1 === singleton2); // true
    

    위 코드는 비공개 메서드인 init()의 return문에서 객체 리터럴로 정의되는 인스턴스가 싱글톤 객체이며, 전체 시스템에서 하나만 존재하게 된다. 순서대로 보면 익명함수의 return문에는 싱글톤 객체를 구하는 공개 메서드(getInstance)를 포함한 객체를 반환하며, getInstance메서드는 instance값을 확인해 인스턴스가 선언이 안되있는 경우 비공개 메서드인 init를 호출하여 singleton인스턴스를 생성하여 instance에 할당하게 된다.

    이렇게 일반적으로 싱글톤 패턴에서는 이미 객체가 생성되었는지 여부를 알려주는 instance와 같은 내부 변수가 필요하다. 그리고 싱글톤 패턴에서는 내부 변수에 접근할 수 있는 객체를 반환하는 클로저를 이용해야 한다.

    정리를 하면 내부의 getInstance메서드에서 비공개 프로퍼티인 instance에 접근할 수 있다는 것과, getInstance메서드의 호출이 끝나더라도 instance의 값은 계속 유지되는 특성(클로저)를 이용해 prop, method()이 포함된 객체를 유일하게 생성하게 된다. 그래서 singleton.getInstance()를 몇번이나 호출하더라도 얻는 객체는 모두 동일한 싱글톤 객체를 가리키게 된다.

    References

    싱글톤(singleton) 패턴

  • [JavaScript] 자바스크립트 모듈 패턴

    [JavaScript] 자바스크립트 모듈 패턴

    모듈 패턴이란?

    모듈이란 전제 어플리케이션의 일부를 독립된 코드로 분리하여 만들어 놓은 것이다.

    모듈화를 했을 때 장점

    • 자주 사용되는 코드를 별도의 파일로 만들어서 필요할 때마다 활용할 수 있다.
    • 코드를 개선하면 이를 사용하고 있는 모든 애플리케이션의 동작이 개선된다.
    • 코드 수정 시에 필요한 로직을 빠르게 찾을 수 있다.
    • 필요한 로직만을 로드해서 메모리의 낭비를 줄일 수 있다.
    • 한번 다운로드된 모듈은 웹브라우저에 의해서 저장되기 때문에 동일한 로직을 로드할 때 시간과 네트워크 트래픽을 절약할 수 있다.(브라우저에서만 해당)

    객체 리터럴을 사용한 모듈 패턴

    자바스크립트에서 모듈을 구현하는 가장 쉬운 방법은 객체 리터럴을 사용하는 방법이다.

    var module = {
        key: 'data',
        publicMethod: function() {
            return this.key;
        }
    }
    
    console.log(module.key); // data
    console.log(module.publicMethod()); // data
    

    객체 리터럴은 모듈 패턴이기도 하며, 하나의 객체라는 점에서 싱글톤 패턴이라고도 할 수 있다. 동일한 코드를 어떠한 관점에서 보느냐에 따라 다양한 패턴이 될 수 있다. 객체 리터럴은 간단하지만 모든 속성이 공개되어있다는 단점이 있다. 독립된 모듈은 자체적으로 필요한 내부 변수 및 내부 함수를 모두 갖고 있어야 하므로 클로저를 이용해야 한다.

    아래는 클로저를 활용한 모듈패턴이다.

    클로저를 활용한 모듈 패턴

    var module = (function() {
    
        /**
            * -----------------------
            * 모듈 패턴을 구현할 클로저 코드
            * -----------------------
            */
    
        // 은닉될 멤버 정의
        var privateKey = 0;
        function privateMethod() {
            return privateKey++;
        }
    
        // 공개될 멤버(특권 메서드) 정의
        return {
            publicKey: privateKey,
            publicMethod: function() {
                return privateMethod();
            }
        }
    
    })();
    
    console.log(module.publicMethod()); // 0
    console.log(module.publicMethod()); // 1
    

    모듈 패턴의 반환값은 함수가 아닌 객체이다. 위의 코드를 순서대로 보면 익명함수가 자동으로 실행되고 반환된 객체를 module 변수에 할당한다. 따라서 module.publicMethod()처럼 메서드를 호출할 수 있다. 자동 호출되는점을 제외하고 클로저와 유사하다.

    클로저 경우

    function func() {
        var private = 0;
        return function() {
            private++;
            return private;
        }
    }
    var val = func();
    console.log(val()); // 1
    console.log(val()); // 2
    

    그리고 인스턴스를 여러개 만들어 낼 수 있는 구조라는 점에서 싱글톤 패턴과 차이가 있다.

    싱글톤 패턴 경우

    var singleton = (function() {
    
        var instance;
        var private = 0;
        function init() {
            return {
                publicKey: private,
                publicMethod: function() {
                    return publicKey;
                }
            }
        }
        return function() {
    
            // 싱글톤 패턴은 아래 조건문에서 처음 인스턴스가 선언되면 다시 인스턴스를 만들지 않고 기존의 인스턴스를 리턴한다.
            if (!instance) {
                instance = init();
            }
            return instance;
        }
    })()
    
    var singleton1 = singleton();
    var singleton2 = singleton();
    console.log(singleton1 === singleton2); // true
    

    하나의 인스턴스를 선언하지 않고 여러개의 인스턴스를 생성하려면 익명함수를 사용하지 않고 생성자 함수 방식으로 만들면 된다.

    var Module = function() {
    
        var privateKey = 0;
        function privateMethod() {
            return privateKey++;
        }
    
        return {
            publicKey: privateKey,
            publicMethod: function() {
                return privateMethod();
            }
        }
    
    }
    
    var obj1 = Module();
    console.log(obj1.publicMethod()); // 1
    console.log(obj1.publicMethod()); // 2
    
    var obj2 = Module();
    console.log(obj2.publicMethod()); // 1
    console.log(obj2.publicMethod()); // 2
    

    위처럼 Module 함수를 정의하여 함수를 호출하면 여러개의 인스턴스를 생성할 수 있다. 클로저 인스턴스와 유사하지만, 한가지 차이점은 내부의 익명함수에서 반환값이 함수가 아니라 객체를 반환한다는 점이다.

    모듈 패턴과 네임 스페이스 패턴을 함께 사용하면 더욱 깔끔한 코드가 완성된다.

    var app = app || {};
    app.module = (function() {
    
        var privateKey = 0;
        function privateMethod() {
            return privateKey++;
        }
    
        return {
            publicKey: privateKey,
            publicMethod: function() {
                return privateMethod();
            }
        }
    })();
    
    console.log(app.module.publicMethod()); // 0
    console.log(app.module.publicMethod()); // 1
    

    References

    module pattern (모듈패턴) #1
    [JS_Design Pattern] 2. 모듈 패턴 (Module Pattern)

  • [JavaScript] 자바스크립트 클로저

    [JavaScript] 자바스크립트 클로저

    정의

    중첩함수에서 내부함수가 외부함수의 환경을 기억하는것을 클로저라고 한다.

    function func() {
        var foo = 'data';
        return function() {
            return foo;
        }
    }
    

    func라는 함수를 선언하고 foo변수에 ‘data’문자열을 추가한 뒤 foo변수를 리턴하는 익명함수를 선언하였다.

    var closure = func();
    console.log(closure());
    // 'data'
    

    func함수의 리턴값을 closure변수에 할당한 뒤 closure를 실행한 값을 콘솔로 찍어보았다. 결과는 ‘data’라는 문자열이 출력되었다. func의 지역변수로 있는 foo는 func함수가 끝나면서 소멸되어야하지만 값을 잃지 않고 ‘data’값을 가지고 있다. 이 현상을 클로저라 한다. 다른 구문도 살펴보겠다.

    function count() {
        var num = 0;
        return function() {
            num++;
            return num;
        }
    }
    
    var closure = count();
    console.log(closure());
    console.log(closure());
    console.log(closure());
    // 1
    // 2
    // 3
    

    count함수의 지역변수인 num값이 소멸되지 않고 계속 카운트되는 것을 확인해 볼 수 있다.

    특징

    변수의 은닉화

    자바스크립트에서는 인스턴스를 생성할때 Private Variables에 대한 접근 권한 문제가 있다.

    function Create(name) {
        this._name = name;
    }
    
    var obj = new Create('민수');
    console.log(obj._name);
    // 민수
    

    위에서 생성된 obj객체의 _name프로퍼티는 변수명 앞에 _를 포함하였기 때문에 Private Variables로 쓰고싶다는 의도를 알 수 있다. 하지만 _name프로퍼티는 동적으로 변경될 수 있다.

    obj._name = '인성';
    console.log(obj._name);
    // 인성
    

    이 경우 클로저를 사용하여 외부에서 내부변수에 접근하는것을 제한할 수 있다.

    function create(name) {
        var _name = name;
        return function() {
            console.log(_name);
        }
    }
    
    var hello = create('민수');
    hello();
    // 민수
    

    여기서는 외부에서 _name에 접근할 방법이 전혀 없다. 이렇게 클로저를 활용하여 은닉화를 해결할 수 있다.

    고유한 환경

    클로저는 고유한 환경을 가지고 있다.

    function func(name) {
        var txt = name;
        return function() {
            return txt;
        }
    }
    
    var closure01 = func('민수');
    var closure02 = func('인성');
    var closure03 = func('한나');
    
    console.log(closure01()) // 민수
    console.log(closure02()) // 인성
    console.log(closure03()) // 한나
    

    위의 구문을 보면 txt변수가 동적으로 변화하는 것처럼 보이지만, 실제로는 txt변수 자체가 여러번 생성된 것이다. 즉, closure01(), closure02(), closure03()은 서로 다른 환경을 가지고 있다. 서로 다른 환경을 가지고 있다는것은 그만큼 메모리면에서 큰 비효율을 낳는다.

    function Func(input) {
        this.name = input;
        this.get = function() {
            return this.name;
        }
        this.set = function (rename) {
            this.name = rename;
        }
    }
    
    var obj = new Func('민수');
    console.log(obj.get());
    

    위 코드는 생성자함수를 사용하여 인스턴스를 생성하는 구문인데, 클로저가 두번(get, set)이나 생성되었다. 이 상태에서 인스턴스를 계속 만들면 같은일을 하는 클로저가 중복으로 생성되고 메모리낭비가 심해질 것이다.
    따라서 클로저는 객체의 prototype안에 저장함으로써 같은 기능을 모든 인스턴스가 공유하는 형태로 코드를 만들어야한다.

    function Func(input) {
        this.name = input;
    }
    Func.prototype.get = function() {
        return this.name;
    };
    Func.prototype.set = function(rename) {
        this.name = rename;
    };
    
    var obj = new Func('민수');
    console.log(obj.get());
    

    이렇게 prototype안에 클로저를 넣으면, 인스턴스가 생성되더라도 중복으로 메모리를 낭비하지 않고, 생성자 내부의 prototype안의 클로저를 참조하기 때문에 메모리낭비를 방지할 수 있다.

    정리

    • 클로저는 독립적인(자유) 변수를 가리키는 함수 또는 클로저 안에 정의된 내부함수는 만들어진 환경을 기억한다.
    • 클로저는 외부함수의 스코프 영역에 접근할 수 있고, 그것을 기억하고 있어야 한다.
    • 외부함수가 종료된 후에도 내부함수는 외부함수를 계속 참조하고 있어야 한다.
    • 데이터의 캡슐화 및 정보은닉에도 사용 가능하다.

    References

    JavaScript 클로저(Closure)

  • [Nginx] Nginx 기본 세팅

    [Nginx] Nginx 기본 세팅

    Nginx 설치

    # rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
    # rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
    # yum install nginx.x86_64
    # systemctl start nginx
    # systemctl enable nginx
    

    PHP 설치

    # yum install yum-plugin-replace
    # yum install mod_php71w php71w-common
    # yum install php71w-gd
    # yum install php71w-fpm
    # yum install php71w-opcache
    # yum install php71w-cli
    # yum install php71w-mysqlnd
    # yum install php71w-xml
    # yum install php71w-mbstring
    
    # sed -i 's/;date.timezone =/date.timezone = Asia\/Seoul/g' /etc/php.ini
    
    # yum install -y make automake gcc gcc-c++ kernel-devel openssl-devel php php-devel php-pear bzip2-devel libvpx-devel yum-utils bison re2c libmcrypt-devel libpqxx-devel libxslt-devel pcre-devel libcurl-devel libgsasl-devel openldap-devel libmemcached-devel libjpeg-devel libpng-devel readline-devel
    
    # systemctl start php-fpm
    # systemctl enable php-fpm
    

    nginx.conf 파일찾기

    # sudo find / -name nginx.conf
    

    nginx.conf 수정하기

    # vi /etc/nginx/nginx.conf
    

    nginx 다시 로드 하기

    # sudo service nginx reload