반응형

클로저 이해하기

클로저의 기본적인 예

 

<script>
    // 클로저의 기본적인 예
    function sum(base) {
        var inClosure = base;

        return function(adder) {
            return inClosure + adder;
        };
    };
    
    var fiveAdder = sum(5); // 5 and return function
    console.log(fiveAdder.toString());
    fiveAdder(3); // inClsure(5) + adder(3) = 8
    var threeAdder = sum(3); // 3 and return function
    console.log(threeAdder.toString());
</script>

 

위 소스에서도 함수 안에 다른 함수를 선언하고 외부에서 내부 함수를 사용하는 클로저의 특징을 확인할 수 있다.

외부에서 sum()함수를 호출하면 파라미터 base를 통해 넘어온 값은 inClosure변수에 저장된다. 그리고 내부 함수에서 inClosure변수를 참조한다.

 

var fiveAdder = sum(5);

 

선언되는 부분부터 보면, var fiveAdder를 통해 sum()함수가 호출되고 sum()함수의 파라미터인 base는 5로 넘어와서 inClsure변수도 5로 설정된다. 그리고 inClosure변수를 참조하는 내부 함수를 반환하여 fiveAdder에 저장한다.

이제부터 fiveAdder를 통해 함수를 호출하게 되면 스코프 체인을 따르게 된다.

그리고 나중에 fiveAdder를 통해 함수를 호출하게 되면 fiverAdder가 레퍼런스를 가지고 스코프 체인을 사용하게 되는 것이다.

 

fiveAdder(3);

 

이제 fiveAdder(3)이 호출되면, 위에 스코프 체인에서 inClosure는 5를 갖고, 내부함수의 파라미터 adder로 들어온 값에 3을 더하여 8이라는 값이 계산된다.

 

var threeAdder = sum(3);

 

다음으로 threeAdder를 호출하면 새로운 스코프 체인을 생성한다.

 

이처럼 같은 함수를 통해 받은 값은 각각의 함수가 생성되어, fiveAdder, threeAdder로 호출하는 스코프 체인이 만들어진다.

 

이처럼 클로저를 통해 각 함수는 자기만의 고유한 값을 보유하고 스코프 체인을 유지하면서 그 체인 안에 있는 모든 변수의 값들을 유지한다.

 

한가지 추가해보면, fiveAdder와 threeAdder변수의 형태는 아래처럼 서로 같다.

 

 

하지만 형태 이외에, fiveAdder !== threeAdder로 두개의 변수는 같지 않다. sum()함수를 호출할 때마다 같은 모양의 함수들이 새롭게 나오지만, 두 함수가 할당받은 스코프 체인, 숨겨져 있는 클로저가 다르기 때문이다.

 

 

다음은 setInterval()함수를 통한 클로저의 발생이다.

<button id="btnToggle">Toggle</button>
<div id="divPending">Pending</div>

<script>
    // setInterval() 함수를 통한 클로저 발생
    (function() {
        var pendingInterval = false,
        div = document.getElementById("divPending"),
        btn = document.getElementById("btnToggle");

        function startPending() {
            if(div.innerHTML.length > 13) {
                div.innerHTML = "Pending";
            }

            div.innerHTML += ".";
        };
        btn.addEventListener("click", function() {
            if(!pendingInterval) {
                pendingInterval = setInterval(startPending, 500);
            } else {
                clearInterval(pendingInterval);
                pendingInterval = false;
            }
        });
    }());
</script>

 

위 소스를 실행하면 아래와 같은 화면이 나온다. Toggle버튼을 클릭하면 “Pending”뒤에 “.”을 하나씩 추가하다가 일정 개수가 넘으면 다시 초기화하는 방식으로 동작한다.

 

Toggle을 클릭했을 때

 

 

var pendingInterval = false,
div = document.getElementById("divPending"),
btn = document.getElementById("btnToggle");

 

위 변수들은 내부에서만 접근 할 수 있도록 private변수로 선언했다. 그리고 startPending()함수 안에 있을 법한 divPending을 가져오는 부분을 상위 스코프에 미리 가져다 놓음으로써, 매번 <div>를 getElementById로 탐색해서 가져오지 않도록 했다.

 

