티스토리 뷰

JavaScript

함수 호출과 this

똑땅해 2018. 1. 16. 00:31

1. arguments 객체

자바스크립트에서는 함수를 호출할 떄 함수 형식에 맞춰 인자를 넘기지 않더라도 에러가 발생하지 않는다.
정의된 함수의 인자보다 적게 함수를 호출할 경우, 넘겨지지 않는 인자에는 undefined 값이 할당된다.
반대의 경우, 초과된 인수는 무시된다.

이러한 특성 때문에 런타임 시에 호출된 인자의 개수를 확인하고 이에 따라 동작을 다르게 해야 할 때가 있다.
이 것을 가능하게 하는 것이 arguments 객체이다. 함수를 호출할 때 암묵적으로 arguments 객체가 함수 내부로 전달된다.
arguments 객체는 함수를 호출할 때 넘긴 인자들이 저장되는 유사 배열 객체이다.


arguments 객체는 다음과 같이 구성되어 있다.

- 함수를 호출할 때 넘겨진 인자(배열 형태)

- length 프로퍼티 : 호출할 때 넘겨진 인자 개수

- callee 프로퍼티 : 현재 실행 중인 함수의 참조값


arguments 객체는 배열이 아니므로 배열 메서드를 사용할 경우 에러가 발생한다는 것에 주의해야 한다.

2. 호출 패턴과 this 바인딩

자바스크립트에서는 함수를 호출할 때 인자값 외에 arguments 객체 및 this 인자가 함수 내부로 암묵적으로 전달된다..
this 인자는 자바스크립트의 여러 가지 함수 호출 패턴에 따라 다른 객체를 참조한다(this 바인딩).

1) 객체의 메서드 호출 시 this 바인딩

객체의 프로퍼티가 함수일 경우, 이 함수를 메서드라고 한다.

메서드를 호출할 때, 메서드 내부 코드에 사용된 this는 해당 메서드를 호출한 객체로 바인딩된다.

2) 함수 호출 시 this 바인딩

자바스크립트에서는 함수를 호출하면, 해당 함수 내부 코드에서 사용된 this는 전역 객체에 바인딩된다.
브라우저에서 자바스크립트를 실행하는 경우 전역 객체는 window 객체가 된다.

함수 호출에서의 this 바인딩 특성은 내부 함수를 호출했을 경우에도 그대로 적용되므로, 내부 함수에서 this를 이용할 때는 주의해야 한다.


내부 함수가 this를 참조하는 자바스크립트의 한계를 극복하려면 부모 함수의 this를 내부 함수가 접근 가능한 다른 변수에 저장하는 방법을 사용한다.


자바스크립트에서는 이와 같은 this 바인딩의 한계를 극복하려고, this 바인딩을 명시적으로 할 수 있도록 call과 apply 메서드를 제공한다.

또한 jQuery, underscore.js 등과 같은 자바스크립트 라이브러리에서는 bind라는 이름의 메서드를 통해 사용자가 원하는 객체를 this에 바인딩할 수 있는 기능을 제공한다.

3) 생성자 함수를 호출할 때 this 바인딩

기존 함수에 new 연산자를 붙여서 호출하면 해당 함수는 생성자 함수로 동작한다. 생성자 함수는 함수 이름의 첫 문자를 대문자로 쓴다.
생성자 함수를 호출할 때, 생성자 함수 코드 내부에서 this는 앞의 메서드나 함수 호출시와 다르게 동작한다.


생성자 함수가 동작하는 방식

1. 빈 객체 생성 및 this 바인딩

생성자 함수 코드가 실행되기 전 빈 객체가 생성되는데, 이 객체는 this로 바인딩된다.
여기서 생성된 객체는 엄밀히 말하면 빈 객체는 아니다.
자바스크립트의 모든 객체는 자신의 부모인 프로토타입 객체와 연결되어 있으며, 이를 통해 부모 객체의 프로퍼티나 메서드를 사용할 수 있기 때문이다. 이렇게 생성자 함수가 생성한 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를 자신의 프로토타입 객체로 설정한다.


2. this를 통한 프로퍼티 생성

이후, 함수 코드 내부에서 this를 사용하여 생성한 객체에 동적으로 프로퍼티나 메서드를 생성할 수 있다.


3. 생성된 객체 리턴

리턴문이 없을 경우, this로 바인딩된 새로 생성한 객체가 리턴된다.
(생성자 함수가 아닌 일반 함수를 호출할 때 리턴값이 명시되어 있지 않으면 undefined가 리턴되는 것을 주의하자)
리턴값이 새로 생성한 객체(this)가 아닌 다른 객체를 반환하는 경우는 this가 아닌 해당 객체가 리턴된다.

// 생성자 함수의 동작 방식

var Person = function(name) {

// 함수 코드 실행 전 - 1

this.name = name;

// 함수 리턴 - 2

};


var foo = new Person('foo');

console.log(foo.name);

1. Person() 함수가 생성자로 호출되면, 함수 코드가 실행되기 전에 빈 객체가 생성된다.

여기서 빈 객체는 Person() 생성자 함수의 prototype 프로퍼티가 가리키는 객체(Person.prototype 객체)를 [[Prototype]] 링크로 연결해서 자신의 프로토타입으로 설정한다. 그리고 이렇게 생성된 객체는 this로 바인딩된다.


2. 리턴값이 없으므로 this로 바인딩한 객체가 생성자 함수의 리턴값으로 반환되어 foo 변수에 저장된다.


객체 리터럴 방식과 생성자 함수를 통한 객체 생성의 차이

// 객체 리터럴
var ryan = {
name: 'ryan',
age: 10,
gender: 'man'
};
console.dir(ryan);

// 생성자 함수
function Children(name, age, gender, position) {
this.name = name;
this.age = age;
this.gender = gender;
}

var neo = new Children('neo', 11, 'woman');
console.dir(neo);

var prodo = new Children('prodo', 12, 'man');
console.dir(prodo);

결과


객체 리터럴 방식은 자신의 프로토타입 객체가 Object이며, 생성자 함수 방식의 경우는 Children 이다.


이러한 차이가 발생하는 이유는 자바스크립트의 객체 생성 규칙 때문이다.

자바스크립트 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를 자신의 프로토타입 객체로 설정한다.

객체 리터럴 방식에서는 객체 생성자 함수는 Object()이며, 생성자 함수 방식의 경우는 생성자 함수 자체,

두 가지 방식이 다른 프로토타입 객체가 있는 것이다.



'JavaScript' 카테고리의 다른 글

함수의 다양한 형태  (0) 2018.01.15
함수 객체  (0) 2018.01.13
함수 선언  (0) 2017.12.30
자바스크립트 패턴 - 객체 생성 패턴  (0) 2017.10.28
자바스크립트 패턴 - 함수  (0) 2017.09.24
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/09   »
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
글 보관함