본문 바로가기

컴퓨터 기본 개념

자바스크립트 기본 개념 & Auth0 & 교차기원 & CORS

JavaScript 함수 정의

  • 함수 선언문 (function statement)
  • 함수 표현식 (function expression)
  • Function() 생성자 함수



함수 선언문 방식으로 함수를 생성

// 함수 선언

function add (x, y) { return x + y; }

~~~~~~~~ ~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~

키워드   이름  |     함수 몸체

               +-- 인자, 매개변수, 파라미터

 

// 함수 호출

console.log(add(3, 4));



함수 표현식 방식으로 함수를 생성 ⇒ 함수 리털러로 함수를 만들고, 생성된 함수를 변수에 할당

JavaScript에서는 함수도 하나의 값으로 취급

var x = 1; // x라는 변수에 1을 할당

var y = 2; // y라는 변수에 2를 할당

var z = x;

 

var add = function(x, y) { // add라는 변수에 매개변수로 전달되는 두수를 더한 값을 반환하는 익명함수를 할당

return x + y; 

}; // ⇐ 함수 표현식 방식으로 함수를 생성할 때는 세미콜론을 넣어주는 것을 권장

var sum = add; // 변수처럼 다른 변수에 재할당

console.log(add(3, 4)); // 7

console.log(sum(3, 4)); // 7

 

함수 표현식 

익명 함수 표현식

  • 기명 함수 표현식
    • 함수 표현식에서 사용된 함수 이름은 외부 코드에서 접근이 불가능
    • 함수 내부에서 해당 함수를 재귀적으로 호출할 때 또는 디버깅 할 때 사용

 

var add = function sum(x, y) { return x + y; };


console.log(add(3, 4));     // 7
console.log(sum(3, 4));     // sum is not defined

 

var myFactorial = function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n-1);
}


console.log(myFactorial(5));    // 120
console.log(factorial(5));      // factorial is not defined

 

 



함수 선언문으로 정의한 함수는 외부에서 호출이 가능하도록, 자바스크립트 엔진에 의해서 함수 이름과 함수 변수 이름이 동일한 기명 함수 표현식으로 변경

function add(x, y) { return x + y; }

var add = function add(x, y) { return x + y; }



Function() 생성자 함수를 이용한 함수 생성

Function() 기본 내장 생성자 함수

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function

 

함수 선언문, 함수 표현식 방식도 내부적으로는 Function() 생성자 함수를 이용해서 생성

 

new Function ([arg1[, arg2[, ...argN]],] functionBody)

 

var add = new Function('x', 'y', 'return x + y');
console.log(add(3, 4)); 




함수 호이스팅(function hosting)

함수 선언문 형태로 정의한 함수는 함수의 유효 범위가 코드의 맨 처음부터 시작 

⇒ 함수를 정의한 위치와 관계 없이 호출이 가능

console.log(add(1, 2));     // 3


function add(x, y) { 
    return x + y;
}


console.log(add(3, 4));     // 7

 

함수 호이스팅이 발생하는 원인(이유)

⇒ JavaScript의 변수 생성(instantiation)과 초기화(initialization) 작업이 분리되어 진행되기 때문

 

함수 표현식 방식과 함수 호이스팅 

console.log(x);             // undefine
var x = 2;
console.log(x);             // 2


console.log(y);             // y is not defined

var z;
console.log(z);             // undefined


console.log(add(1, 2));     // add is not a function
var add = function(x, y) { 
    return x + y;
}
console.log(add(3, 4));     // 7



함수 종류

콜백 함수 (callback function)

개발자가 명시적으로 코드를 통해 호출하는 함수가 아니고, 

개발자는 함수를 등록만 하고, 이벤트가 발생했을 때 또는 특정 시점에 도달했을 때 시스템에서 호출하는 함수

 

특정 함수의 인자로 넘겨서 코드 내부에서 호출되는 함수

예) 이벤트 핸들러

 

즉시 실행 함수 (immediate function)

함수를 정의함과 동시에 바로 실행하는 함수

최초 한번의 실행만을 필요로하는 초기화 구문에 사용

함수 리터럴을 괄호로 둘러싼 후 함수가 바로 호출될 수 있도록 괄호를 추가

function add(x, y) {
    console.log(x + y);
}
add(3, 4);      //


(function add(x, y) {
    console.log(x + y);
})(3, 4);


(function (x, y) {
    console.log(x + y);
})(3, 4);


(function add(x, y) {
    console.log(x + y);
}(3, 4));


(function (x, y) {
    console.log(x + y);
}(3, 4));

 

(function() {
    $(document).ready(function() {
        userController.init(configConstants);
    });
}());






함수를 반환하는 함수

var self = function() {
    console.log('a');


    return function() {
        console.log('b');
    };
};


self();         // a
console.log('------------');
self = self();  // a
self();         // b