아래는 클로저가 발생한 부분들이다.

 

if(div.innerHTML.length > 13) {
   div.innerHTML = "Pending";
}

 

if문에서 상위 스코프 div변수를 참조하는 부분과

 

pendingInterval = setInterval(startPending, 500);

 

setInterval()함수에서 첫번째 인자로 startPending함수를 사용하는 부분이다.

이런 경우를 보면, 함수 안에 함수가 있어서 내부에 있는 함수가 반환되지 않고 이벤트 콜백함수로 호출될 때도 클로저가 발생하는 것을 알 수 있다.

 

 

반응형
반응형

뷰(View) : 가상의 테이블

:: 실제 행 데이터를 가지고 있지 않는다.

( 실체는 없고, 진짜 테이블에 링크된 개념이다. )

 

뷰 생성하기 ( 회원 이름과 주소만 존재하는 뷰 )

 

CREATE VIEW uv_memberTBL AS SELECT memberName, memberAddress FROM memberTBL;

 

SELECT = 뷰에 접근하게 되면 뷰 생성시에 입력한 SELECT문이 그때 작동한다.

 

SELECT * FROM uv_memberTBL;

 

이런식으로 만들어두면 중요한 정보만 빼고 바꿔야 하는 정보만 보여줄 수 있다.

:: 주민번호나 핸드폰번호처럼 예민한 정보를 같이 둘리는 없겠지만 만약에 두게 되었을 때, 아무에게나 보여주면 안되기 때문에 이런식으로 바꿔야 하는 정보만 따로 뷰로 생성해서 바꿀 수 있도록 해주면 유용하다.

 

반응형
반응형

5일차 - 푸터 완료

다음 진행 - 오른쪽 사이드바 ( 로그인 부분 )

네이버 클론 Korini

 

반응형

'Figma' 카테고리의 다른 글

[ Figma ] 피그마 네이버 카피  (0) 2022.04.12
[ Figma ] 피그마 네이버 카피  (0) 2022.04.08
[ Figma ] 피그마 네이버 카피  (0) 2022.04.06
[ Figma ] 피그마 네이버 카피  (0) 2022.03.31
[ Figma ] 피그마 네이버 카피  (0) 2022.03.30
반응형

4일차 - 왼쪽 컨텐츠 작업완료, 푸터 작업 시작

 

반응형

'Figma' 카테고리의 다른 글

[ Figma ] 피그마 네이버 카피  (0) 2022.04.08
[ Figma ] 피그마 네이버 카피  (1) 2022.04.07
[ Figma ] 피그마 네이버 카피  (0) 2022.03.31
[ Figma ] 피그마 네이버 카피  (0) 2022.03.30
[ Figma ] 피그마 네이버 카피  (0) 2022.03.28
반응형

인덱스( Index )란 ?

인덱스는 책 제일 뒷부분에 있는 '찾아보기'와 같은 개념이다.

책의 내용 중 특정 단어를 찾고자 할 때 책의 첫 페이지 ~ 마지막 페이지까지 전부 찾아보는 것보다 책 뒷부분에 '찾아보기'를 찾아보고 색인에 나와 있는 페이지로 바로 찾아간느 것이 훨씬 빠르다.

 

MySQL employees 샘플 데이터에서 아래 Mary라는 사람을 조회해 본다.

 

SELECT * FROM indexTBL WHERE first_name = 'Mary';

 

잠시 후 결과가 나오고 오른쪽아래 밑으로 내려보면 Execution Plan(실행 계획)을 확인 할 수 있다.

Full Table Scan(전체 테이블 스캔) : 테이블 전체를 검색했다.

즉, 인덱스를 사용하지 않고 테이블 전체를 검색 했다는 뜻이다. ( 500건을 모두 읽어서 1개의 결과를 찾아냈다. )

:: 현재는 index가 없기 때문에 전체에서 검색할 수 밖에 없다.

 

인덱스 생성하기

 

CREATE INDEX idx_indexTBL_firstname ON indexTBL(first_name);

 

인덱스 생성에 성공하면 아래와 같은 문구가 나온다.

 

다시한번 Mary라는 사람을 조회해 본다.

 

