프로젝트에서 이미지 api에서 받아온 이미지 url로

 

이미지 파일 N개 혹은

이미지 파일 1개를 같은 width, height 값으로 N개 분할하여

 

여러개의 이미지

이미지 N개를 1개의 연결된 gif 이미지로 보여주려는 작업요건이 필요했다. 

 

그래서 일단 해당 요건을 테스트 해보기 위해 테스트 소스를 작성해보았다.

 

codepen.io/shlee0882/pen/QWGmJbm

 

이미지 gif 효과 만들기

...

codepen.io

위 소스는 캔버스를 이용해 특정영역을 잡고

이미지 데이터 주소를 획득하여 배열에 넣은 다음

마우스 hover시 이미지 정보가 담긴 배열을 0.5초 간격으로 번갈아 가며 보여주며

마우스 out시는 반복을 멈추는 소스코드이다.

 

그럼 이 코드로 기본검증이 끝났으므로

 

응용하여 gif를 생성하는 라이브러리를 사용하지 않고 (not use gif library)

아래와 같은 움직이는 gif이미지를 생성한 것 같은 착각을 일으키는 코드를 작성할 수 있다.

 

 

 

www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png

 

위 이미지는 구글 웹페이지 메인에 로고이다.

위 이미지의 url이 노출된 상태에서 js에서 해당 이미지url로 image 생성자에 담아 

localhost로 해당 이미지를 조작 및 변경 처리를 시도 하면 아래와 같이

CORS policy: No 'Access-Control-Allow-Origin 오류가 발생한다.

 

 

CORS를 통하지 않고, 다른 origin으로 부터 가져온 이미지를

canvas를 통해 이미지를 자르고 조작 시 
원본데이터가 오염 및 안전하지 않다고 판단하여

js에서 origin exception이 발생한 것이다.

 

developer.mozilla.org/ko/docs/Web/HTML/CORS_enabled_image

 

교차 출처 이미지와 캔버스 허용하기 - HTML: Hypertext Markup Language | MDN

교차 출처 이미지와 캔버스 허용하기 Table of contentsTable of contentsHTML은 이미지 처리를 위해 CORS header를 포함하고 있는 crossorigin 속성을 제공합니다. 이는 요소에서 정의된, 외부 origin으로 부터 가

developer.mozilla.org

 

이러한 문제를 회피하기 위해 image url이 완전히 노출된 데이터를 인코딩 해서 처리해야한다.

 

 

- js에서 base64 encoding으로 변환 후 처리를 시도할 수 있지만 잘 처리가 되지 않을 수 있다.

 

 

- 이럴경우 java에서 base64 encoding으로 변환 후 처리하면 쉽게 해결 할 수 있다.

 

 

인코딩 된 base64 data 값을 화면에서 가져와 img 태그안에 src attribute로 넣어주면 된다.

 

 

 

img 태그는 해당 이미지값을 읽어 다음과 같이 출력해준다.

 

 

인코딩된 값으로 canvas 등을 활용해 CORS policy: No 'Access-Control-Allow-Origin을 회피하여

DOM을 조작할 수 있게 되었다. 


1. 자바스크립트 이용한 pc, 모바일 체크, DOMContentLoaded 이벤트 사용하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<script type="text/javascript">
 
var onresize = function() {
    var width = document.body.clientWidth;
    var height = document.body.clientHeight;
    if(width <= 1575){
        smallMenu();
    }else{
        largeMenu();
    }
};
 
var top_frame01 = document.getElementById('top_frame01');
    
var smallMenu = function(){
    top_frame01.setAttribute( 'rows''120,*' )
};
 
var largeMenu = function(){
    top_frame01.setAttribute( 'rows''90,*' )
};
 
