2014.11.12 23:27

JavaScript Quiz


Quiz 1
var name = "javarouka";
var introduce = function() {
    var intro = "My name is ";
    if(!name) {
        var name = "unknown"
    }
    return intro += name;
}
document.write(introduce());
  • "My name is undefined"
  • "My name is null"
  • "My name is javarouka"
  • "My name is unknown”
    : function scope에 선언된 variable name은 introduce 함수 실행 시 hoisting 되어 undefined로 초기화 된 상태가 되므로 if(!name) 구문 내부로 진입이 가능하게 된다.
    또한, local variable로 선언된 name이 “unknown”값으로 할당을 받으면  global scope에 선언된 name은 shadow 되므로 “javarouka”가 아닌 “unknown”이 최종 값이 된다


Quiz 2

document.write(myName() + " / ");
var myName = "javarouka";
function myName() {
    return "rouxrouka";
}
delete myName;
document.write(myName);
  • 실행 오류
  • "rouxrouka / javarouka”
    :  myName과 같은 Named Function은 script loading과 동시에 AST에 구성되어 Hoisting과 더불어 선언이 완료된다. 따라서, 초기 myName을 호출해도 정상 동작하게 되어 “rouxrouka”값을 얻게 된다.
    이후 var로 myName을 재선언 하게 되면 myName은 함수가 아닌 문자열 object로 인식하게 된다. 이후 delete를 호출하여 myName을 삭제 하려하고 있으나 var로 선언된 myName은 삭제 불가 속성이므로 삭제되지 않고 “javarouka” 값을 유지하게 된다.
  • "undefined / javarouka"
  • "undefined / undefined"


Quiz 3

(function(doc) {
    document.write(new doc() === doc());
    document.write(new doc() === document);
    document.write(doc() === document);
})
(function arg() {
    return document;
})
  • 실행 오류
  • "falsefalsefalse"
  • "falsefalsetrue"
  • "falsetruetrue"
  • “truetruetrue” 
    : 위의 구조는 IIFE 방식으로 arg() 함수가 doc으로 넘겨지는 구조를 가진다. JavaScript에서는 new 키워드를 하여 함수를 constructor로 인식 object를 생성 할 수 있다.
    new operation을 실행하면 먼저 메모리 공간에 empty object를 생성하고 이 object의 constructor property를 constructor 함수의 저장 영역을 가리키게 한 후 constructor 함수를 호출하면서 context를 새로 생성된 object로 bind하게 된다. constructor 함수의 실행이 종료되면 생성된 object (this) 를 return하게 되는데, 만약 constructor 함수가 임의의 object를 명시적으로 return 하는 경우 새로 생성한 object 대신 명시된 object를 return 하게 된다.

    JavaScript의 이러한 특징에 의해 예제의 new doc()과 doc()을 실행하여 얻는 object는 document로 identical 조건을 만족한다. 만약, return값이 object가 아닌 string과 같은 literal일 경우는 해당되지 않으므로 결과 값은 falsefalsetrue가 된다.

    참고로, 이러한 constructor 함수의 특징을 이용하여 private function 을 구현 하기도 한다.
  • "truefalsefalse"
  • "truetruefalse"


Quiz 4

function setter(aryUnits) {
    for(var i=0; i < aryUnits.length; i++) {
        var id = i + 1;
        aryUnits[i] = new Object();
        aryUnits[i].getId = function() {
            return id;
        }
    }
}
var ary = new Array(5);
setter(ary);
document.write(ary[3].getId());
  • 실행 오류
  • undefined
  • 4
  • 5
    : setter 함수의 for loop 에서 var 로 선언된 id는 hoisting되어 setter 함수의 진입 시 undefined 값을 가지게 된다.
    aryUnits element에 할당하는 getId 정보는 단지 Function Literal로 for loop을 통해 함수 자체가 실행되는 것이 아니며, 이후 getId()를 호출 하는 시점에 scope이 형성된다. 이 함수의 내부에서 사용되는 id는 setter 함수 scope에 bind된 id로서 reference만 유지하게 된다.

    이 예제에서는 for loop이 진행되면서 id는 1에서 5까지 변하게 되지만 array별로 할당받은 getId 함수를 호출할 때는 결국 같은 object인 id를 참고하게 된다. 따라서, id의 최종 id 값인 5를 얻게 된다.

    각 array element 별로 값을 얻기 위해선 id를 얻는 function을 closure로 생성하여 scope을 확보 후 넘겨 주어야 한다.
    getId = (function(id) {
        return function() {
            return id;
        }
    })(id);


Quiz 5

function args() {
    return (typeof arguments) && (arguments instanceof Array);
}
document.write(args());
  • 실행 오류
  • "object"
  • true
  • false
    : typeof arguments는 object이나 arguments는 Array Like Object이므로 Array Instance가 아니다


Quiz 6