SELECT * FROM indexTBL WHERE first_name = ‘Mary’;

 

인덱스를 만든 후에 검색을 했을 경우에는 Non-Unique Key Lookup이라는 문구가 나온다.

Non-Unique Key Lookup : 인덱스를 사용해서 결괄를 찾아냈다.

:: 아래 작은 글씨로 idx_indexTBL_firstname( 인덱스이름 )이 나타나 있다.

( 간단하게 인덱스를 생성한 후 조회하는 것이 데이터 양에 따라 몇십배 이상 빠를수 있다고 생각하면 된다. )

 

반응형
반응형

클로저(Closure)란 ?

클로저는 특정 함수가 참조하는 변수들이 선언된 렉시컬 스코프(Lexical Scope)는 계속 유지되는데, 그 함수와 스코프를 묶어서 클로저라 한다.

 

:: 렉시컬 스코프(Lexical Scope) : 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정하는 것이다. 중요한 점은 함수의 호출이 아닌 함수의 선언에 따라 결정된다는 점이다.

 

<script>

   var num = 1;
   function a() {
       var num = 10;
       b();
   }
 
   function b() {
       console.log(`num : ${num}`);
   }
 
   a(); // 1
   b(); // 1

</scrip>

 

이렇게 출력되는 이유는 함수의 호출로 상위 스코프가 결정된 것이 아니라 함수의 선언에 따라 상위 스코프가 결정되었기 때문이다. 즉 a, b모두 1을 출력한 것으로 볼 때 b함수가 전역을 가리키고 있다는 것을 알 수 있다.

 

<script>

   var name = 'Hello World'; // 전역변수
 
   function c() {
       var name = 'New World'; // 지역변수
       // secondName()은 내부함수이며, 클로저이다.
       function secondName() {
           // 부모함수에서 선언된 변수를 사용한다.
           console.log(`name : ${name}`); // New World
       }
       secondName();
   }
   
   c();

</script>

 

c();는 지역변수 name, secondName()함수를 생성한다. secondName()함수는 c()안에 정의된 내부 함수이며, c() 함수 내부에서만 사용이 가능하다.

 


 

최종정리

 

<script>
 
   // 클로저의 예
   function outer() {
       var count = 0;
       var inner = function() {
           return ++count;
       };
       return inner;
   }
   var increase = outer();
 
   console.log(increase()); // 1
   console.log(increase()); // 2
 
</script>

 

:: 정리

1. count변수는 outer()함수의 로컬 변수다.따라서 원칙적으로는 outer()함수 내부에서만 접근이 가능하다.

2. outer()함수 내부에 다시 함수를 하나 선언하여 inner변수에 할당했다.

3. inner변수에 할당한 함수는 outer()함수의 로컬 변수인 count에 접근하여 1만큼 증가시키고 이 값을 반환한다.

4. outer()함수의 반환값으로 inner변수를 지정하면서 함수 정의를 마친다.

 

반응형
반응형

 

샘플 데이터

mysqlworkbench 다운로드

 

employees SAMPLE

MySQL WorkBench를 실행한 후 왼쪽 위에 Open a SQL script file in a new query tab을 클릭해서 다운받은 employees를 열어준다.

 

이후 File --> Run SQL Script --> employees.sql을 다시한번 열어준다.

기본스키마를 설정할 필요가 없기 때문에 run을 클릭한다.

 

 

successfully가 뜨면 close를 클릭한다.

 

 

Refresh All을 누르면 employees 스키마가 새로 생성된다.

 

다시한번 왼쪽 위에 Create a new SQL tab for executing queries로 새로운 쿼리창을 열어준다.

 

use employees;

select * from employees;

데이터가 들어오게 된다.

 

CREATE TABLE indexTBL (first_name VARCHAR(14), last_name VARCHAR(16), hire_date DATE);

 

INSERT INTO indexTBL SELECT first_name, last_name, hire_date FROM employees.employees LIMIT 500;

 

본인이 만든 스키마를 활성화 시키고 실행 시키면 indexTBL 테이블이 만들어지면서 안에 데이터가 들어가게 된다.

 

SELECT * FROM indexTBL WHERE first_name = 'Mary';

