remagine

JAVASCRIPT 초급 강의 2 본문

JAVASCRIPT

JAVASCRIPT 초급 강의 2

remagine 2017. 2. 17. 10:57

JAVASCRIPT 기본 강의 2


 


뭔가 보여드리겠습니다 -햄스터(무직)


모든 예제는 브라우저 개발자 도구에 복붙하셔서 바로 확인하실 수 있습니다.


읽고 지나가지 마시고 예제들을 직접 확인해보세요



1. 지난 시간 복습


 /* ---------------------------------------------------------

 * 자바스크립트 데이터 유형

 * 1. 원시형 데이터 (복사, pass to value)

 *   1.1 숫자(Number)

 *   1.2 문자(String)

 *   1.3 불리언(Boolean)

 *   1.4 undefined

 *   1.5 null

 * 2. 자료형 데이터 (참조, pass to reference)

 *   2.1 함수(Function)

 *   2.2 배열(Array)

 *   2.3 객체(Object)

 * ---------------------------------------------------------

 * 자바스크립트 데이터 유형 확인

 * 1. [키워드 연산자] typeof

 *   1.1 약점

 *     null, [] => 'object'

 * 2. [키워드 연산자] instanceof

 *   2.1 약점

 *     원시 데이터 유형에 한해서 리터럴(Literal) 표현식을 사용할 경우,

 *     제대로 확인을 해주지 못한다. 

 * 3. [속성] constructor

 *   3.1 약점

 *     객체가 아닌 유형은 판별할 수 없다. //즉 undefined와 null을 판별하지 못함 객체가 아닌 자료형은 뭐다?

 * 4. [사용자 정의 헬퍼 함수] isType()

 *   4.1 핵심 구현 방법

 *     Function 객체의 능력 중에 .call()

 *     객체의 메소드(Method)를 빌려쓰기 패턴

 *     정확한 데이터 유형을 판별

 */


1. typeof


* typeof와 instanceof는 어떠한 변수가 문자열인지아닌지, 특정한 객체인지 아닌지 판단할때 사용하는 '연산자'들이다. 이들 둘이 어떻게 다른지 살펴보고 사용하면서 있을 수 있는 약점들도 같이 살펴보자.


* typeof

: typeof는 unary 오퍼레이터이다. unary 오퍼레이터로는 ! 라던가 - 등과 같이 인자를 하나만 받을 수 있는 연산자를 뜻한다. 즉, 함수가 아니고 연산자이기 때문에 괄호를 사용하면 안된다.


typeof yourVariable;

위와 같이 실행하고 나면 리턴 값으로는 해당하는 변수의 primitive 타입을 스트링으로 준다. 돌려주는 primitive 타입의 종류는 아래와 같다.


'undefined'

'boolean'

'number'

'string'

'object'

'function'

위의 기본 형식 중 하나를 스트링 형태로 리턴하기 때문에 어떠한 형인지 스트링으로 구분을 하면 된다. 즉, typeof를 사용해서 object인지 아닌지를 판별하는 경우 아래와 같이 하면 된다.


if(typeof yourVariable === 'object') { /* 오브젝트 처리 */}

하지만 위와 같이 하게 되면 만약 yourVariable이 null이라면 결과가 true로 나타난다. 따라서 null인 경우 false의 결과를 나타내고 싶다면,

if(yourVariable != null && typeof yourVariable === 'object') {/*오브젝트 처리*/}

if(!!yourVariable && typeof yourVariable === 'object') {/*오브젝트 처리*/}

위의 방법둘 중 하나를 하면 된다. 변수가 string인 경우를 판별하고 싶다면 위의 'object'를 'string'으로 바꿔주면 된다. 간단한 예들을 들어보면,



typeof 3;    // === 'number'

typeof 'str';    // === 'string'

typeof {};    // === 'object'

typeof [];    // === 'object'

typeof function () {};    // === 'function'

typeof null; // === 'object'

위의 테스트를 구글 크롬에서 개발자 도구의 콘솔을 열어서 실행해보면 쉽게 직접 결과를 확인할 수 있을 것이다.



2. instanceof


 instanceof 는 비교 연산자로 >,<,== 와 같이 두개의 인자를 받는 연산자로 앞의 비교 연산자들을 이용하는 기분으로 사용하면 된다. 하지만 결과로 리턴하는 것은 typeof와는 성질이 조금 다르다. instanceof는 해당하는 변수가 사용하고 있는 prototype의 chain을 2번째 인자와 쭉 비교해서 true/false 값을 리턴한다.


쉬운말로 하자면, 해당하는 변수의 클래스와 비교해서 리턴해주는, java에서 많이 쓰던것과 비슷하다고 볼 수 있다.


var Person = function(){

    this.name = "unikys";

};

var inst = new Person();


inst instanceof Person; // === true

inst instanceof Object; // === true

typeof inst; // === 'object'


instanceof는 클래스의 타입을 감지하는 역할을 하고, 위의 예를 통해 모든 클래스는 기본 클래스인 Object를 확장한다는 것을 알 수 있다.


