일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 제너레이터와 async/await
- version management
- middleware pattern
- 블로그 서비스 최적화
- 학습내용정리
- 이미지 갤러리 최적화
- unique identifiers
- js pattern
- 진행기록
- js pattern
- 자바스크립트
- 커리어
- Babel과 Webpack
- 새 코드 받아오기
- 모던 자바스크립트 Deep Dive
- 올림픽 통계 서비스 최적화
- pr review
- 브라우저의 렌더링 과정
- package management
- 스코프
- 이벤트
- 딥다이브
- 자바스크립트 패턴
- 프론트엔드 성능 최적화 가이드
- 자바스크립트 딥다이브
- DOM
- mixin pattern
- const
- 프로그래머스
- peerdependencies
- Today
- Total
Dev Blog
1-1. IM Prep - modern JavaScript 본문
- 화살표 함수
- this 키워드
- call, apply 메소드
- bind 메소드
화살표 함수
1. 함수 표현식을 축약할 수 있다.
1) function 제거하고 인수 다음에 => 추가
2) return 제거(본문에 return만 있는경우) or {} + return 조합
2. call, apply, bind 사용불가
var adder = {
base : 1,
addThruApply : function(a) {
var f = v => v + this.base;
var b = {
base : 100
};
return f.apply(b, [a]);
},
addThruCall: function(a) {
var f = v => v + this.base;
var c = {
base : 100
};
return f.call(c, a);
}
};
adder.addThruApply(1); // 2
adder.addThruCall(1); // 2
3. 바인딩 되지 않는 this
function Person() {
// Person() 생성자는 `this`를 자신의 인스턴스로 정의.
this.age = 0;
setInterval(function growUp() {
// 비엄격 모드에서, growUp() 함수는 `this`를
// 전역 객체로 정의하고, 이는 Person() 생성자에
// 정의된 `this`와 다름.
this.age++;
}, 1000);
}
var p = new Person();
위 함수에서 this는 전역 객체로 정의되기 때문에, this.age 는 0부터 시작하지 않습니다.
따라서 아래와 같이 비전역 변수에 this를 할당하여 해결할 수 있습니다.
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
// 콜백은 `that` 변수를 참조하고 이것은 값이 기대한 객체이다.
that.age++;
}, 1000);
}
이와 달리 화살표 함수는 자신의 this가 없습니다. 대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용됩니다. 즉, 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 끝내게 됩니다.
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this|는 Person 객체를 참조
}, 1000);
}
var p = new Person();
의도된대로 setInterval 내의 this는 p 를 가리키기 때문에 this.age 는 0부터 순차적으로 증가합니다.
this키워드
this는 함수 실행시 호출(invocation) 방법에 의해 결정되는 특별한 객체
패턴 | 바인딩되는 객체 | 설명 |
Method 호출; obj.foo() | 부모 객체 (실행 시점에 온점 왼쪽에 있는 객체) | 하나의 객체에 값과 연관된 메소드를 묶어서 사용할 때 주로 사용함 |
new 키워드를 이용 생성자 호출; new foo() | 새롭게 생성된 인스턴스 객체 | 객체 지향 프로그래밍에서 주로 사용함 |
.call 또는 .apply 호출; foo.call() foo.apply() |
첫번째 인자로 전달된 객체 | this 값을 특정할 때 사용하며, 특히 apply의 경우 배열의 엘리먼트를 풀어서 인자로 넘기고자 할 때 유용함 |
Global; console.log(this) | window (strict mode에서는 undefined) | module.exports(전역에서 this 참조) |
Function; 호출 foo() | window (strict mode에서는 undefined) | global |
- 브라우저 환경에서 this는 기본적으로 window 객체
- node.js 환경에서 this는 기본적으로 module.exports 객체
- node.js 환경에서는 global이라는 객체가 존재
Method 호출
: 객체의 속성 값으로 담긴 함수
화살표 함수로 작성된 메소드 호출시 this = module.exports
메소드 선언시 화살표 함수 사용X or 화살표 함수 사용시 this 사용X
생성자 호출
: 객체를 new 키워드를 이용해 만듦.
객체 = 인스턴트. 인스턴트.메소드() 형태의 호출.
new가 안 붙은 경우, this는 전역 객체를 가리킨다.
함수에도 메소드가 있다 => call(), apply(), bind()
call 메소드
.call 호출은 명시적으로 this를 지정할 때 사용. 첫번째 인자가 항상 this.
foo.call(context). context를 this로 지정하고, foo() 함수를 실행.
call의 두번째 인자 이후로는 파라미터로 전달됨.
function printProfile(name, age, ...args) {
return `${this.type} ${name} 나이:${age}${args.length === 0 ? "" : " " + this.feature + ":" + args.join(",")}`;
}
const artist = { type: "아티스트", feature: "노래" };
printProfile.call(artist, "BTS", 7, "ON", "Dynamite")
//아티스트 BTS 나이:7 노래:ON,Dynamite
apply 메소드
.apply 호출은 명시적으로 this를 지정할 때 사용. 첫번째 인자가 항상 this.
apply의 두번째 인자는 배열.
function printProfile(name, age, ...args) {
return `${this.type} ${name} 나이:${age}${args.length === 0 ? "" : " " + this.feature + ":" + args.join(",")}`;
}
const artist = { type: "아티스트", feature: "노래" };
printProfile.apply(artist, ["BTS", 7, "ON", "Dynamite"])
//아티스트 BTS 나이:7 노래:ON,Dynamite
prototype 기능 빌려쓰기
const array1 = ["code", "states"];
const array2 = ["immersive", "course"];
const arrayNumbers = [5, 10, 4, 9];
Array.prototype.concat.call(array1, array2, arrayNumbers)
//["code","states","immersive","course", 5, 10, 4 ,9]
Array.prototype.concat.apply(array1, [array2])
//["code","states","immersive","course"]
유사 배열 다루기 가능
const nodeList = {
length: 3,
0: "div#target",
1: "li",
2: "span#new"
};
Array.prototype.slice.apply(nodeList, [0, 1]) // ["div#target"]
Array.prototype.map.call(nodeList, node => node.split("#")[0]) //["div","li","span"]
일반 배열 예시
bind 메소드
bind는 함수를 실행하지 않고, this 컨텍스트를 담은 함수를 리턴.
bind의 인자 순서는 call과 동일.
CASE1
: 각 버튼을 클릭했을때 클릭된 버튼의 이름이 출력되게 하려면?
Solution1
user를 this로 바인딩 시키는 방법
solution2
this를 사용하지 않고, 인자를 전달하는 방법
solution3
bind를 사용하지 않고 인자를 전달하는 방법
CASE2: setTimeOut
setTimeout은 시간 지연을 일으킨 후 callback 함수를 비동기적으로 실행시키는 함수입니다.
이 함수는 명시적으로 항상 window 객체를 this 바인딩하는 특징이 있습니다.
따라서, 아래와 같이 Error가 발생한다.
solution1
bind를 사용하여 해결하는 방법
solution2
익명함수를 사용하여 this를 새 변수에 담아 전달하는 방법(권장x)
solution3
화살표함수를 사용하여 해결하는 방법.
현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 끝내게 됩니다.
'BootCamp_Codestates > IM Tech Blog' 카테고리의 다른 글
3-1. Inheritance Patterns - Subclassing, Prototype Chain (0) | 2020.12.09 |
---|---|
3. Inheritance Patterns - Object Oriented Programming (0) | 2020.12.09 |
2-1. Data Structure - Linked-list, HashTable (0) | 2020.12.03 |
2. Data Structure - Stack, Queue (1) | 2020.12.03 |
1. IM Prep - Git workflow (0) | 2020.12.03 |