내부 함수 (inner function)

함수 내부에 정의된 함수

function parent() {
    var a = 100;
    var b = 200;


    function child() {
        var b = 300;

        console.log(a);     // 100
        console.log(b);     // 300
    }


    child();
}


parent();
child();                    // child is not defined

부모 함수에서 내부 함수를 외부로 반환하면, 부모 함수 밖에서도 내부 함수를 호출이 가능

function parent() {
    var a = 100;
    var b = 200;


    return function child() {
        var b = 300;


        console.log(a);     // 100
        console.log(b);     // 300
    };
}


var inner = parent();
inner();                    // 클로져(closure)              
                            // https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures
                            // 실행이 끝난 parent()와 같은 부모 함수 스코프의 변수를 참조하는 함수

 

arguments 객체

function add(x, y) {
    console.dir(arguments);
    return x + y;
}


console.log(add(1, 2));     // 3
console.log(add(1, 2, 3));  // 3    인자 개수가 초과하면 -> 무시
console.log(add(1));        // NaN  인자 개수가 모자라면 -> undefined 값이 할당

 

함수가 호출될 때 파라미터(인자)와 함께 암묵적으로 arguments 객체가 함수 내부로 전달

                                                  함수를 호출할 때 넘긴 파라미터를 배열 형태로 저장한 객체

                                                                                   실제 배열이 아닌 유사 배열 객체         



파라미터의 개수가 정확하게 정해지지 않은 함수를 구현할 때 또는 파라미터의 개수에 따라서 처리를 다르게 구현해야 하는 함수를 정의할 때 사용

function sum() {
    var result = 0;
    for (var i = 0; i < arguments.length; i ++) {
        result += arguments[i];
    }
    return result;
}


console.log(sum(1));                // 1
console.log(sum(1, 2));             // 3
console.log(sum(1, 2, 3, 4, 5));    // 15



함수 호출 패턴과 this 바인딩

자바스크립트에서 함수를 호출하면 파라미터와 함께 arguments 객체와 this 인자가 함수 내부로 암묵적으로 전달

함수가 호출되는 방식(호출 패턴)에 따라 this가 다른 객체를 참조

 

객체의 메서드를 호출할 때 this 바인딩

객체의 메서드 = 객체의 프로퍼티가 함수인 경우 ⇒ 해당 함수를 메서드라고 함

 

메서드 내부 코드에서 사용된 this ⇒ 해당 메서드를 호출한 객체에 바인딩

var myObj = {
    name: 'crpark', 
    sayName: function() {
        console.log(this.name);
    }
};


var otherObj = {
    name: 'other'
};


otherObj.sayName = myObj.sayName;


myObj.sayName();        // crpark
otherObj.sayName();     // other



함수를 호출할 때 this 바인딩

함수 내부 코드에 사용된 this는 전역 객체에 바인딩

브라우저 → windows 객체

node.js  → global 객체

var text = "This is JavaScript";
console.log(text);          // This is JavaScript
console.log(window.text);   // This is JavaScript
console.dir(window);


var say = function() {
    console.log(this);      // Window {window: Window, self: Window, document: document, name: "", location: Location, …}
    console.log(this.text); // This is JavaScript
};
say();

 

  

 

내부 함수의 this도 전역 객체에 바인딩

var value = 100;

var myObject = {
    value: 1,
    func1: function() {
        this.value += 1;
        console.log(`func1() called. this.value = ${this.value}`);          // #1 → 2


        func2 = function() {
            this.value += 1;
            console.log(`func2() called. this.value = ${this.value}`);      // #2 → 101


            func3 = function() {
                this.value += 1;
                console.log(`func3() called. this.value = ${this.value}`);  // #3 → 102
            }
            func3();
        }
        func2();
    }
};
myObject.func1();

 

#1 ⇒ myObject 객체의 메서드 코드에 포함된 this ⇒ 호출한 객체에 바인딩되므로 myObject.value 프로퍼티 값을 증가

#2, #3 ⇒ func1 함수 내부에 정의된 func2 함수와 func2 함수 내부에 정의된 func3 함수 내부 코드에서 사용하는 this ⇒ 글로벌 객체를 참조하므로 글로벌 변수로 정의(var value = 100;)된 값이 증가



#2와 #3에서 사용하는 this를 myObject를 참조하도록 하고 싶을 때는??? ⇒ 객체를 나타내는 this를 값을 가지는 변수 that (단순한 변수 이름)을 정의

var value = 100;

var myObject = {
    value: 1,
    func1: function() {
        var that = this; // var _this = this;
        this.value += 1;    
        console.log(`func1() called. this.value = ${this.value}`);          // 2


        func2 = function() {
            that.value += 1;
            console.log(`func2() called. this.value = ${that.value}`);      // 3


            func3 = function() {
                that.value += 1;
                console.log(`func3() called. this.value = ${that.value}`);  // 4
            }
            func3();
        }
        func2();
    }
};
myObject.func1();

 

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
	console.log(window);		// 글로벌 객체인 window에 jQuery, $ 가 등록된 것을 확인
