arguments 객체는 함수 호출 시 전달된 인수(argument)들의 정보를 담고 있는 순회가능한(iterable) 유사 배열 객체(array-like object)이다.
함수 객체의 arguments 프로퍼티는 arguments 객체를 값으로 가지며 함수 내부에서 지역변수처럼 사용된다.
1 2 3 4 5 6
// ES5 var foo = function () { console.log(arguments); };
foo(1, 2); // { '0': 1, '1': 2 }
ES5에서 매개변수 갯수가 확정되지 않은 가변 인자 함수를 구현할 때 arguments 객체가 유용하게 사용된다.
파라미터를 통해 인수를 전달받는 것이 불가능하므로 arguments 객체를 활용하여 인수를 전달받는다. 하지만 arguments 객체는 유사 배열 객체이기 때문에 배열 메소드를 사용하려면 Function.prototype.call, Function.prototype.apply를 사용하여야 하는 번거로움이 있다.
1 2 3 4 5 6 7 8 9 10 11
// ES5 functionsum() { // 가변 인자 함수의 경우, 파라미터를 통해 인수를 전달받는 것이 불가능하므로 arguments 객체를 활용하여 인수를 전달받는다. // arguments 객체를 배열로 변환 var array = Array.prototype.slice.call(arguments); return array.reduce(function (pre, cur) { return pre + cur; }); }
console.log(sum(1, 2, 3, 4, 5)); // 15
ES6의 Arrow function에는 함수 객체의 arguments 프로퍼티가 없다.
1 2 3 4 5
var es5 = function () {}; console.log(es5.hasOwnProperty('arguments')); // true
ES6에서는 rest 파라미터를 사용하여 가변인자를 함수 내부에 배열로 전달할 수 있다. arguments 프로퍼티가 없는 Arrow function에서 가변 인자 함수를 구현하는 경우, rest 파라미터를 사용하여야 한다.
1 2 3 4 5 6 7 8 9
// ES6 const sum = (...args) => { // console.log(arguments); // Uncaught ReferenceError: arguments is not defined console.log(Array.isArray(args)); // true
return args.reduce((pre, cur) => pre + cur); };
console.log(sum(1, 2, 3, 4, 5)); // 15
4.this
function 키워드를 사용하여 생성한 일반 함수와 Arrow function와의 가장 큰 차이점은 this이다.
4.1 일반 함수의 this
일반 함수의 경우, 해당 함수 호출 패턴에 따라 this에 바인딩되는 객체가 달라진다. 콜백함수 내부의 this는 전역 객체 window를 가리킨다.
var pre = new Prefixer('Hi'); console.log(pre.prefixArray(['Lee', 'Kim']));
생성자함수는 1. 빈객체를 생성하고 this를 담을 곳이다, 2.
(A)에서의 this는 생성자 함수 Prefixer가 생성한 객체, 즉 생성자 함수의 인스턴스(위 예제의 경우 pre)이다.
(B)에서 사용한 this는 아마도 생성자 함수 Prefixer가 생성한 객체(위 예제의 경우 pre)일 것으로 기대하였겠지만 이곳에서 this는 전역 객체 window를 가리킨다. 이는 생성자 함수와 객체의 메소드를 제외한 모든 함수(내부함수, 콜백함수 포함)의 내부의 this는 전역객체를 가리키기 때문이다.
해결방법 4가지를 아래에 소개하겠다.
1.that변수를 함수안에 선언해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Solution 1: that = this functionPrefixer(prefix) { this.prefix = prefix; }
Prefixer.prototype.prefixArray = function (arr) { var that = this; // this: Prefixer 생성자 함수의 인스턴스 return arr.map(function (x) { return that.prefix + ' ' + x; }); };
var pre = new Prefixer('Hi'); console.log(pre.prefixArray(['Lee', 'Kim']));