[JavaScript] 03. this
this
-
this 는 실행 컨텍스트가 생성될 때 함께 결정 => 함수를 호출할 때 결정
-
상황에 따른 this
-
전역 공간
- 전역 객체를 가리킴
- 전역 컨텍스트를 생성하는 주체가 바로 전역 객체기 때문
- 브라우저에선
window
, Node에서는global
-
메서드로서 호출할 때 그 메서드 내부
-
함수 vs 메서드 ?
-
메서드 : 객체의 프로퍼티에 할당된 상태에서 객체의 메서드로 호출할 경우
-
함수 : 위의 경우가 아닌 경우 모두 함수로 동작
var func = function (x) { console.log(this, x); }; func(1); // Window { ... } var obj = { method: func }; obj.method(2); // { method: f } obj['method'](2); // { method: f }
-
-
메서드 내부에서 this
-
this는 호출한 주체에 대한 정보가 담김
-
함수를 메서드로 호출하는 경우 주체는 함수명 앞의 객체가 됨
var obj = { methodA: function () { console.log(this); }, inner: { methodB: function () { console.log(this); } } }; obj.methodA(); // { methodA: f, inner: {...} } obj.inner.methodB(); // { methodB: f }
-
-
-
함수로 호출할 때 그 내부에서의 this
-
함수 내부에서의 this
-
함수로서 호출하는 것은 호출 주체를 명시하지 않고 개발자가 코드에 직접 관여해서 실행한 것
-
호출 주체의 정보를 알 수 없으므로 this는 전역 객체를 가리킴
-
더글라스 크락포드는 이를 명백한 설계상의 오류라고 말함
var obj1 = { outer: function () { console.log(this); var innerFunc = function () { console.log(this); }; innerFunc(); var obj2 = { innerMethod: innerFunc }; obj2.innerMethod(); } }; obj1.outer(); // obj1 / window / obj2 가 this가 됨
-
this 바인딩은 함수를 실행하는 당시의 주변 환경은 중요하지 않고, 오직 해당 함수를 호출하는 구문 앞에 점 또는 대괄호 표기가 있는지 없는지에 따라 바인딩 됨
-
-
메서드 내부 함수에서 this를 우회하는 방법
-
ES5 : 변수를 활용
var obj = { outer: function () { console.log(this); // { outer: f } var innerFunc1 = function () { console.log(this); // Window { ... } }; innerFunc1(); var self = this; var innerFunc2 = function () { console.log(self); // { outer: f } }; innerFunc2(); } }; obj.outer();
-
ES6
- 화살표 함수를 사용
- 화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠지게 됨 -> 상위 스코프의 this를 그대로 활용 가능
var obj = { outer: function () { console.log(this); // { outer: f } var innerFunc = () => { console.log(this); // { outer: f } }; innerFunc(); } }; obj.outer();
- call, apply 등의 메서드를 활용하는 방법도 있음
-
-
-
콜백 함수 호출 시 그 함수 내부에서의 this
-
콜백 함수에서 this는 제어권을 가지는 함수(메서드)가 콜백 함수에서 this를 무엇으로 할지에 따라 달라짐
-
특별히 정의하지 않은 경우에는 기본적으로 함수와 마찬가지로 전역객체를 바라봄
setTimeout(function () { console.log(this); }, 300); [1, 2, 3, 4, 5].forEach(function (x) { console.log(this, x); }); document.body.innerHTML += '<button id="a">클릭</button>'; document.body.querySelector('#a').addEventListener('click', function (e) { console.log(this, e); }); // (1), (2) : this 는 전역 객체, (3) : this는 querySelector('#a')
-
-
생성자 함수 내부에서의 this
-
프로그래밍적으로 '생성자'는 구체적인 인스턴스를 만들기 위한 일종의 틀
-
자바스크립트에서는 new 명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작하게 됨
-
생성자 함수를 호출하면 생성자의 prototype 프로퍼티를 참조하는
__proto__
라는 프로퍼티가 있는 객체(인스턴스)를 만들고, 미리 준비된 공통 속성 및 개성을 해당 객체(this)에 부여var Cat = function (name, age) { this.bark = '야옹'; this.name = name; this.age = age; }; var choco = new Cat('초코', 7); var nabi = Cat('나비', 5); console.log(choco, nabi); // Cat {bark: '야옹', name: '초코', age: 7} undefined
-
-
-
명시적으로 this를 바인딩하는 방법
-
call 메서드
-
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
-
call 메서드는 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령
-
call 메서드를 이용하면 임의의 객체를 this로 지정할 수 있음
var func = function (a, b, c) { console.log(this, a, b, c); }; func(1, 2, 3); // Window{ ... } 1 2 3 func.call({ x: 1 }, 4, 5, 6) // { x: 1 } 4 5 6 var obj = { a: 1, method: function (x, y) { console.log(this.a, x, y); } }; obj.method(2, 3); // 1 2 3 obj.method.call({ a: 4 }, 5, 6); // 4 5 6
-
-
apply 메서드
-
Function.prototype.apply(thisArg[, argsArray])
-
apply 메서드는 call 메서드와 기능적으로 완전히 동일
-
apply
는 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정 -
call
은 첫 번째 인자를 제외한 나머지 모든 인자들을 호출할 함수의 매개변수로 지정var func = function (a, b, c) { console.log(this, a, b, c); }; func.apply({x: 1}, [4, 5, 6]); // { x: 1 } 4 5 6 var obj = { a: 1, method: function (x, y) { console.log(this.a, x, y); } }; obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
-
-
call / apply 메서드의 활용
-
유사배열객체에 배열 메서드를 적용
- 유사배열객체 : 키가 0 또는 양의 정수인 프로퍼티가 존재하고 length 프로퍼티 값이 0 또는 양의 정수인 객체
- ES6에서는 유사배열객체 또는 순회 가능한 모든 종류의 데이터 타입을 배열로 전환하는
Array.from
메서드를 도입
-
생성자 내부에서 다른 생성자를 호출
-
생성자 내부에 닫른 생성자와 공통된 내용이 있을 경우 call 또는 apply를 이용해 다른 생성자를 호출
function Person(name, gender) { this.name = name; this.gender = gender; } function Student(name, gender, school) { Person.call(this, name, gender); this.school = school; } function Employee(name, gender, company) { Person.apply(this, [name, gender]); this.company = company; }
-
-
여러 인수를 묶어 하나의 배열로 전달하고 싶을 때 (apply) -> spread operator로 대체 가능
-
-
bind 메서드
-
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
-
ES5에 추가, call과 비슷하지만 즉시 호출하지는 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하기만 하는 메서드
-
함수에 this를 미리 적용하는 것과 부분 적용 함수를 구현하는 두 가지 목적을 지님
var func = function (a, b, c, d) { console.log(this, a, b, c, d); }; func(1, 2, 3, 4); // Window{ ... } 1 2 3 4 var bindFunc1 = func.bind({ x: 1 }); bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8 var bindFunc2 = func.bind({ x: 1 }, 4, 5); bindFunc2(6, 7); // { x: 1 } 4 5 6 7 bindFunc2(8, 9); // { x: 1 } 4 5 8 9
-
-
Author And Source
이 문제에 관하여([JavaScript] 03. this), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rkd028/JavaScript-03.-this저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)