</script>

 

<script>
    //  HTML 문서가 준비되면 매개변수로 전달된 콜백 함수를 실행
    window.onload = () => {
        console.log("#1");
    };
 
    jQuery(document).ready(function() {
        console.log("#2");
    });
 
    $(document).ready(function() {
        console.log("#3");
    });
 
    jQuery(function() {
        console.log("#4");
    });
 
    $(function() {
        console.log("#5");
    });
    
</script>

 

var x = true;

 

x == true ⇒ true

x == false ⇒ false



var x;

 

x == true ⇒ false

x == false ⇒ false

 

x = !x; ⇒ x == true

 

x == true ⇒ true

x == false ⇒ false

 

x = !!x; ⇒ x가 true이면 x는 true가 되고, x가 false이거나 undefine이면 x는 false가 됨(undefined값이 안들어가게 하기 위해 사용하는 경우 많음)

 

 

storage (저장소)

HTML5 스팩에 추간된 개념

https://developer.mozilla.org/ko/docs/Web/API/Web_Storage_API

    속성명   속성값

        ~~  ~~~~~~~~~~~ 

<button id="auth0-login" class="btn btn-success">Sign in</button>

~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~

 |        속성 = attribute                        태그값 = 요소값

 +-- 태그 = 요소 = element





There was an error fetching the SSO data. This is expected - and not a problem - if the tenant has Seamless SSO enabled. If the tenant doesn't have Seamless SSO enabled, this could simply mean that there was a problem with the network. But, if a "Origin" error has been logged before this warning, please add "http://localhost:8000" to the "Allowed Web Origins" list in the Auth0 dashboard: https://manage.auth0.com/#/applications/eSvyRiLgh8sjcbRtUKA9JrHjNiM7NFIH/settings

auth0 lock 를 통해 로그인(인증)에 성공했을 때 반환되는 값

→ accessToken을 localStorage에 저장

 

로그인한 사용자 정보를 조회할 때 localStorage에 저장된 access token을 authentication 요청 헤더를 통해서 전달

 

사용자 프로필 정보를 반환



auth0.com 인증 내역 확인



잠시 쉬고 14시 50분에 이어서 하겠습니다. 




웹 = 공유

 

교차 기원 요청이 가능

 

orgin = 기원 = 출처

⇒ 스킴(프로토콜) + 호스트명 + 포트번호

 

http://www.example.com:8888/abc.html

http://www.sample.com:8080/xyz.html  ⇒ 기원이 다르다.

~~~~   ~~~~~~~~~~~~~~ ~~~~





HTTP 요청은 기본적으로 교차 기원 요청이 가능

<html>
    <head></head>
    <body>
        <img src="https://s.pstatic.net/shopping.phinf/20201015_8/65c73d10-71c2-4c20-a416-ed94184f1456.jpg?type=f214_292" />
        <img src="tile.png" />


        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
        <script src="https://pm.pstatic.net/dist/lib/search.jindo.20200326.js?o=www"></script>
    </body>
</html>

 

⇒ 기원이 다른 js 파일과 이미지 파일이 서비스(스크립트 파일은 다운로드되어서 실행되고, 이미지 파일은 다운로드되어서 화면에 출력)

 

http://127.0.0.1:8000/

https://s.pstatic.net

//ajax.googleapis.com

https://pm.pstatic.net

 

스크립트 내에서의 교차 기원 요청은 보안 상의 이유로 제한 ⇒ ajax = XMLHttpRequest 객체를 이용한 비동기 통신

⇒ SOP(Same Origin Policy: 동일 기원 정책, 동일 출처 정책) 

 

⇒ XMLHttpRequest 객체을 사용해서 가져오는 리소스는 해당 웹 애플리케이션과 동일 기원으로 제한

 

<html>
    <head></head>
    <body>
        <img src="https://s.pstatic.net/shopping.phinf/20201015_8/65c73d10-71c2-4c20-a416-ed94184f1456.jpg?type=f214_292" />
        <img src="tile.png" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

    


        <script>
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    console.log(xhttp.responseText);
                }
            };
            xhttp.open("GET", "https://pm.pstatic.net/dist/lib/search.jindo.20200326.js?o=www", true);
            xhttp.send();
        </script>
    </body>
</html>

 




CORS(Cross Origin Resource Sharing: 교차 기원 자원 공유)

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

 

= SOP 완화 정책

= 브라우저가 XMLHttpRequest로 교차 기원 원청이 가능하도록 해 주는 것

= Access-Control-Allow-Orgin 응답 헤더를 이용해서 자원 사용 여부를 허가