arguments 객체

  • 자바스크립트 함수에서는 인자의 개수를 맞추지 않아도 에러가 나지 않습니다.
    • 입력 인자 개수 < 정의된 인자 개수: undefined 값 할당
    • 입력 인자 개수 > 정의된 인자 개수: 무시
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 객체는 호출된 인자의 개수를 확인하고, 이에 따라 동작을 다르게 해줄 수 있습니다.
    • 함수를 호출 -> 인수들과 함께 암묵적으로 arguments 객체가 함수 내부로 전달 -> 인자들이 배열 형태로 저장 (유사 배열 객체)
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

호출 패턴과 this 바인딩

  • 함수가 호출될 때에는 ‘arguments 객체 + this 인자’가 암묵적으로 전달됩니다.
  • 함수가 호출되는 방식 (호출 패턴)에 따라 this가 다른 객체를 참조(this 바인딩) 합니다.

1. 객체의 메서드 호출할 때 this 바인딩

  • 메서드 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩 됩니다.
var myObject = {
  name: ‘foo’,
  sayName: function () {
    console.log(this.name);
  }
};

var otherObject = {
  name : ‘bar’
};

// otherObject 객체 생성
var otherObject.sayName = myObject.sayName;

// sayName() 메서드 호출
myObject.sayName(); // (출력물) ‘foo’
otherObject.sayName(); // (출력물) ‘bar’

함수를 호출할 때 this 바인딩

  • 해당 함수 내부 코드에서 사용된 this는 전역 객체에 바인딩된다.
    ex) 브라우저에서 자바스크립트 실행 -> 전역 객체 = window 객체

1) 전역 객체와 전역 변수의 관계를 보여주는 예제 코드

var foo =I’m foo”;  // 전역 변수 선언

console.log(foo);               // (출력값) I’m foo
console.log(window.foo); // (출력값) I’m foo

2) 함수를 호출할 때 this 바인딩을 보여주는 예제 코드

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

3) 내부 함수를 호출했을 경우

// 전역 변수 value 정의
var value = 100;

// myObject 객체 생성
var myObject = {
  value: 1,
  func1: function() {
    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();

// (출력값)
func1() called - this.value : 2
func2() called - this.value : 101
func3() called - this.value : 102

  • 이렇게 this가 참조하는 한계를 극복하기 위한 방법
    • 부모 함수 (func1())의 this를 내부 함수가 접근 가능한 다른 변수에 저장 =>that

< 수정된 버전 >

// 내부 함수 this 바인딩
var value = 100;

var myObejct = {
  value : 1, 
  func1 : Function() {
    var that = this;
    
     this.value += 1;
     console.log(“function1() called - this.value:+ this.value);
     
     func2 = Function () {
       that.value += 1;
       console.log(“func2() called - this.value :+ that.value);

       func3 = function () {
         that.value += 1;
         console.log(“func3() called - this.vlaue:+ that.value);
       }
       func3();
     }
     func2();
  }
};

myObject.func1(); 

// (출력값)
func1() called - this.value : 2
func2() called - this.value : 3
func3() called - this.value : 4

  • 이러한 this 바인딩 한계를 극복하기 위해서 this 바인딩을 명시화
    -> call, apply 메서드 제공

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

  • 자바스크립트에서 기존 함수에 new 연산자를 붙여서 호출하면 해당 함수는 생성자 함수로 동작합니다.
  • 일반 함수가 생성자 함수로 동작하지 않도록 함수 이름의 첫 문자를 대문자로 써서 특정 함수가 생성자 함수로 정의되어 있음을 알리도록 권합니다.
// 생성자 함수의 동작 방식

// Person() 생성자 함수
var Persion = function (name) {
  // 함수 코드 실행 전
  this.name = name;
 // 함수 리턴
};

// foo 객체 생성
var foo = new Person(‘foo’);
console.log(foo.name); // (출력값) foo

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

  • 객체 리터럴 방식으로 생성된 객체: 형태의 객체를 재생성할 수 없다.
  • 생성자 함수를 사용 방식으로 생성된 객체: 생성자 함수를 호출할 때 다른 인자를 넘김으로서 같은 형태의 서로 다른 객체 bar 과 baz를 생성할 수 있다.
// 생성자 함수
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); // 프로토타입 : Person

var baz = new Person('baz', 31, 'man');
console.dir(baz); // 프로토타입 : Person

생성자 함수를 new를 붙이지 않고 호출할 경우 (new -> 생성자 함수로 동작)

  • 일반 함수 this = window 전역 객체에 바인딩
  • 생성자 함수 this = 새로 생성되는 빈 객체에 바인딩
// new를 붙이지 않고 생성자 함수 호출 시의 오류
var qux = Person(‘qux’, 20, ‘man’);
console.log(qux); 
// (출력값) undefined -> new를 붙히면 새로 생성된 객체가 리턴되지만 지금은 일반 함수로 호출되었으므로 undefined가 리턴된다.

console.log(window.name);      // (출력값) qux
console.log(window.age);      // (출력값) 20
console.log(window.gender);  // (출력값)  man

(p.114 객체 생성하는 패턴 추가필요)

profile
Android, Flutter 앱 개발자입니다.

0개의 댓글