Open eunzy38 opened 4 years ago
3-2 명시적으로 this를 바인딩하는 방법
3-2-1 call 메서드
Function.prototype.call[thisArg[, arg1[, arg2[, ...]]]);
someFunction.call("지정할 객체","인자1","인자2",...);
3-2-2 apply 메서드
Function.prototype.apply(thisArg[, argsArray]);
someFunction.apply("지정할 객체","배열");
3-2-3 call / apply 메서드의 활용
3-2-4 bind 메서드
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]]);
var newfunc = function(){console.log("test");}.bind();
3-2-5 화살표 함수의 예외사항
3-2-6 별도의 인자로 this를 받는 경우(콜백 함수 내에서의 this) 요소를 순회하면서 콜백 함수를 반복 호출하는 내용의 일부 메서드(배열 메서드)는 별도의 인자로 this를 받기도 함
메서드의 호출 주체인 함수를 즉시 실행하도록하는 명령어이며, call 메서드를 사용하면 임의의 객체를 지정할 수 있다.
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,
mathod: function (x,y) {
console.log(this a , x, y);
}
}
obj.method( 5,6); // 1 2 3
obj.method.call({a:4},5,6); // 4 5 6
call 메서드와 기능적으로 동일하다. 다만 call 메서드는 첫 번째 인자를 제외한 모든 인자들을 호출할 함수의 매개변수로 지정하지만 apply 메서드는 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정한다.
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,
mathod: function (x,y) {
console.log(this a , x, y);
}
}
obj.method.apply({a:4},[5,6]); // 4 5 6
유사배열객체에 배열 메서드를 적용 키가 0 또는 양의 정수인 프로퍼티가 존재하고 length 프로퍼티의 값이 0 또는 양의정수인 객체 유사배열객체의 경우 call 또는 apply 메서드를 이용해 배열 메서드를 차용할 수 있다.
생성자 내부에서 다른 생성자를 호출 생성자 내부에 다른 생성자와 공통된 내용이 있는 경우 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;
}
var by = new Student('보영', 'female', '단국대');
var jn = new Employee('보영', 'female', '구글');
여러 인수를 묶어 하나의 배열로 전달하고 싶을 때 여러 개의 인수를 받는 메서드에게 하나의 배열로 인수를 전달하고 싶을 때 apply 메서드를 사용하면 편리하다.
var number =[10, 20, 3, 16, 45];
var max = Math.max.apply(null, number);
var min = Math.min.apply(null, number);
console.log(max, min);
es5에서 추가 된 기능으로 call과 비슷하지만 즉시 호출하지는 않고 넘겨 받은 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
name 프로퍼티 nmae 프로퍼티에 도상 bind의 수동태인 bound라는 접두사가 붙는다.
console.log(func.name) // func
console.log(bondFunc.name); // bound func
상위 컨텍스트의 this를 내부함수나 콜백함수에 전달하기
call, apply, bind 메서드를 사용한다면 self 등의 변수를 활용한 우회 방법보다 더 간단히 처리할 수 있다.
var obj = {
outer: function() {
console.log(this);
var innerfunc = function() {
console.log(this);
}
innerfunc.call(this);
}
}
//////
var obj = {
outer: function() {
console.log(this);
var innerfunc = function() {
console.log(this);
}.bind(this);
innerfunc();
}
}
ES6에 도입된 화살표 함수는 실행 컨텍스트 생성 시 this를 바인딩하는 과정이 제외 되었다.
var obj = {
outer: function () {
console.log(this);
var innerFunc = () => {
console.log(this);
};
innerFunc();
}
}
obj.outer;
콜백 함수를 인자로 받는 메서드 중 일부는 추가로 this로 지정할 객체를 인자로 지정할 수 있는 경우가 있다.
var report = {
sum: 0,
count: 0,
add: function() {
var args = Array.prototype.slice.call(arguments);
args.forEach(function (entry) {
this.sum += entry;
++this.count;
},this);
},
average: function() {
return this.sum / this.count;
}
};
report.add(60, 85, 95);
console.log(report.sum, report.count, report.average()); // 240 3 88
call 메서드는 첫번째 인자를 제외한 나머지 모든 인자들을 호출할 함수의 매개변수로 지정하는 반면, apply 메서드는 두번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정한다
키가 0 또는 양의 정수인 프로퍼티가 존재하고 length 프로퍼티의 값이 0 또는 양의 정수인 객체, 즉 배열의 구조와 유사한 객체의 경우(유사배열객체) call 또는 apply 메서드를 이용해 배열 메서드를 차용할 수 있다
생성자 내부에 다른 생성자와공통된 내용이 있을 경우 call 또는 apply를 이용해 다른 생성자를 호출하면 간단하게 반복을 줄일 수 있다
여러 개의 인수를 받는 메서드에게 하나의 배열로 인수들을 전달하고 싶을 때 apply 메서드 사용
call/apply 메서드는 명시적으로 별도의 this를 바인딩하면서 함수 또는 메서드를 실행하는 훌륭한 방법 단점: 이로 인해 this를 예측하기 어렵게 만들어 코드 해석을 방해하게 됨
name 프로퍼티에 동사 bind의 수동태인 'bound'라는 접두어가 붙음
self 변수를 활용한 우회방법보다 call, apply, bind 메서드를 이용하면 더 깔끔하게 처리가 가능
콜백 함수를 인자로 받는 메서드 중 일부는 추가로 this로 지정할 객체를 인자로 지정할 수 있는 경우가 있음
function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
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
function.prototype.apply(thisArg[, argsArray])
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
유사배열객체에 배열 메서드를 적용
생성자 내부에서 다른 생성자를 호출
여러 인수를 묶어 하나의 배열로 전달하고 싶을 때 - apply 활용
function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
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
name 프로퍼티
var func = function (a, b, c, d) { console.log(this, a, b, c, d); }; var bindFunc = function({ x : 1}, 4, 5); console.log(func.name); // func console.log(bindFunc.name); //bound func
상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
var obj = { outer: function() { console.log(this); var innerFunc = function() { console.log(this); }; innerFunc.call(this); } }; obj.outer(); --------------------------------------- var obj = { outer : function() { console.log(this); var innerFunc = function() { console.log(this); }.bind(this); innerFunc(); } }; obj.outer();
2. 명시적으로 this를 바인딩하는 방법 2-1. call 메서드
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
2-2. apply 메서트
Function.portotype.apply(thisArg[, argsArray])
2-3. call / apply 메서드의 활용
유사배열객체에 배열 메서드를 적용
생성자 내부에서 다른 생성자를 호출
2-4. bind 메서드
name 프로퍼티
상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
2-5. 화살표 함수의 예외사항
2-6. 별도의 인자로 this를 받는 경우(콜백함수 내에서의 this)
콜백 함수와 함께 thisArg를 인자로 받는 메서드
Array.prototype.forEach(callback[, thisArg]) Array.prototype.map(callback[, thisArg]) Array.prototype.fliter(callback[, thisArg]) Array.prototype.some(callback[, thisArg]) Array.prototype.every(callback[, thisArg]) Array.prototype.find(callback[, thisArg]) Array.prototype.findIndex(callback[, thisArg]) Array.prototype.from(callback[, thisArg]) sat.prototype.forEach(callback[, thisArg]) Map.prototype.forEAch(callback[, thisArg])
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
let 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
## 2-2. apply 메서드
```javascript
Function.prototype.apply(thisArg[, argsArray]);
var obj = {
0:'a', 1:'b', 2:'c', length : 3
};
Array.prototype.push.call(obj, 'd'); // push : 마지막에 추가
console.log(obj); // { 0:'a', 1:'b', 2:'c', 3:'d', length : 4}
var arr = Array.prototype.slice.call(obj); // slice : 배열의 일부를 선택하여 새로운 배열을 만듬 console.log(arr); // ['a', 'b', 'c', 'd']
- push() 메서드 : 배열의 끝에 원소를 추가할 때 사용하는 메서드
- slice() 메서드 : 시작 인덱스값과 마지막 인덱스값을 받아 시작값부터 마지막값의 앞부분까지의 배열 요소를 추출하는 메서드이나, 매개변수를 아무것도 넘기지 않을 경우에는 그냥 원본 배열의 얕은 복사본을 반환한다.
### 2-3-2. 생성자 내부에서 다른 생성자를 호출
생성자 내부에 다른 생성자와 공통된 내용이 있을 경우 call 또는 apply를 이용해 다른 생성자를 호출하면 간단하게 반복을 줄일 수 있다.
### 2-3-3. 여러 인수를 묶어 하나의 배열로 전달하고 싶을 때 - apply 활용
여러 개의 인수를 받는 메서드에게 하나의 배열로 인수들을 전달하고 싶을 때 apply 메서드를 사용하는 것이 좋다.
### 2-3-4. bind 메서드
```javascript
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]]);
var obj = {
outer : function(){
console.log(this); //{outer: ƒ}
var innerFunc = () => {
console.log(this); //{outer: ƒ}
};
innerFunc();
}
};
obj.outer();
화살표 함수로 바꾸는 경우 별도의 변수로 this를 우회하거나 call/apply/bind를 적용할 필요가 없어 간결하게 관리가 가능
Array.prototype.forEach();
Set.prototype.forEach();
Map.prototype.forEach();
Array.prototype.map(); Array.prototype.filter(); Array.prototype.some(); Array.prototype.every(); Array.prototype.find(); Array.prototype.findIndex(); Array.prototype.flatMap(); Array.prototype.from();
thisArg를 인자로 받는 메서드는 여러개가 있다.
study 완료 후 체크 부탁드립니다.