// 모바일, pc 체크
window.mobilecheck = function() {
      var check = false;
      (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m||s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
      return check;
};
 
// DOMContentLoaded
window.addEventListener('DOMContentLoaded'function(){
    if(mobilecheck()){
        console.log('mobile');
        smallMenu();
    }else{
        console.log('pc');
        largeMenu();
    }
});
 
window.addEventListener("resize"onresize);
 
</script>
cs


index.jsp가 화면에 로딩될때 접근한 기기가 PC인지 모바일인지 확인 후 상단의 메뉴 사이즈를 줄여주려고 한다.


처음에 windows.onload = function(){} 을 사용했으나 모든 콘텐츠가 로드된 후 실행되어 스크립트가 늦게 실행되어 화면이 늦게 바뀌는 문제점이 있었다.


그래서 DOMContentLoaded 이벤트를 사용했다.  

DOMContentLoaded는 최초 HTML 문서가 완전히 로드 및 파싱되었을때 발생되고, 

스타일시트나 이미지 및 서브프레임 로드가 끝나기를 기다리지 않는다고 한다.


$(document).ready(function(){}); 은 jquery에서 쓰는 것인데 DOMContentLoaded 이벤트와 동일하다.



JS Event Loop 이벤트 루프







1.

main 함수에 대한 호출은 먼저 스택으로 푸시된다. (프레임으로써 푸시된다) first pushed into the stack 

브라우저는 main 함수의 첫 번째 명령문인 console.log ( 'A') 를 스택으로 푸시한다. main function into the stack which is console.log(‘A’). 

이 문이 실행되고 완료되면 해당 프레임이 튀어 나온다. 알파벳 A가 콘솔에 표시된다.


2.

콜백 exec () 및 0ms 대기 시간이있는 다음 명령문 (setTimeout ())이 호출 스택으로 푸시되고 실행이 시작된다.

setTimeout 함수는 브라우저 API를 사용하여 제공된 함수에 대한 콜백을 지연한다. 

그런 다음 브라우저로의 핸드 오버가 완료되면 (타이머의 경우) 프레임 (setTimeout 포함)이 튀어 나온다.


3.

console.log ( 'C')는 exec () 함수에 대한 콜백을 위해 브라우저에서 타이머가 실행되는 동안 스택에 푸시된다. 

지연이 0ms 였기 때문에 브라우저가 메시지를 받자 마자 (이상적으로) 콜백이 메시지 대기열에 추가된다.


4.

main 함수에서 마지막 명령문을 실행 한 후 main () 프레임이 호출 스택에서 튀어 나와 비어있게 만든다.. 

브라우저가 대기열에서 호출 스택으로 메시지를 푸시하려면 먼저 호출 스택을 비워야한다.

그렇기 때문에 setTimeout ()에 제공된 지연이 0 초라도 exec ()에 대한 콜백은 호출 스택의 

모든 프레임 실행이 완료 될 때까지 대기해야한다.


5.

이제 콜백 exec ()가 호출 스택으로 푸시되고 실행된다. 알파벳 C가 콘솔에 표시된다. 

이것이 자바 스크립트의 이벤트 루프다.



요약


- main 함수 프레임이 호출 stack에서 pop되어 empty 상태여야한다.

- 그러므로 지연시간이 0초라도 스택이 비워져 있어야 한다.

- 스택이 비워지면 실행하게 된다.








setTimeout은 0초를 지연하고 while 루프는 3초 동안 실행 되더라도 exec() 콜백은 메시지 대기열에 고정되어 있다. 

while 루프는 3 초가 경과 할 때까지 호출 스택 (단일 스레드)에서 계속 실행된다.

그리고 호출 스택이 비게되면 콜백 exec()가 호출 스택으로 이동되어 실행된다.

따라서 setTimeout ()의 지연 인수값은 타이머가 지연을 마친 후에 실행 시작을 보장하지 않는다.



  1. 남갯 2019.04.26 14:03 신고

    요즘은 자바스크립트를 공부하고 계시는군요

    • effortDev 2019.04.26 17:36 신고

      네네. 여러가지 공부해보려고 노력하고 있습니다. 포스팅 봐주셔서 감사합니다.


1. IIFE ( Immediately Invoked Function Expressions )



자바스크립트에서 즉시 호출되는 익명 함수 표현식을 말한다.



1.1 일반적으로 함수를 선언하는 방식


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 1. The natural function definition
function sayHi() {
    console.log("Hello, World!");
}
sayHi(); // shows "Hello, World!" as console log in browser.
 
// 2. Function expressions
var msg = "Hello, sanghyun!";
var sayHi2 = function() {
    console.log(msg);
};
sayHi2(); // shows msg as console log in browser.
 
// 3. Named function expressions
var fibo = function fibonacci() {
    // you can use "fibonacci()" here as this funciton expression has a name.
};
// fibonacci() here fails, but fibo() works.
cs


함수를 선언 생성하고 함수명을 호출하는 방식을 사용한다.




1.2 execute once IIFE, void IIIFE, return value IIFE 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 4. That’s a function that died immediately after it came to life.
!function() {
    console.log("Hello from IIFE!");
}();
// Shows the console log "Hello from IIFE!"
 
 
// 5. All the below patterns are useful when we are not interested in the return value from the IIFE.
void function() {
    console.log("void from IIFE!");
}();
 
// 6. IIFEs with a return value
var result = (function() {
    return "return value from IIFE";
}());
console.log(result); // console log "From IIFE"
cs




1.3 일반적인 IIFE의 여러가지 표현방식


1
2
3
4
5
6
7
8
9
10
// 7. Classical IIFE style
// Variation 1
(function() {
    console.log("I am an IIFE!");
}());
 
// Variation 2
(function() {
    console.log("I am an IIFE, too!");
})();
cs




1.4 유효한 IIFE와 무효한 IIFE


1
2
3
4
5
6
7
8
9
10
11
12
13
// 8. Valid IIFE
(function initGameIIFE() {
    // All your magical code to initalize the game!
    console.log("initGameIIFE");
}());
 
// 9. invalid IIFE
function nonWorkingIIFE() {
}();
 
function () {
    // You will get a syntax error here as well!
}();
cs


선언한 함수 전체를 감싸지 않는다면 무효하다.




1.5 IIFE 안의 내부함수와 내부변수의 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 10. IIFEs and private variables
(function IIFE_initGame() {
    // Private variables that no one has access to outside this IIFE
    var lives;
    var weapons;
    
    init();
    console.log(lives);
    console.log(weapons);
    
    // Private function that no one has access to outside this IIFE
    function init() {
        lives = 5;
        weapons = 10;
    }
}());
cs




1.6 IIFE에 파라미터를 넘겨 호출


1
2
3
4
5
6
7
// 11. IIFEs with parameters
(function IIFE(msg, times) {
    for (var i = 1; i <= times; i++) {
        console.log(msg+i);
    }
}("shlee"5));
// shlee1, shlee2, shlee3, shlee4, shlee5
cs


function에 매개변수를 넘겨 for문으로 해당값이 잘 넘어갔는지 확인했다. 



2. Module pattern



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 12. Classical JavaScript module pattern
var Sequence = (function sequenceIIFE() {
    // Private variable to store current counter value.
    var current = 10;
    // Object that's returned from the IIFE.
    return {
        getCurrentValue: function() {
            return current;
        },
        getNextValue: function() {
            current = current + 10;
            return current;
        }
    };
}());
 
console.log(typeof Sequence); // console log "object"
console.log(Sequence.getNextValue()); // 20
console.log(Sequence.getCurrentValue()); // 20
cs



current값이 IIFE에 숨겨저 있으므로 클로저를 통해 액세스 할수 있는 함수 외에는 curret값을 수정하거나 액세스 할 수 없다.

private 클로저 scope를 만들기 위해 IIFE를 사용한다. ( almost all of them use an IIFE to create a private closure scope )



3. 소스코드



https://repl.it/@shlee0882/IIFE


'전체 > JS & Jquery' 카테고리의 다른 글

자바스크립트 PC, 모바일 감지, resize 하기  (0) 2019.09.20
JS Event Loop(이벤트 루프)  (2) 2019.04.26
JS 표현식(expressions)  (0) 2019.04.09
JS scope from function, collision avoidance  (0) 2019.04.09
JS ==, === 의 비교  (0) 2019.04.08


1. expression


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// expression
{}+1    // 1
{1}+2   // 2
{1+2}+2 // 2
2+(2*3)/2 // expressions
 
const assignedVariable = 2//this is a statement, assignedVariable is state
 
assignedVariable + 4 // expression
assignedVariable * 10 // expression
assignedVariable - 10 // expression
console.log(assignedVariable); // 2
 
const foo = (n) => {
  return n//explicit return for readability
}
assignedVariable2 = foo(14
console.log(assignedVariable2); // 14
cs




2. 함수 선언 및 허용범위


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 함수선언
function fooFunc1 (func) {
  return func.name
}
 
console.log(fooFunc1(function () {} )) // ""
console.log(fooFunc1(function sanghyun () {} )) // "sanghyun"
 
 
// 허용 범위
if (true) {
  function fooFunc2 () {} // top level of block, declaration
}
 
function fooFunc2 () {} //global level, declaration
 
function fooFunc2 () {
  function bar() {} //top level of block, declaration
}
 
function fooFunc2 () {
  return function bar () {} // named function expression
}
 
fooFunc2(function () {}) // anonymous function expression
 
function fooFunc2 () {
  return function bar () {
    function baz () {} // top level of block, declaration
  }
}
cs




3. , 쉼표 사용


1
2
3
4
5
6
7
8
// 쉼표, 사용
// 모든 표현식은 왼쪽에서 오른쪽으로 계산되고 마지막 표현식이 반환된다.
console.log( (1+2,3,100) ) //100
console.log( (29/3function () {}) ) // function (){}
console.log( (3true ? 2+2 : 1+1) ) // 4
 
function fa1 () {return 123200}
console.log(fa1()) //200
cs




4. 익명함수 선언 및 호출


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 익명함수 선언 호출
 
(function () {
  console.log("immediately invoke anonymous function call")
})() // "immediately invoke anonymous function call"
 
(function () {
  return 3
})() // 3
 
console.log((function () {
  return 3
})()) // 3
 
//you can also pass an argument to it
(function (a) {
  return a
})("I'm an argument"// I'm an argument
cs




5. 변수와 문자열 표현방법


1
2
3
4
5
// 변수와 문자열 표현방법
var value = 123;
console.log('test ${value}'//=> test ${value}
console.log(`test ${value}`) //=> test 123
console.log('test '+value) //=> test 123
cs




6. label 활용방법


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// label 활용 
loop1: {
  for (const i = 0; i < 2; i++) {
    for (const n = 0; n <2; n++) {
      console.log(n);
      break loop1 //breaks outer loop and stops entire loop
    }
  }
}
 
first: for (var i = 0; i < 3; i++) {
  second: for (var j = 0; j < 3; j++) {
    if (i === 1continue first;
    if (j === 1break second;
    console.log(`${i} & ${j}`);
  }
}
cs



7. 실습 코드


https://repl.it/@shlee0882/expression-and-statement


https://repl.it/@shlee0882/expression-and-statement-2



'전체 > JS & Jquery' 카테고리의 다른 글

JS Event Loop(이벤트 루프)  (2) 2019.04.26
JS IIFE, Modules  (0) 2019.04.10
JS scope from function, collision avoidance  (0) 2019.04.09
JS ==, === 의 비교  (0) 2019.04.08
JS Implicit Coercion(형변환)  (0) 2019.04.08


1. 함수에서 범위 ( Scope From Functions )


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script
    src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="
    crossorigin="anonymous"></script>
</head>
<body>
    <button id="button1">button</button>
</body>
<script type="text/javascript">
$( document ).ready(function() {
    $( "#button1" ).click(function() {
        bar(); // fails
        console.log(a, b, c); // all 3 fail
    });
 
    function foo(a) {
        var b = 2;
        // some code
        function bar() {
            // ...
        }
        // more code
        var c = 3;
    }
});
</script>
</html>
cs



bar(); 는 foo() 안의 들어있는 함수이므로 바로 호출이 불가능하다.

foo()의 인자로 받는 a, foo() 안의 선언한 변수 b,c를 호출하는 것은 불가능하다.




2. 충돌 회피( Collision Avoidance )


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script
    src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="
    crossorigin="anonymous"></script>
</head>
<body>
    <button id="button1">button</button>
</body>
<script type="text/javascript">
$( document ).ready(function() {
    $( "#button1" ).click(function() {
        foo();
    });
 
    function foo() {
        function bar(a) {
            debugger;
            i = 3// changing the `i` in the enclosing scope's for-loop
            console.log( a + i );
        }
 
        for (var i=0; i<10; i++) {
            debugger;
            bar( i * 2 ); // oops, infinite loop ahead!
        }
    }
});
</script>
</html>
cs



foo() 함수에 for문 i값은 초기값이 0 이지만

반복하면서 bar() 함수로 진입후 i의 값이 3으로 재정의된다. 

이후 bar() 함수를 빠져나오면 재정의된 i값 3이 for문으로 들어와 무한반복을 한다.

3, 11, 11, 11, 11 ...



3. Anonymous vs. Named


1
2
3
4
5
6
7
8
setTimeoutfunction(){
    console.log("I waited 1 second!");
}, 1000 );
 
 
setTimeoutfunction timeoutHandler1(){ // <-- Look, I have a name!
    console.log( "I waited 1 second!" );
}, 1000 );
cs



익명 함수는 더 읽기 쉽고 이해할 수있는 코드를 제공하는 데 도움이되는 이름을 생략한다.

익명 함수에는 스택 추적에 표시 할 이름이 없어 디버깅을 더 어렵게 만들 수 있다.

이름이 없으면 함수가 자체를 참조해야하거나 재귀를 참조해야하는 경우 사용되지 않는 인자의 참조가 필요하다.

설명이 포함 된 이름은 문제의 코드를 스스로 문서화하는 데 도움이된다.



4. let


1
2
3
4
5
6
7
8
9
var foo = true;
 
if (foo) {
    let bar = foo * 2;
    bar = something( bar );
    console.log( bar );
}
 
console.log( bar ); // ReferenceError
cs


var를 사용하면 어떤 블록에 어떤 변수를 범위에 두었는가에 따라 값이 변하거나 원치않은 결과가 나오는데

let을 사용하여 명시적 블록범위를 작성하면 변수가 연결되는 위치가 명확해진다.




let loop


1
2
3
4
5
for (let i=0; i<10; i++) {
    console.log( i );
}
 
console.log( i ); // ReferenceError
cs


let의 for문은 밖에서 호출시 ReferenceError가 발생한다.

값을 다시 할당해주어야 한다.




const


1
2
3
4
5
6
7
8
9
10
11
12
var foo = true;
 
if (foo) {
    var a = 2;
    const b = 3// block-scoped to the containing `if`
 
    a = 3// just fine!
    b = 4// error!
}
 
console.log( a ); // 3
console.log( b ); // ReferenceError!
cs



ES6에서 const블록 스코프 변수를 만들면 그 값은 고정된다.(상수)

값을 변경하려고하면 ReferenceError가 발생한다.



5. 소스


https://repl.it/@shlee0882/collision-avoidance


'전체 > JS & Jquery' 카테고리의 다른 글

JS IIFE, Modules  (0) 2019.04.10
JS 표현식(expressions)  (0) 2019.04.09
JS ==, === 의 비교  (0) 2019.04.08
JS Implicit Coercion(형변환)  (0) 2019.04.08
js value와 reference  (0) 2019.03.12


1. 자바스크립트에서  ==., ===



==는 loose equality할때 사용한다. 또한 ==은 형변환을 수행한다.

형변환 후에 오직 두개의 값 비교만 수행한다는 의미이다.

(Type coercion means that two values are compared only after attempting to convert them into a common type.)


===는 strict equality 할때 사용한다.

타입(type)과 값(value) 모두 비교했을때 같아야 한다.




2. === 비교


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Triple Equals
 
5 === 5 
// true
 
'hello world' === 'hello world'
// true (Both Strings, equal values)
 
true === true
// true (Both Booleans, equal values)
 
 
77 === '77'
// false (Number v. String)
 
'cat' === 'dog'
// false (Both are Strings, but have different values)
 
false === 0
// false (Different type and different value)
cs

type, value가 모두 같아야 true를 
둘 중 하나라도 다르다면 false를 반환하는 것을 확인할 수 있다.



3. == 비교


1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Double equals
 
77 === '77'
// false (Number v. String)
 
 
77 == '77'
// true
 
false === 0
// false (Different type and different value)
 
false == 0
// true
cs


자바스크립트는 실제로 같은 타입으로 변환을 시도하여 형변환한다. 
77 == '77' 에서 '77'은 number value로 쉽게 변환되어 true를 return 한다.


4. Falsy Value Comparison(거짓값 비교)


거짓값은 false, 0, "", null, undefined, NaN으로 총 6가지이다.

1. false — boolean false
2. 0 — number zero
3. “” — empty string
4. null
5. undefined
6. NaN — Not A Number



1. false, 0, and ""

1
2
3
4
5
6
7
8
false == 0
// true
 
0 == ""
// true
 
"" == false
// true
cs


2. null and undefined

1
2
3
4
5
6
7
8
null == null
// true
 
undefined == undefined
// true
 
null == undefined
// true
cs


3. NaN

1
2
3
4
5
6
7
8
NaN == null
// false
 
NaN == undefined
// false
 
NaN == NaN
// false
cs



5. 테스팅 코드




Triple Equals는 double equals보다 우수하다.
가능하면 테스트를 위해 비교가 필요한 구문이 필요하다면 ===를 사용하는 것이 좋다.
type과 value를 테스트해서 강제형변환을 막아 오류를 막을 수 있다.


'전체 > JS & Jquery' 카테고리의 다른 글

JS 표현식(expressions)  (0) 2019.04.09
JS scope from function, collision avoidance  (0) 2019.04.09
JS Implicit Coercion(형변환)  (0) 2019.04.08
js value와 reference  (0) 2019.03.12
js primitive type  (0) 2019.03.10

+ Recent posts