객체지향 프로그래밍에 익숙하다면 함수, 메서드, 클래스 생성자 이렇게 세 개의 요소로 생각하기 쉽다. 하지만 자바스크립트에서는 function
을 사용하는 서로다른 패턴일 뿐이다.
📌 일급 객체
자바스크립트에서 함수는 일급 객체이다. 다른 객체와 마찬가지로 함수가 값으로 취급된다는 것을 의미한다. 즉 함수를 매개변수, 반환값, 변수에 할당등이 가능하다. 이는 함수형 프로그래밍이나 콜백 패턴과 같은 고급 프로그래밍 기법을 가능하게 한다.
function hello(username){
return "hello "+ username;
}
hello("world") //hello world
다음 예제는 보이는 그대로 동작한다.
📌 JavaScript에서
this
는 현재 실행 중인 코드의 컨텍스트를 가리키는 특수한 키워드입니다.this
는 함수 내부에서 사용되며, 함수가 호출될 때 동적으로 결정됩니다.this
의 값은 함수를 호출하는 방식과 실행 컨텍스트에 따라 달라집니다.
this
의 값은 다음과 같은 경우에 결정될 수 있다.
this
가 결정된다.this
는 해당 객체를 가리킨다.this
는 새로 생성된 객체를 가리킨다.var obj = {
hello:function(){
return "hello, " + this.username;
},
usename : "jhon"
}
obj.hello(). //''hellow, jhon"
자바스크립트에서 매서드는 함수로 동작하는 객체의 프로퍼티이다. 여기서 hello()
가 obj
에 선언 되었기 때문에 this
는 obj
에 바인딩 되었다고 생각할 것이다. 그렇다면 다음 코드를 살펴보자
var obj2 = {
hello: obj.hello,
username : "aron"
}
obj2.hello(); // hello, aron
아까와는 전혀 다른 결과가 출력된다.
obj.hello()
표현식은 obj
에서 hello
프로퍼티를 찾고, 수신자 객체 obj
로 호출한다.
obj2.hello()
표현식은 obj2
의 hello
프로퍼티를 찾고 이는 obj.hello()
와 동일한 함수지만 수신자 객체는 obj2가 된다.
이처럼 어떤 객체의 메서드를 호출하면 메서드를 찾고, 해당 객체를 수신자 객체로 사용한다.
function hello(){
return "hello, "+ this.username;
}
이 방법은 여러 개의 객체에서 공유하는 함수를 미리 선언해 둘 때 유용하게 사용한다.
var obj1 = {
hello:hello,
username : "abc"
}
obj1.hello() // hello abc
var obj2 = {
hello:hello,
username:"def"
}
obj2.hello() // hello def
하지만 this
를 사용하는 함수는, 메서드로써 호출할 때는 유용하지만 함수로써 호출하면 특별히 유용하지는 않다.
hello() // hello undefined
메서드가 아닌 함수를 호출하면 전역객체가 그 수신자가 되고 , 이경우에는 username
이라는 프로퍼티가 없어서 undefined
값을 만들어 내므로 오히려 해가 된다.
전역객체로 바인딩 하는것은 기본적으로 문제의 소지가 있기 때문에 ES5의 스트릭트 모드에서는 this
의 기본 바인딩을 undefined
로 변경되었다.
function hello(){
"use strict"
return "hello, "+ this.username;
}
hello(); //에러 발생
매서드와 일반 함수처럼 생성자 또한 function
으로 정의한다.
function User(name, passwordHash){
this.name = name;
this.passwordHash = passwordHash;
}
다음과 같이 new
연산자로 User
를 실행하면 생성자 처럼 처리된다.
var u = new User("abcd", " 123123123 );
u.name; // "abcd"
메서드나 함수와는 다르게 , 생성자 호출은 this의 값으로 새로운 객체를 전달하고, 암묵적으로 이 객체를 결과로 반환한다. 즉 생성자 함수의 주요한 역할은 객체를 초기화 시키는 것이다.