Programming/JAVASCRIPT

[JAVASCRIPT] 함수와 프로토타입 체이닝(3)

100winone 2019. 12. 4. 17:43

call과 apply 메서드를 이용한 명시적인 this 바인딩

* call() 메서드는 apply() 메서드와는 기능이 같음 단지 넘겨받는 인자의 형식만 다름

* apply() 메서드도 this를 특정 객체에 바인딩할 뿐 결국 본질적인 기능은 함수호출

-> 만약 Person() 이라는 함수가 있고, Person.apply() 호출하면 기본적인 기능은 Person() 함수 호출

function.apply(thisArg, argArray)

-> 첫 번째 thisArg는 apply() 메서드를 호출한 함수 내부에서 사용한 this에 바인딩할 객체를 가리킴

-> 두 번째 argArray 인자는 함수를 호출할 때 넘길 인자들의 배열을 가리킴

** 두 번째 인자인 argArray 배열을 자신을 호출한 함수의 인자로 사용하되, 이 함수 내부에서 사용된 this는 첫 번째 인자인 thisArg 객체로 바인딩해서 함수를 호출하는 기능

ex) 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');

유사 배열 객체에메서드를 사용하는 경우

- > arguments 객체는 실제 배열이 아니므로 pop(), shift() 같은 표준 배열 메서드를 사용할 수 없지만 apply() 메서드를 사용하면 가능

ex) apply() 메서드를 활용한 arguments 객체의 배열 표준 메서드 slice() 활용 코드

function myFunction() {

console.dir(arguments); // 얘 프로토타입 Object

// arguments.shift(); 에러 발생

// arguments 객체를 배열로 전환

var args = Array.prototype.slice.apply(arguments);

console.dir(args); // 얘 프로토타입 Array[0]

}

myFunction(1, 2, 3);

함수 리턴

자바스크립트 함수는 항상 리턴값을 반환

규칙 1) 일반 함수나 메서드는 리턴값을 지정하지 않을 경우, undefined 값이 리턴

ex) return 문 없는 일반 함수의 리턴값 확인

// noReturnFunc() 함수

var noReturnFunc = function() {

console.log('This function has no return statement');

};

var result = noReturnFunc();

console.log(result);

(출력)

This function has no return statement

undefined

규칙 2) 생성자 함수에서 리턴값을 지정하지 않을 경우 생성된 객체가 리턴

*생성자 함수는 리턴값을 일반적으로 지정하지 않음

ex) 생성자 함수에서 명시적으로 객체를 리턴했을 경우

// Person() 생성자 함수

function Person(name, age, gender) {

this.name = name;

this.age = age;

this.gender = gender;

// 명시적으로 다른 객체 변환

return {name: 'bar', age:20, gender:'woman'};

}

var foo = new Person('foo', 30, 'man');

console.dir(foo);

* return 값을 설정하면 밑에 새 객체를 만들더라도 return 값에서 명시적으로 넘긴 객체나 배열이 리턴됨

return이 없다면 foo 객체가 출력

프로토타입 체이닝

프로토타입의 두 가지 의미

* 자바스크립트의 모든 객체는 자신의 부모인 프로토타입 객체를 가리키는 참조 링크 형태의 숨겨진 프로퍼티가 있음

-> 이러한 링크를 암묵적으로 프로토타입 링크 라고 부름

* prototype 프로퍼티와 객체의 숨은 프로퍼티인 [[Prototype]] 링크를 구분해야 함

-> 자바스크립트에서 모든 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 포로토타입 객체를 자신의 부모 객체로 설정하는 [[Prototype]] 링크로 연결

ex) prototyype 프로퍼티와 [[Prototype]] 링크 구분

// Person 생성자 함수

function Person(name) {

this.name = name;

}

//foo 객체 생성

var foo = new Person('foo');

console.dir(Person);

console.dir(foo);

* Person() 생성자 함수로 생성된 foo 객체는 Person() 함수의 프로토타입 객체를 [[Prototype]] 링크로 연결. 즉 prototype 프로퍼티나 [[Prototype]] 링크는 같은 프로토타입 객체를 가리킴

프로토타입 체이닝의 종점

* Object.prototype은 프로토타입 체이닝의 종점!!

-> 모든 자바스크립트 객체는 프로토타입 체이닝으로 Object.prototype 객체가 가진 프로퍼티와 메서드에 접근하고, 서로 공유 가능

기본 데이터 타입 확장

ex) String 기본 타입에 메서드 추가

String.prototype.testMethod = function() {

console.log('This is the String.prototype.testMode()');

};

var str = "this is test";

str.testMethod();

console.dir(String.prototype);