콜백함수로 넘길 함수가

어떤 객체의 프로퍼티이고, 함수 내부에서 this를 사용했다면,

콜백을 전달받은 함수에서 이 콜백함수를 호출하게되면 this의 값이 달라진다.


다음 예를 보면,

var myobj = {}
var myobj.color = "green"
var myobj.paint = function(node) {
	node.style.color = this.color
};


myobj.paint 함수를 다른 함수의 콜백인자로 넘겨보자.

var setColor = function(callback) {
	...
	if ( typeof callback === "function" ) {
		callback(node);
	}
	...
};

setColor(myobj.paint);


myobj.paint 함수 정의의 this는 setColor의 함수객체를 가리킨다. 즉 전역에 color 이라는 필드가 선언되어 있다면 그 값이 나오겠지만 선언되지 않았다면 ReferenceError exception이 발생한다.



이 상황을 해결하기 위해 myboj 객체도 인자로 같이 넘겨받아 this를 알아내는 방법이 있다.


자바스크립트는 함수 선언도 hoisting 기능이 적용된다.

다음 예를 보자.



//전역 함수 선언
function foo1() {
	alert('global foo1');
}
function foo2() {
	alert('global foo2');
}
function hoistMe() {
	foo1();
	foo2();

	function foo1() {
		alert('local foo1');
	}
	var foo2 = function() {
		alert('local foo2');
	}
}
hoistMe();

결과는 어떻게 될까......


의도된 결과는

'global foo1'

'global foo2'

였을 것이다.


하지만 자바스크립트의 hoisting 기능으로 인해 결과는

'local foo1'

Type Error


가 된다.


어째서?


자바스크립트는 hoistMe() 함수 내부에 선언된 변수 및 함수를 hoisting 하는데

foo1()은 함수 선언이므로 함수 정의 자체도 같이 hoisting되어서

전역 foo1() 함수를 가린다.


따라서 호출 결과 global이 아닌 local 이 불리게 되는것이다.



그럼 왜 foo2는 global도 local도 아닌 Type error 일까?


foo2()는 hoistMe 함수 내부에서 함수표현식으로 함수를 정의 했다.

hoist 기능은 선언문만 유효범위 맨 위로 올려지기 때문에

var foo2; 만 hoisting되고 함수 정의는 그 위치 그대로 남게 된다.


따라서 foo2()를 호출 하였을 때엔 

var foo2; 는 선언이 되어있지만 정의가 안된 undefined 값이어서,

즉 foo2라는 객체가 isCallerble이 아니기 때문에 Type Error 예외를 발생시킨다.



local 안에서 새로 정의한 함수를 호출 할 의도였으면

함수 선언문으로 선언을 하자.


'WEB > javascript' 카테고리의 다른 글

javascript JSON 사용하기  (0) 2012.08.10
자바스크립트 콜백과 유효범위  (0) 2012.07.27
자바스크립트 함수 객체의 name 프로퍼티  (0) 2012.07.27
생성자 함수 안전 사용  (0) 2012.07.22
객체 생성자의 함정  (0) 2012.07.22

자바스크립트의 함수를 정의하는 방법은 두가지가 있다.

함수 선언문, 함수 표현식



함수 선언문

function foo() {}

를 evaluation 하게되면

foo.name 은 "foo" 가 된다.



기명 함수 표현식


var fun = function add (a, b) {
	return a+b;
};

를 evaluation 하게되면

name 프로퍼티에 "add"라는 값을 가지는 함수 객체를 f에 리턴해 준다.


즉, fun.name 은 "add" 가 된다.


익명 함수

var fun = function (a, b) {
	return a+b;
};

fun.name 은 "" 이다. (IE에서는 undefined)


표현식에는 마지막 세미콜론을 꼭 써줘야 한다.






'WEB > javascript' 카테고리의 다른 글

자바스크립트 콜백과 유효범위  (0) 2012.07.27
자바스크립트 함수 hoisting  (0) 2012.07.27
생성자 함수 안전 사용  (0) 2012.07.22
객체 생성자의 함정  (0) 2012.07.22
자바스크립트 리터럴 표기법  (0) 2012.07.22


일급함수란 앞에서 설명했듯이, 어떤 함수가 리턴값으로도 올 수 있고, 다른함수의 인자로 넘겨질 수도 있는 성질을 말한다.


그럼 함수 몸체 내에 있는 free variable의 바인딩을 결정하는 시점은 언제일까?

함수 선언 때? 실행 때?


다음 예를 보자.


var x = 10;
 
(function (funArg) {
 
  var x = 20;
  funArg(); // 10, not 20
 
})(function () { // create and pass a funarg
  console.log(x);
});


익명의 함수를 funArg 라는 이름의 인자로 넘겨주어 호출되도록 하였다.
funArg() 몸체 내에서 x 값을 출력하는데, 이 값은 20(실행시점)이 아니라 10(선언시점) 으로 결정된다.

즉, 자바스크립트에서 함수의 environment를 결정하는 시점은 함수 선언 때 이다.

myname = "global";
function func() {
	alert(myname);
	var myname = "local";
	alert(myname);
}
func();


의도된 결과는




였을 것이다.


하지만. 자바스크립트에는 hoisting이라는 성질이 있다.


myname = "global";
function func() {
var myname;            // undefined
alert(myname);
myname = "local";
alert(myname);
}
func();



myname 라는 변수의 선언이 scope의 맨 위로 올려져 undefined 값으로 설정된다.


따라서 결과는







'WEB > javascript' 카테고리의 다른 글

자바스크립트 리터럴 표기법  (0) 2012.07.22
eval() 안전하게 사용하는 방법  (0) 2012.07.22
자바스크립트 전역변수  (0) 2012.07.10
strict mode  (0) 2012.07.10
객체지향 언어  (0) 2012.07.09



네이티브 객체 : ECMAScript 표준에 정의된 객체

네이티브 객체는 내장객체(예를들면, Array나 Date) 또는 사용자 정의 객체(var o={};)로 분류된다.



호스트 객체 : 호스트환경(예를 들면, 브라우저 환경)에서 정의된 객체

호스트 객체의 예로는 window 객체나 모든 DOM 객체를 들 수 있다.





어떤 객체가 호스트 객체인지 궁금하다면?

코드를 브라우저가 아닌 다른 환경에서 실행시켜 보면 된다. 

만약 잘 동작한다면 네이티브 객체만을 사용하고 있는 것이다.



'WEB > javascript' 카테고리의 다른 글

자바스크립트 리터럴 표기법  (0) 2012.07.22
eval() 안전하게 사용하는 방법  (0) 2012.07.22
호이스팅(hoisting): 분산된 var 선언의 문제점  (0) 2012.07.12
자바스크립트 전역변수  (0) 2012.07.10
strict mode  (0) 2012.07.10

+ Recent posts