: 하지만 자바스크립트라는 언어의 특징 때문에 그 동작하는 것은 부분부분 매우 다르기도 하다. instanceof가 동작을 다르게 한다기 보다는 자바스크립트라는 언어 자체가 다르게 동작을 하는 것으로 보면 된다. 가장 대표적인 예로 {}는 new Object()와 같은 의미를 하며, []는 new Array()와 같은 의미를 가지므로 위에 대해서 instanceof를 사용해보면 true가 나올 것이다. 하지만 다른 primitive type들에 대해서는 클래스로 instanceof를 할 수가 없다.


"foo" instanceof String; // === false

"foo" instanceof Object; // === false

true instanceof Boolean; // === false

true instanceof Object; // === false


[0,1] instanceof Array; // === true

{0:1} instanceof Object; // === true


var color1 = new String("red");

var color2 = "red";

color1 == color2; // === true

color1 instanceof String; // === true

color2 instanceof String; // === 무엇일까요?


위의 맨 아래 구분은 true/false 무엇일까? 왜 물어보는지 예상하셨다면 답은 false다. 다음과 같은 경우 자바스크립트를 처음 접해봤다면 이해를 할 수 없을 것이다. color1의 경우는 String이 맞지만 color2는 primitive type string으로 다르다. 하지만 비교 연산자 ==는 true가 나온다. 어떻게 보면 편하면서도 잘못사용하면 원인도 모르고 삽질을 할지도 모른다. 위에서 object literal인 []와 {}에 대해서 typeof는 둘다 object를 리턴했지만, instanceof는 각각 Array와 Object를 리턴한 것도 관심을 가져야할 결과이다. 아래는 그래서 조금 다른 예이다.


"foo".constructor instanceof String; // === false

"foo".constructor === String; // === true?!


이건 또 어떻게 된 영문인가? "foo".constructor는 String하고 같지만 String의 instance는 아니다?! 여기서 크롬의 개발자 콘솔에 String을 쳐보면 왜 그런지 알 수 있을 것이다.


String

function String() { [native code] }


크롬에서 String을 실행하면 위와같이 나온다. "foo".constructor 는 Function의 instance인 것이다. instance의 개념에 대해서 다시한번 돌이켜보면 어쩌면 당연한 결과이기도 하다. 즉, String 자체는 Function의 instance인 것이다.


* 이렇게 살펴보면 결국 두가지의 연산자는 각각 다른 용도로 활용하면 될 것이다. primitive type을 구분할 때에는 typeof를 사용하고 클래스의 타입을 구분할 때에는 instanceof를 사용하면 된다.




3. 실제 예시 


   JS 데이터 유형은 변수에 값을 복사/참조할 경우

   new() 생성자 함수 방법보다는 객체 리터럴 표현식을 사용하는 것을 권장

   var 키워드를 한번만 사용하는 패턴 -> 'var' singleton pattern


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
44
45
46
47
48
49
50
51
52
53
54
55
56
var num =21,
    _num = new Number(num),
    str = '이롭게 에이전시',
    boo = false,
    fnc = function(){},
    arr = [num, str, boo,fnc],
    obj = {'name' : str, 'live' : !boo, getName : fnc},
    isType = function(data){
      return Object.prototype.toString.call(data).slice(8,1).toLowerCase();
    };
 
//var 선언뒤에 , 로 이어나가면 변수선언이 동일하게 이뤄진다. 함수도 마찬가지. 
 
//JS 타입 체크
// * with 문은 사용하지 않는 것이 좋다. (성능에 안 좋은 영향을 미침)
// with 문을 사용하면 귀찮은 타이핑이 줄어들 수 있네?
 
