일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 자바
- 자바스크립트 이벤트중지
- 자바 순열 코드
- Interface
- inner class
- 알고리즘
- char to str
- 재귀
- 재귀함수
- jquery dom 계층 선택자
- 자바입출력
- Java
- 후위표기
- 자바스크립트 이벤트처리
- 순열 재귀
- 알고리즘 그래프
- str to char array
- java 내부 클래스
- java Collections.sort()
- java lambda
- jquery 속성선택자
- 자바 조합 재귀
- 조합 재귀
- 순열코드
- 자바 재귀 조합
- 상속
- parseInt()
- 서로소
- jquery 필터선택자
- jquery 이벤트 처리
- Today
- Total
유블로그
자바스크립트 함수 호출과 this 본문
arguments 객체
function func(arg1, arg2) {
console.log(arg1, arg2);
};
func(); // undefined undefined
func(1); // 1 undefined
func(1,2); // 1 2
func(1,2,3); // 1 2
함수를 호출할 때 같이 넘긴 인자들이 arguments 라는 유사 배열 객체에 담겨 전달된다.
이 객체의 구성은
- 함수 호출 시 넘겨진 인자들 : 유사배열 형태로, 첫번째 인자는 0번 인덱스, 두번째 인자는 1번 인덱스.. 에 저장됨. 배열은 아니므로 배열 함수 사용 불가
- length 프로퍼티 : 전달된 인자 개수
- callee 프로퍼티 : 현재 실행중인 함수의 참조값
가 있다.
arguments 객체는 매개변수 개수가 정확하게 정해져있지않거나, 전달된 인자 개수마다 다른 처리를 해줘야할 때 유용하다.
function sum() {
var result = 0;
for(var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
};
console.log(sum(1)); // 1
console.log(sum(1,2,3)); // 6
이렇게 sum() 안에 인자 개수를 정확히 적지 않아도 arguments 객체를 이용하여 인자에 접근할 수 있다.
호출 패턴과 this 바인딩
(1) 객체 메서드 호출 시 this 바인딩
var obj1 = {
name: '이름1',
sayName: function () {
console.log(this.name);
}
};
var obj2 = {
name: '이름2'
};
obj2.sayName = obj1.sayName;
obj1.sayName(); // 이름1
obj2.sayName(); // 이름2
obj2의 sayName은 obj1의 sayName과 같은 함수를 참조하지만
this는 호출한 객체에 바인딩 하기 때문에
obj1 과 obj2 의 sayName() 결과가 다르다.
(2) 함수 호출 시 this 바인딩
함수 호출 시 함수 내부 코드에서 사용된 this는 전역 객체에 바인딩된다 !
브라우저에서 자바스크립트를 실행하는 경우에 전역 객체는 window 이다.
var test = 'hello';
console.log(test); // hello
console.log(window.test); // hello
var sayTest = function() {
console.log(this.test);
};
sayTest(); // hello
자바스크립트의 전역 변수는 전역 객체인 window의 프로퍼티다.
내부 함수에서도 this 가 전역 객체에 바인딩된다 !
var val = 100;
var obj = {
value: 1,
func1: function () {
this.value += 1;
console.log(this.value);
func2 = function () {
this.value += 1;
console.log(this.value);
func3 = function () {
this.value += 1;
console.log(this.value);
}
func3();
}
func2();
}
};
obj.func1();
위 코드의 출력은
2
101
102
이다.
이 상태!
그렇다면 내부함수에서 부모 함수가 가리키는 this (obj) 에 접근하려면 ?
that 이라는 변수를 사용한다.
var val = 100;
var obj = {
value: 1,
func1: function () {
this.value += 1;
console.log(this.value);
func2 = function () {
that.value += 1;
console.log(that.value);
func3 = function () {
that.value += 1;
console.log(that.value);
}
func3();
}
func2();
}
};
obj.func1();
출력 결과
2
3
4
이렇게 바꿀 수 있다 !
(3) 생성자 호출 시 this 바인딩
var Person = function (name) {
this.name = name;
};
var yj = new Person('yj');
console.log(yj.name); // yj
만약 생성자 함수를 호출할 때 new 키워드를 붙이지 않거나, 일반 함수에 new를 붙이면 this가 원하지 않는 곳에 바인딩된다.
var Person = function (name, age) {
this.name = name;
this.age = age;
};
var yj = Person('yj', 10);
console.log(yj); // undefined
console.log(window.name); // yj
console.log(window.age); // 10
위처럼 Person 함수에 작성된 this는 window 객체에 바인딩되어 yj 객체를 출력하면 undefined 가 나온다.
일반 함수에서 return 값이 없으면 undefined 가 나오기 때문이다.
자바스크립트에서 일반 함수와 생성자 함수 구분이 없으므로
생성자 함수는 앞글자를 대문자로 쓰자 !
그래도 new 를 사용하지 않아 발생하는 에러를 막기 위해 다음과 같은 코드를 쓰기도 한다고 한다.
var Person = function (arg) {
if(!(this instanceof Person)) {
return new Person(arg);
}
this.value = arg ? arg : 0;
};
if(!(this instanceof arguments.callee))
arguments의 callee 는 호출한 함수를 가리키기 때문에 이렇게 쓰기도 한다.
(4) call과 apply 메서드를 이용한 this 바인딩
this 를 특정 객체에 바인딩 시키기 위한 방법이다.
apply(), call() 은 Function.prototype 객체의 메서드이다.
apply(함수 내부에서 사용한 this에 바인딩할 객체, 함수를 호출할 때 넘길 인자들의 배열)
function Person (name, age) {
this.name = name;
this.age = age;
};
var yj = {};
Person.apply(yj, ['yj', 10]); // this에 바인딩할 객체를 yj 로 지정
console.log(dir);
// 출력결과
// age: 10
// name: "yj"
이렇게 명시적으로 바인딩할 객체를 지정할 수 있다.
call은 apply의 두번째 인자를 배열 형태 대신 각각 인자로 넘긴다.
Person.apply(yj, ['yj', 10]);
Person.call(yj, 'yj', 10);
위 두 줄은 동일하다.
function func () {
console.dir(arguments);
arguments.shift(); // 에러! arguments 는 유사배열이기 때문에 배열 메서드 사용불가
var args = Array.prototype.slice.apply(arguments);
console.log(args);
}
func(1,2,3);
Array.prototype.slice.apply(arguments); 를 사용하면
Array.prototype.slice() 를 호출하는데, this를 arguments 에 바인딩함으로써
arguments.slice() 형태로 사용할 수 있다.
이 때 args 의 prototype은 Array.prototype 이다.
출처: 송형주, 고현준, 『인사이트 자바스크립트』, 한빛미디어(2020)
'JavaScript & jQuery' 카테고리의 다른 글
자바스크립트 실행 컨텍스트 생성 과정 (0) | 2021.06.19 |
---|---|
자바스크립트 프로토타입 체이닝 (0) | 2021.06.18 |
자바스크립트 콜백함수, 즉시 실행 함수, 내부 함수 등 (0) | 2021.06.18 |
자바스크립트 함수 객체 (0) | 2021.06.18 |
자바스크립트 함수, 함수 호이스팅 (0) | 2021.06.18 |