1. arguments 객체
- 런타임 시에 호출된 인자의 개수를 확인하고 이에 따라 동작을 다르게 해준다.
- 함수를 호출할 때 인수들과 함께 암묵적으로 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
//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
- arguments 객체는 매개변수 개수가 정확하게 정해지지 않은 함수를 구현하거나,
전달된 인자의 개수에 따라 서로 다른 처리를 해줘야 하는 함수를 개발하는데 유용하게 사용할 수 있다.
function sum(){
var result = 0;
for(var i=0; i<arguments.length; i++){
result += arguments[i];
}
return result;
}
console.log(sum(1,2,3)); //출력 결과 : 6
console.log(sum(1,2,3,4,5));//출력 결과 : 15
2. 호출 패턴과 this 바인딩
- 함수 호출 시 arguments 객체 및 this 인자가 함수 내부로 암묵적으로 전달된다.
- this가 이해하기 어려운 이유는 자바스크립트의 여러가지 함수가 호출되는 방식(호출 패턴)에 따라
this가 다른 객체를 참조하기(this 바인딩) 때문이다.
1) 객체의 메서드를 호출할 때 this 바인딩
· 메서드 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩된다.
//myObject 객체 생성
var myObject = {
name: 'foo',
sayName: function(){
console.log(this.name);
}
}
//otherObject 객체 생성
var otherObject = {
name : 'bar'
};
//otherObject.sayName() 메서드
otherObject.sayName = myObject.sayName;
//sayName() 메서드 호출
myObject.sayName(); //출력 결과 : foo
otherObject.sayName(); //출력 결과 : bar
2) 함수를 호출할 때 this 바인딩
var foo = "I'm foo" //전역 변수 선언
console.log(foo); // 출력 결과 : I'm foo
console.log(window.foo); // 출력 결과 : I'm foo
var test = 'This is test';
console.log(window.test);
//sayFoo() 함수
var sayFoo = function(){
console.log(this.test); //sayFoo()함수 호출 시 this는 전역 객체에 바인딩 된다.
}
sayFoo();
// 출력 결과
// This is test
// This is test
· 내부함수를 호출했을 경우에도 this는 전역 변수에 바인딩 되므로 조심해야한다.
//전역 변수 value 정의
var value = 100;
//myObject 객체 생성
var myObject = {
value : 1,
func1 : fucntion(){
/* var that = this; */
this.value +=1;
console.log('func1() called. this.value : ' + this.value);
//func2() 내부 함수
func2 = function(){
this.value +=1;
console.log('func2() called. this.value : ' + this.value);
//func3() 내부 함수
func3 = function(){
this.value +=1;
console.log('func3() called. this.value : ' + this.value);
}
func3();
}
func2();
}
}
myObject.func1();
//출력 결과 /* */ 해제 후 출력결과
// 2 2
// 101 3
// 102 4
3)생성자 함수를 호출할 때 this 바인딩
- 기존 함수에 new 연산자를 붙여서 호출하면 해당 함수는 행성자 함수로 동작한다.
- 생성자 함수 : 함수 이름의 첫 문자를 대문자로 써라
i) 생성자 함수가 동작하는 방식
new 연산자로 자바스크립트 함수를 생성자로 호출하면, 아래와 같은 순서로 동작한다.
① 빈 객체 생성 및 this 바인딩
생성자 함수가 생성한 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를
자신의 프로토 타입 객체로 설정한다.
일반 함수는 this가 window 전역 객체에 바인딩 된다.
② this를 통한 프로퍼티 생성
이후에는 함수 코드 내부에서 this를 사용해서, 앞에서 생성된 빈 객체에
동적으로 프로퍼티나 메서드를 생성할 수 있다.
③ 생성된 객체 리턴
특별하게 return 문이 없을 경우, this로 바인딩된 새로 생성한 객체가 리턴된다.
생성자 함수가 아닌 일반 함수는 return 문이 없으면 undefined가 리턴된다.
this가 아닌 다른 객체를 리턴하는 경우 해당 객체가 리턴된다.
ii) 객체 리터럴 방식과 생성자 함수를 통한 객체 생성 방식의 차이
· 프로토타입 객체(__proto__ 프로퍼티)가 다르다
객체 리터럴 방식 : Object.prototype // 객체 생성자 함수가 Object
생성자 함수 방식 : Person.prototype
※ 자바스크립트 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를
자신의 프로토타입 객체로 설정한다.
iii) 생성자 함수를 new를 붙이지 않고 호출할 경우
· 일반 함수로 동작한다.
· 일반 함수와 생성자 함수는 this 바인딩 방식이 다르기 때문에 오류가 발생할 수 있다.
※ 일반 함수, 생성자 함수 혼용을 피하기 위한 강제 인스턴스 생성 패턴
function A(arg){
if(!(this instanceof A))
return new A(arg);
this.value = arg?arg:0;
}
var a = new A(100);
var b = A(10);
console.log(a.value); //출력 결과 : 100
console.log(b.value); //출력 결과 : 10
console.log(global.value) //출력 결과 : undefiled
4) call과 apply 메서드를 이용한 명시적인 this 바인딩
i)apply(), call()
· apply()메서드를 호출하는 주체는 함수이며, apply메서드도 this를 바인딩 할 뿐 함수호출과 같다.
//생성자 함수
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
}
//foo 빈 객체 생성
var foo = {};
//apply() 메서드 호출
Person.apply(foo, ['foo', 30, 'man']);
console.dir(foo);
//Person('foo',30,'man')함수를 호출하면서, this를 foo객체에 명시적으로 바인딩하는 것
/* call로 바꾼 것은 다음과 같다*/
Person.call(foo, 'foo', 30, 'man');
ii)유사 배열 객체에서 배열 메서드를 사용하기
function myFunction(){
console.dir(arguments);
//arguments.shift(); 에러 발생
//arguments 객체를 배열로 변환
var args = Array.prototype.slice.apply(arguments);
//Array.prototype.slice() 메서드를 호출해라. 이때 this는 arguments 객체로 바인딩해라.
//args가 없는 경우 slice 함수의 리턴은 array이다.
console.dir(args)
}
myFunction(1,2,3);
3. 함수 리턴
- 자바스크립트 함수는 항상 리턴값을 반환한다.
1) 규칙 1 : 일반 함수나 메서드는 리턴값을 지정하지 않을 경우, undefined 값이 리턴된다.
2) 규칙 2 : 생성자 함수에서 리턴값을 입력하지 않을 경우, 생성된 객체가 리턴된다.
3) 규칙 3 : 생성자의 함수의 리턴값이 객체가 아닌 primitive 타입인 경우 무시되고 this가 리턴된다.
'Language > Java Script' 카테고리의 다른 글
자바스크립트 실행 컨텍스트 (0) | 2020.02.24 |
---|---|
자바스크립트 프로토타입 체이닝 (0) | 2020.02.24 |
자바스크립트 함수 형태 (0) | 2020.02.23 |
자바스크립트 함수 객체 (0) | 2020.02.23 |
자바스크립트 함수 선언 (0) | 2020.02.23 |