with(console) {
  log('%c---------------------------------------------------''color: #b8b8b8');
  log('num:'typeof num);                     //결과 number
  log('str:'typeof str);                         // string 
  log('boo:'typeof boo);                     // boolean
  log('fnc:'typeof fnc);                       // function
  log('* arr:'typeof arr);                      // object (array가 아니다)
  log('obj:'typeof obj);                       // object
  // 객체가 아닌 데이터 유형 체크 
  log('* null:'typeof null);                    // object (null이 아니다)
  log('undefined:'typeof undefined);        // undefined 
 
// typeof 는 인자를 하나받는 '연산자'이다. array와 null을 object로 반환하는 문제가 있다. 
 
 
  log('%c---------------------------------------------------''color: #b8b8b8');
  log('arr instanceof Array:', arr instanceof Array);         // 결과 true
  log('* num instanceof Number:', num instanceof Number); //  false (리터럴 값은 제대로 비교하지 못한다)
  log('_num instanceof Number:', _num instanceof Number);//  true (변수에 담긴 _num은 new Number(num)으로 생성된 instance. 제대로 나온다)
  log('%c---------------------------------------------------''color: #b8b8b8');
  
  log('str.constructor === String:', str.constructor === String);
  log('boo.constructor === Boolean:', boo.constructor === Boolean);
  log('fnc.constructor === Function:', fnc.constructor === Function);
  log('arr.constructor === Array:', arr.constructor === Array);
  log('obj.constructor === Object:', obj.constructor === Object);
  // ※ 객체가 아닌 데이터 유형에서는 .constructor 속성을 사용할 수 없다. 객체가 아닌 것은 null과 undefined
  // log('(null).constructor === Object:', (null).constructor === null);
  // log('(undefined).constructor === Object:', (undefined).constructor === undefined);
  log('%c---------------------------------------------------''color: #b8b8b8');
  log("isType(num) === 'number':",          isType(num) === 'number');   // 위에서 정의함 isType 함수...사용
  log("isType(str) === 'string':",          isType(str) === 'string');         // call()을 통해 메소드를 빌려 모든 인자의 type을 체크할 수 있다..
  log("isType(boo) === 'boolean':",         isType(boo) === 'boolean');//사실..toString된것을 slice해서 비교긴 하다..
  log("isType(fnc) === 'function':",        isType(fnc) === 'function');
  log("isType(arr) === 'array':",           isType(arr) === 'array');
  log("isType(obj) === 'object':",          isType(obj) === 'object');
  log("isType(null) === 'null':",           isType(null=== 'null');
  log("isType(undefined) === 'undefined':", isType(undefined) === 'undefined');
}
cs



4. false로 형 변환이 이뤄지는 데이터 값


 -->  0, '' , null, undefined , void 0



 1. 특정 기능을 지원하는 브라우저와 아닌 브라우저 감지

 var feature = !!window.localStorage; // 지원 : true, 미지원 : false

 feature = 'geolocation' in window.navigator; // navigator instance에 geolocation이라고 정의된 prop가 있는지 하나씩 꺼내서 탐색


if (feature) {

  // localStorage 사용

  // console.info('localStorage 사용 가능');

  console.info('geolocation 사용 가능');

} else {

  // cookie 사용

  // console.info('cookie 사용');

  console.info('geolocation 사용 불가');

}



5. 간단한 if else, 삼항 조건식 사용


// 조건 2개 이상, 조건이 만족되지 않은 경우에 처리되는 if 구문 작성

// 배열 데이터를 생성해서 요일을 갈무리한다.

var days = '일 월 화 수 목 금 토'.split(' '); // 이러면 알아서 배열이 생성된다

 // var days = ["일", "월", "화", "수", "목", "금", "토"]  이렇게 해도 되겠지..


var today = (new Date()).getDay(); // 현재 브라우저의 시간객체를 생성해서 요일을 가져온다. 

 // 0~6까지의 값을 return한다. 0 = 일요일


var showDayMessage = function(n) {

  return '오늘은 ' + days[n] + '요일입니다. :-)';

}; 


1. if ~ else 로 요일 출력하기 


 if      ( today === 0 ) { console.log( showDayMessage(0) ); }

 else if ( today === 1 ) { console.log( showDayMessage(1) ); }

 else if ( today === 2 ) { console.log( showDayMessage(2) ); }

 else if ( today === 3 ) { console.log( showDayMessage(3) ); }

 else if ( today === 4 ) { console.log( showDayMessage(4) ); }

 else if ( today === 5 ) { console.log( showDayMessage(5) ); }

 else if ( today === 6 ) { console.log( showDayMessage(6) ); }


2. 다중 삼항 조건식


 today === 0 ? console.log( showDayMessage(0) ) :

   today === 1 ? console.log( showDayMessage(1) ) :

     today === 2 ? console.log( showDayMessage(2) ) :

       today === 3 ? console.log( showDayMessage(3) ) :

         today === 4 ? console.log( showDayMessage(4) ) :

           today === 5 ? console.log( showDayMessage(5) ) :

             today === 6 ? console.log( showDayMessage(6) ) : console.log('장난 하냐?');


3. switch ~ case


switch(today) {

   case 0:

     console.log( showDayMessage(0) );

   break;

   case 1:

     console.log( showDayMessage(1) );

   break;

   case 2:

     console.log( showDayMessage(2) );

   break;

   case 3:

     console.log( showDayMessage(3) );

   break;

   case 4:

     console.log( showDayMessage(4) );

   break;

   case 5:

     console.log( showDayMessage(5) );

   break;

   case 6:

     console.log( showDayMessage(6) );

   break;

   default:

     console.log( '장난 하냐?' );

 }


4. for 구문 성능 체크


var check_arr = new Array(1000); // ECMAScript 3rd Edition console.time('for문'); for ( var i=0, l=check_arr.length; i<l; i+=1 ) { console.log(i); } console.timeEnd('for문'); // ECMAScript 6th Edition => ECMAScript 2015 console.time('for ~ of문'); for ( let m of check_arr ) { console.log(m); } console.timeEnd('for ~ of문');


// for 구문에서 int i=0 을 선언하고 실행할때 i++ 형식보다 i--형식이 더 빠르다(감산이 더 빠름)

'JAVASCRIPT' 카테고리의 다른 글

Closure 클로저에 대해서  (0) 2017.06.30
This의 중요성과 Call() 사용  (0) 2017.05.04
JAVASCRIPT 초급 강의 3  (0) 2017.02.17
JAVASCRIPT 초급 강의 1  (0) 2017.02.17
Comments