-
[JAVASCRIPT]함수와 프로토타입 체이닝(2)Programming/JAVASCRIPT 2019. 12. 4. 17:43
함수 호출과 this
arguments 객체
자바스크립트는 함수를 호출할 때 함수 형식에 맞춰 인자를 넘기지 않더라도 에러가 나지 않음
ex) 함수 형식에 맞춰 인자를 넘기지 않더라도 함수 호출 가능 코드
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
* 만약 C를 이런 방식으로 코딩하면 바로 에러를 내며 프로그램 종료
* 이러한 자바스크립트의 특성 때문에 함수 코드 작성시, 런타임 시에 호출된 인자의 개수를 확인하고 이에 따른 동작을 다르게 해줘야 하는 경우가 존재
-> 이를 가능하게 해주는 것이 arguments 객체
자바스크립트에서 함수를 호출할 때 인수들과 함께 암묵적으로 arguments 객체가 함수 내부로 전달 (유사 배열 객체)
ex) arguments 객체 예제 코드
// add() 함수
function add(a, b) {
// arguments 객체 출력
console.dir(arguments);
return a + b;
}
console.log(add(1)); // (출력) NaN
console.log(add(1, 2)); // (출력) 3
console.log(add(1, 2, 3)); // (출력) 3
* console.dir(arguments)를 실행시 length: 로 인자의 갯수 같이 넘어감
* arguments 객체는 매개변수 개수가 정확하게 정해지지 않은 함수를 구현하거나, 전달된 인자의 개수에 따라 서로 다른 처리를 해줘야 하는 함수를 개발하는 데 유용하게 사용할 수 있음
ex) 이런식으로 접근 가능
function sum() {
var result = 0;
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return ;
}
console.log(sum(1, 2, 3)); // (출력) 6
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9)); // (출력) 45
호출 패턴과 this 바인딩
* 자바스크립트에서 함수 호출할 때, 기존 매개변수로 전달되는 인자값에 더해, arguments 객체 및 this 인자가 함수 내부로 암묵적으로 전달
객체의 메서드 호출할 때 this 바인딩
* 메서드를 호출할 때, 메서드 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩
ex) 메서드 호출 사용 시 this 바인딩
// myObject 객체 생성
var myObject = {
name: 'baek',
sayName: function() {
console.log(this.name);
}
};
//otherObject 객체 생성
var otherObject = {
name: 'bar'
};
// otherObject.sayName() 메서드
otherObject.sayName = myObject.sayName;
// sayName() 메서드 호출
myObject.sayName();
otherObject.sayName();
(출력)
baek
bar
함수를 호출할 때 this 바인딩
* 자바스크립트에서는 함수를 호출하면 , 해당 함수 내부 코드에서 사용된 this는 전역 객체에 바인딩'
ex) 전역 객체와 전역 변수의 관계를 보여주는 예제
var baek = "I'm baek"; // 전역 변수 선언
console.log(baek); // (출력) I'm baek
console.log(window.baek); // (출력) I'm baek
* 전역 변수는 전역 객체(window)의 프로퍼티로도 접근할 수 있음
ex) 함수를 호출할 때 this 바인딩을 보여주는 예제
var test = 'This is test';
console.log(window.test);
//sayHan() 함수
var sayHan = function() {
console.log(this.test); // sayHan() 함수 호출시 this는 전역 객체에 바인딩
};
sayHan();
(출력)
This is test
This is test
* 내부함수를 호출했을 경우에도 그대로 적용되므로, 내부 함수에서 this 이용시 주의!
ex) 내부 함수의 this 바인딩 동작을 보여주는 예제
// 전역 변수 value 정의
var value = 100;
// myObject 객체 생성
var myObject = {
value: 1,
func1: function() {
this.value += 1;
console.log('func1() called. this. value : ' + this.value);
func2 = function() {
that.value += 1;
console.log('fun2() called, this.value: ' + this.value);
// func3() 내부 함수
func3 = function() {
that.value += 1;
console.log('func3() called. this.value : ' + this.value);
}
func3(); // func3() 내부 함수 호출
}
func2() 내부 함수 호출
}
};
myObject.func1(); // func1() 메서드 호출
(출력)
func1() called - this.value : 2
func2() called - this.value : 101
func3() called - this.value : 102
* 예상과 다른 이유는 내부 함수 호출 패턴을 정의해 놓지 않기 때문
* 내부 함수도 결국 함수라 이를 호출시 함수 호출 패턴 규칙에 따라 내부 함수의 this는 전역 객체(window)에 바인딩
// 내부 함수가 this를 참조하는 자바스크립트의 한계를 극복하기위해 부모 함수(위에 경우 func1() 메서드)의 this를 내부 함수가 접근 가능한 다른 변수에 저장하는 방법 사용
* 관례상 this 값을 저장하는 변수의 이름 that 이라 칭함
ex) 내부 함수의 this 바인딩 문제를 해결한 예제
// 내부 함수 this 바인딩
var value = 100;
// myObject 객체 생성
var myObject = {
value: 1,
func1: function() {
var that = this;
this.value += 1;
console.log('func1() called. this. value : ' + this.value);
// func2() 내부 함수
func2 = function() {
that.value += 1;
console.log('fun2() called, this.value: ' + that.value);
// func3() 내부 함수
func3 = function() {
that.value += 1;
console.log('func3() called. this.value : ' + that.value);
}
func3(); // func3() 내부 함수 호출
}
func2() 내부 함수 호출
}
};
myObject.func1(); // func1() 메서드 호출
* func1() 에서 this를 that이라는 변수에 저장하고, 이후 내부 변수에서는 that으로 부모 함수의 this가 가리키는 객체에 접근
생성자 함수를 호출할 때 this 바인딩
* 여러가지 다른 인자를 넘김으로써 같은 형태의 서로 다른 객체를 생성할 수 있음
ex) 생성자 함수
function Person(name, age, gender, position) {
this.name = name;
this.age = age;
this.gender = gender;
}
// Person 생성자 함수를 이용해 bar 객체, baz 객체 생성
var bar = new Person('bar', 33, 'woman');
console.dir(bar);
var baz = new Person('baz', 25, 'woman');
console.dir(baz);
* 객체 리터럴 방식과 생성자 함수 방식의 차이는 프로토타입 객체(__proto__ 프로퍼티)에 있음
* 객체 리터럴 방식 프로토타입 객체 : Object.prototype
* 생성자 함수 방식 프로토타입 객체 : 생성자 함수 자체가 프로토 타입 객체가 됨
-> 예제에서는 Person.prototype
'Programming > JAVASCRIPT' 카테고리의 다른 글
[JAVASCRIPT] 실행 컨텍스트와 클로저(1) (0) 2019.12.04 [JAVASCRIPT] 함수와 프로토타입 체이닝(3) (0) 2019.12.04 [JAVASCRIPT] 함수와 프로토타입 체이닝(1) (0) 2019.12.04 [JAVASCRIPT] 데이터 타입과 연산자(3) (0) 2019.12.04 [JAVASCRIPT] 데이터 타입과 연산자(2) (0) 2019.12.04