var c;
document.write(typeof typeof c);
  • "undefined"
  • "object"
  • 실행 오류
  • “string” 
    : typeof c는 “object”라는 string literal 값을 가지므로 typeof “object”는 “string”이 된다.


Quiz 7

var privacy = {
    secret: "I did not study last night.",
    getSecret : function() {
        return this.secret;
    }
};
var what = privacy.getSecret;
document.write(what());
  • 실행 오류
  • "I did not study last night."
  • undefined
    : privacy.getSecret 함수를 global variable인 what에 할당을 한 경우이므로, 실제 함수가 실행 될 때 this는 what이 속해 있는 window object를 context로 인식하게 된다. window에는 secret이 정의 되어 있지 않았으므로 undefined 값을 얻게 된다. 만약, var secret = “100”으로 global variable을 설정한 경우라면 당연히 return 되는 값은 “100”을 얻게 된다. 또한, what()이 아닌 privacy.getSecret()을 실행하면 this는 privacy object가 되므로 “I did ~~ night.” 값을 얻게 된다.

    JavaScript의 Function에서 기본적으로 제공하는 기능 중에 call이나 apply의 경우 이러한 context를 다르게 줄 수 있는 기능을 제공한다. 예를 들어 what.call(privacy)라고 호출 했다면, 비록 what이라는 함수를 실행한다해도 context가 privacy이므로 “I did ~~ night”를 호출하게 된다.
  • "function() { return this.secret; }"


Quiz 8

function func1( ) { return func1; }
if(new func1() === func1()) {
    document.write("same!");
}
else {
    document.write("different!");
}
  • 실행 오류
  • "same!”
    : 앞서 Quiz3번과 유사한 문제로 초기 AST(Abstract Syntax Tree)구성 시 f
    unc1이 Named Function으로 등록된다. 그 상태에서 new func1()을 실행하면 return 값으로 func1 함수 object을 return하고 func1()을 실행 할 때도 마찬가지로 동일한 func1을 얻게 된다.
  • "different!"


Quiz 9

(function(){
    Object.prototype.scope = "prototype";
    (function(f) {
        var scope = "local";
        alert(f());
    })(function checkScope() { return scope; });
})();
  • 실행 오류
  • "local"
  • “prototype” 
    : Object.prototype.scope에 값을 assign하는 경우 모든 Object에 scope이라는 property key를 갖게 된다. IIFE 함수의 argument로서 넘겨받은 checkScope 함수를 실행하면 IIFE의 context에 bind되므로 scope == window.scope을 의미하게 된다. 따라서, global로 scope이 정의되어 있지 않아 undefined가 될 것 같은 모습이지만, 앞서 Object의 prototype에 scope이라는 property를 추가 해 주었기 때문에 prototype chain을 따라 그 값은 “prototype”이 된다. 

     만약,
    var scope 대신 scope = “local” 또는 this.scope = “local” 이라고 선언 했다면, 명시적으로 window.scope에 값이 할당된 것이므로 prototype 값이 아닌 window object에 할당된 메모리 영역을 접근하여 “local” 값을 얻게 된다.
  • "undefined"


Quiz 10

var strZero = "0";
var numZero = 0;
var notNumer = NaN;
var strEmpty = '';
var tab = '\t';
var undef;
var nll = null;
if(strZero == true) {
    document.write("1");
}
if(notNumer == false) {
    document.write("2");
}
if(undef == nll) {
    document.write("3");
}
if(tab == 0) {
    document.write("4");
}
if(tab == true) {
    document.write("5");
}
if(strEmpty == numZero) {
    document.write("6");
}
if(false == 'false') {
    document.write("7");
}
if(strEmpty == false) {
    document.write("8");
}
  • ""
  • "78"
  • “3468” :
    1: 문자열 “0”과 boolean의 비교 이므로 strZero는 0 true은 1로 비교하므로 false
    2: NaN은 어떤 값과 비교해도 false
    3: undefined와 null은 abstract equality comparison에서 같은 것으로 인식하므로 true
    4: 문자열 number 비교로 문자열 tab을 숫자 0으로 변환되므로 true

    5: 문자열 boolean 비교로 문자열 tab을 숫자 0으로 변환되고, true는 1로 변환되므로 false
    6: 문자열 number 비교로 strEmpty는 숫자 0으로 변환되므로 true
    7: 문자열 boolean 비교로 false는 +0으로 변환되고 ‘false’는 numeric literal이 아니므로 변환되지 않으므로 false
    8: 문자열 boolean 비교로 false는 +0으로 변환되고 strEmpty는 숫자 0으로 변환되므로 true

    JavaScript 비교 연산에 대한 정리는 JavaScript Equality Operator 에 대한 글을 참고하기 바란다.
  • "34568"
  • "2567"


'Technical Stubs > JavaScript' 카테고리의 다른 글

JavaScript Quiz  (0) 2014.11.12
JavaScript 비교 연산에 대한 정리  (0) 2014.11.12
Trackback 0 Comment 0