데이터가 나오면 잘 적용된 것이다.

 

반응형
반응형

각각의 div를 클릭했을 때 어떤 div를 클릭했는지 알려주는 소스

 

문제점

 

<div id="div0">Click0</div>
<div id="div1">Click1</div>
<div id="div2">Click2</div>

<script>

    var len = 3;

    // i는 모두 3이 출력된다.
    for(var i = 0; i < len; i++) {
        document.getElementById("div" + i).addEventListener("click", function() {
            alert("You Clicked div #" + i);
            console.log(i);
        }, false);
    }
    
</script>

 

문제점 : Click0, Click1, Click2중 어떤것을 클릭해도 "You Clicked div #3이 나오는 현상

 

이유 : 9번째줄에 콜백 함수는 5번줄에 선언된 변수에 접근할 수 있는 스코프를 생성하게 된다.

이후 div에 클릭 이벤트가 발생해서 콜백 함수가 호출될 때도 클릭에 설정한 이벤트 핸들러의 콜백 함수는 5번 줄의 변수들에 계속 접근할 수 있는 스코프를 갖게된다.

이것은 for-loop를 통해서 각각 div에 순서대로 클릭 이벤트 핸들러를 부여할 때 i가 0~3까지 증가한 뒤, 이후 for-loop가 끝나고 나서도 계속 유지된다. 따라서 나중에 10번줄의 alert()함수가 호출될 때 변수 i의 값은 이미 for-loop가 끝난 후의 값인 3으로 출력된다.

for-loop가 돌 때는 별도의 스코프가 생성되지 않고 i는 글로벌 스코프에 존재한다.

그러다 addEventListener()로 콜백 함수를 설정할 때 익명 함수가 선언되면서 스코프가 생성되어 스코프 체인을 만들게 된다.

 

function을 이용한 문제해결

 

<div id="div0">Click</div>
<div id="div1">Click</div>
<div id="div2">Click</div>

<script>

    var len = 3;
    
    // function을 이용한 문제해결
    function setDivClick(index) {
        document.getElementById("div" + index).addEventListener("click", function() {
            console.log(index);
            alert("You Clicked div #" + index);
        }, false);
    }

    // var i, len = 3;
    for(var i = 0; i < len; i++) {
        setDivClick(i);
        console.log(i);
    }

</script>

 

closure를 활용한 문제해결

 

<div id="div0">Click</div>
<div id="div1">Click</div>
<div id="div2">Click</div>

<script>

    // closure를 활용한 문제해결
    for(var i = 0; i < len; i++) {
        document.getElementById("div" + i).addEventListener("click", (function(index) {
            return function() {
                alert("You Clicked div#" + index);
            };
        }(i)), false);
    }

</script>

 

반응형
반응형

Mac에서 여러 이유로 기존의 설정을 완전히 삭제한 후 VSCode를 새로 설치하려면 아래 코드를 입력해준다.

 

cd ~/Library/Application\ Support/code

 

실제 VSCode파일의 경로는 ~/Library/Application Support/code지만, 터미널에 입력할 경우 공백 때문에 문제가 될 수있어 위처럼 입력한다.

 

아래 코드를 입력하면 상위로 올라오게 된다. 이후 code폴더를 삭제하면 된다.

 

cd ..

 

마지막으로 아래 코드를 입력해주면 모든 설정이 초기화가 된다.

 

sudo rm -r code
반응형
반응형

설치 플러그인

 

npm i --save @fortawesome/fontawesome-svg-core
npm i --save @fortawesome/free-solid-svg-icons

npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons

// Vue2 ( Vue2로 이용할 때 )
npm i --save @fortawesome/vue-fontawesome

// Vue3 ( Vue3로 이용할 때 )
npm i --save @fortawesome/vue-fontawesome@prerelease

 

main.js

 

import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(fab, far, fas)

const app = createApp(App)

// fa = 변경가능
app.component("fa", FontAwesomeIcon)
app.use(store).use(router).mount('#app')

 

App.vue ( 사용할 페이지 )

 

<fa :icon="['fab', 'html5']" />

 

fontawesome에서 아이콘을 찾아서 넣기만 하면 완료된다.

 

반응형

+ Recent posts