제 홈페이지의 모든 글은 anti-nhn license에 따릅니다.



요상한 javascript

1. this 는 함수가 호출되는 시점에 결정된다.

var a = {name:'a', sayName: function (){ return this.name;} };
var b = {name:'b', sayHello : function(){ return 'hello ' + this.name;}};

alert( b.sayHello.apply(a)); //hello a 가 찍힘.

a에는 존재하지도 않는 함수를 호출하는 방법입니다.

javascript가 class 기반의 oop 언어와 상당히 다른 점 중 한 가지 입니다.

특정 객체에 소속되지 않는 함수에서의 this 는 window 객체가 됩니다.

ex> 
foo();
function foo(){
var me = this; // 함수 선언과 호출이 이와 같이 된다면( object.foo()나 method.call(object, ...) method.apply(object ,.. ) 의 형식이 아니면 ) this는 window 객체를 의미함.
}





2. debugger

firebug나 chrome debugger 등이 켜져 있을 때 자동으로 break point 의 역할을 하게 됩니다. 코드에 debugger; 라고 치면 그 라인에서 디버그가 걸려서 멈추게 됩니다. 디버거가 안 켜져 있으면 무시하고 지나갑니다. console.log 와 비슷하다고 이해하시면 됩니다.
HTTP get으로 js가 호출될 경우 브라우저에서 판단해서 굳이 호출하지 않고 브라우저의 cache를 쓰기도 합니다. 따라서 js파일을 수정했더라도 수정된 것이 반영되지 않는데 이런 현상이 일어나지 않게 하는 방법은 두 가지가 있습니다.
 1. 호출전에 브라우저 캐쉬를 지운다. ( 아~ 구찮아... )
 2. javascript library 등을 통해서 cache를 무력화 시키는 파라미터를 강제로 박는다. (Extjs의 _dc 파라미터가 하는 역할이 이겁니다.)
 
 1 번의 경우는.... 정말 걍 구찮습니다.
 2 번의 경우는 디버거 툴을 이용해서 break point를 걸어놓더라도 cache 무력화 파라미터 때문에 새로 호출하면 완전히 다른 파일로 인식하기 때문에 break point 가 동작하지 않습니다. ( /a.js?_dc=1 로 받아온 파일과 /a.js?_dc=2 로 받아온 파일을 브라우저는 다른 놈으로 인식한다는 뜻입니다.)

 이럴 때, 2번의 방법으로 하고 debugger; 라고 치면 그 라인에 break point가 걸립니다. 





3. javascript에서 함수는 변수다.

java 와 같은 언어에서는 함수와 변수가 완전히 다른 것이지만 javascript에서는 함수란 "실행가능한 변수"의 개념으로 이해하시는 게 좋습니다.

function foo(){ alert('merong');}
var foo = 'a';
foo(); //에러남.

foo 라는 변수가 foo라는 함수를 덮어쳐 버렸습니다.

함수를 함수의 인자로 넘기는 것이 가능한 것이 바로 이 때문입니다. command 패턴 같은 것을 쓸 때 굳이 인터페이스 같은 것을 만들 필요가 없어집니다.

기본적으로는 아래 두 구문은 동일합니다.

