ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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

Designed by Tistory.