1. function foo (...
2. var foo = function (... 

다만 차이가 있는 것은 1의 경우는 함수 호출을 그 위쪽에서 해도 되지만 2의 경우는 그렇게 하면 함수를 찾을 수 없다고 나옵니다. (인터프리팅 후 런타임 단계로 넘어가는데 1은 인터프리팅이 되면 바로 함수가 생기지만 2는 런타임 시점에서 함수가 생긴다고 보시면 됩니다.)

ex> 
case 1 > 
foo();
function foo(){ alert ('merong');} //함수가 먼저 파싱되서 에러 안나고 함수 호출 잘 됨.

case 2>
foo(); // 아직까지는 foo가 뭔지 알 수 없는 상태라서 에러
var foo = function () { alert('merong');}


아래 코드는 특히 좀 골 때립니다. 

var foo = function (){alert('haha');};
function foo(){ alert('merong');}
foo(); //haha가 찍힘

이유는... function foo()가 먼저 인터프리팅되서 처리 끝난 후에 런타임에 var foo가 덮어쓰기 때문입니다.





4. javascript의 함수는 멤버를 가질 수 있다.

function foo(){ alert('merong');}
foo.member = function(){alert('member');};
foo(); //얘는 함수
foo.member(); //얼레? 얘도 함수

javascript에서의 함수는 실행가능한 object 의 형식으로 이해하시면 되겠습니다. object니까 당연히 멤버를 물고 다닐 수 있습니다.





5. default value 처리

a라는 변수에 b의 값이 있으면 b를 할당하고 없으면 c를 하려면 아래와 같이 하면 됩니다.

var a = b?b:c;

이것을 더 간단히 하면 아래와 같이 됩니다.

var a = b||c;

이것을 응용하면 함수의 인자의 기본값을 설정할 수 있습니다.

function eat(hamburger, beverage){
 beverage||(beverage='coke'); //음료가 없으면 음료는 coke로 설정!
 alert('eating ' + hamburger + ' with ' + beverage);
}

eat('치킨버거');
eat('불고기버거', '사이다');





6. javascript object에서 키값은 반드시 String

java의 object 처럼 키를 아무거나 넣을 수 있는 것이 아닙니다. string과 숫자만 됩니다. 

var s = {'name':'jack'};
var s = {name : 'jack'};

따라서 위 두 구문은 완전히 동일합니다.


var key = {}; //key로 쓰기 위한 어떤 object
var object = {}; //테스트용 object
object[key] = 1; //key로 object를 썼네 ?
alert(object[{}]); //뭐야? 예상한 대로 1이 나온다!!

뭐, key로 object를 넣어도 되는 것 같아 보이는 코드입니다. 하지만 맨 마지막 줄을 alert(object[{a:0}]) 과 같이 엄한 놈을 집어넣어도 1이 나옵니다. 잘 되는 게 아닙니다.

alert(object['[object Object]']); // 이거 해봐도 1이 나옮. 
var v = {toString : function (){ return '[object Object]';}}
alert(object[v]); // 이거도 1이 나옮

var v = {toString : function (){ return '이상한 문자';}}
alert(object[v]); // 이거는 1이 안 나옮. 결국은 toString 이란 얘기..


숫자도 주의해야 할 점이 있는데.

var a = {};
a[0] = 'int';
a['0'] = 'string';
alert(a[0]); // string이 찍힘

이유는.. object의 key 에 들어간 숫자도 string으로 고쳐지기 때문입니다.





7. NaN은 무엇과 비교해도 false

var nan1 = Number('a');
var nan2 = Number('a');
alert(nan1 == nan2); //false


또 재밌는 것은 alert(typeof nan1) 을 해보면 number라고 나옵니다. NaN 이 "Not a Number" (숫자가 아님) 인데 타입은 숫자 타입이랩니다.

비슷한 것으로 

alert(typeof(null)); // object

null의 타입은 object입니다.

또 비슷한 것으로 new Boolean(false)가 있습니다.

alert(new Boolean(false)); //false
if (new Boolean(false)){ //그러나 실행됨..
alert('true??'); //결국 이 alert도 실행됨..
}

alert에서 찍힘 false가 boolean값 false를 의미하는 게 아닙니다. 
아래쪽 if에 들어가서 실행됩니다. 그 이유인 즉슨, Boolean은 object이기 때문입니다.

alert( typeof new Boolean(false)); // object





8. 숫자 변환기 + 표시

var v = +new Date();  // ==> var v = new Date().getTime(); 과 같음.

+"1000" // ==> parseInt('1000'); 과 동일.
+true // ==> 1
+false //==> 0
+"1e3" //==> 1000

등과 같이 숫자로 변환할 수 있는 게 많습니다.

특정 클래스에 valueOf 함수가 있으면 + 표시는 valueOf 함수를 호출해 줍니다. 아래는 그 예제입니다.

function IntWrapper(a){
this.valueOf = function (){ return a;};
}

var a = new IntWrapper(1);
alert(+a); // 1

by 삼실청년 | 2013/07/09 23:10 | 컴터질~ | 트랙백(1) | 덧글(2)

트랙백 주소 : http://iilii.egloos.com/tb/5756394
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from at 2014/03/11 00:48

제목 : http://helenmccrory.org/
line1...more

Commented by warrenth at 2014/08/14 10:10
오랜만에 글을 쓰셨네요.

잘읽고 가요^^
Commented by 삼실청년 at 2015/01/22 21:07
오랫만 아닌데요~ ㅋㅋㅋㅋ 1년도 넘은 글이에요...ㅜㅜ
블로그 버렸다가 오랫만에 들어와봤는데.....
천천히 시간 나문 정리 좀 하면서 넘어갈께요.
찾아주셔서 감사합니다.

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