화살표 기능 은 기능 을 단순화 scope하고 this키워드를 더 단순하게 하여 키워드를 해결 하기 위해 작성되었습니다 . =>화살표처럼 보이는 구문을 사용합니다 .
참고 : 기존 기능을 대체하지 않습니다. 모든 함수 구문을 화살표 함수로 바꾸면 모든 경우에 작동하지 않습니다.
기존 ES5 구문을 살펴 보도록하겠습니다. this키워드가 객체의 메서드 (객체에 속한 함수) 안에 있다면 무엇을 의미합니까?
var Actor = {
name: 'RajiniKanth',
getName: function() {
console.log(this.name);
}
};
Actor.getName();
위의 스 니펫은를 참조 object하고 이름을 인쇄합니다 "RajiniKanth". 아래의 스 니펫을 살펴보고 이것이 무엇을 지적하는지 봅시다.
var Actor = {
name: 'RajiniKanth',
movies: ['Kabali', 'Sivaji', 'Baba'],
showMovies: function() {
this.movies.forEach(function(movie) {
alert(this.name + " has acted in " + movie);
});
}
};
Actor.showMovies();
this키워드가 내부 에 있다면 method’s function어떨까요?
여기서 이것은 타락한 window object것으로 inner function간주됩니다 scope. 때문에 this, 항상 함수의 소유자를 참조하는 것이이 경우에,에 -이 범위를 벗어나 지금부터 - 윈도우 / 전역 객체.
object의 메소드 안에있을 경우 — function소유자가 객체입니다. 따라서 this 키워드는 객체에 바인딩됩니다. 그러나 독립형 또는 다른 방법 내에서 함수 내부에있는 경우 항상 window/global오브젝트를 참조 합니다.
var fn = function(){
alert(this);
}
fn(); // [object Window]
우리 ES5스스로이 문제를 해결할 수있는 방법이 있습니다. ES6 화살표 기능으로 들어가기 전에 그 문제를 해결하는 방법을 살펴 보겠습니다.
일반적으로 메서드의 내부 함수 외부에서 변수를 만듭니다. 이제이 ‘forEach’메소드 this는 object’s속성 및 해당 값에 액세스 할 수 있습니다.
var Actor = {
name: 'RajiniKanth',
movies: ['Kabali', 'Sivaji', 'Baba'],
showMovies: function() {
var _this = this;
this.movies.forEach(function(movie) {
alert(_this.name + " has acted in " + movie);
});
}
};
Actor.showMovies();
를 사용 하여 메소드를 나타내는 키워드 bind를에 첨부 this합니다 method’s inner function.
var Actor = {
name: 'RajiniKanth',
movies: ['Kabali', 'Sivaji', 'Baba'],
showMovies: function() {
this.movies.forEach(function(movie) {
alert(this.name + " has acted in " + movie);
}.bind(this));
}
};
Actor.showMovies();
이제 ES6화살표 기능 lexical scoping을 사용하여 더 간단한 방법으로 문제를 처리 할 수 있습니다 .
var Actor = {
name: 'RajiniKanth',
movies: ['Kabali', 'Sivaji', 'Baba'],
showMovies: function() {
this.movies.forEach((movie) => {
alert(this.name + " has acted in " + movie);
});
}
};
Actor.showMovies();
Arrow functionsbind이것에 대한 것을 제외하고는 함수 문과 비슷합니다 parent scope. 경우] arrow function is in top scope, this인수를 참조한다 window/global scope일반 함수 안에 화살표 기능이 외부 함수와 같은 인수는이있는 반면,.
with arrow함수 this는 scope생성시 둘러싸기에 바인딩되어 있으며 변경할 수 없습니다. 새로운 연산자 인 bind, call 및 apply는 이에 영향을 미치지 않습니다.
var asyncFunction = (param, callback) => {
window.setTimeout(() => {
callback(param);
}, 1);
};
// With a traditional function if we don't control
// the context then can we lose control of `this`.
var o = {
doSomething: function () {
// Here we pass `o` into the async function,
// expecting it back as `param`
asyncFunction(o, function (param) {
// We made a mistake of thinking `this` is
// the instance of `o`.
console.log('param === this?', param === this);
});
}
};
o.doSomething(); // param === this? false
위의 예에서 우리는 이것에 대한 통제력을 잃었습니다. 변수 참조를 this사용하거나를 사용 하여 위 예제를 해결할 수 있습니다 bind. ES6으로, 그것은 관리에 용이하게 this결합 그것으로 lexical scoping.
var asyncFunction = (param, callback) => {
window.setTimeout(() => {
callback(param);
}, 1);
};
var o = {
doSomething: function () {
// Here we pass `o` into the async function,
// expecting it back as `param`.
//
// Because this arrow function is created within
// the scope of `doSomething` it is bound to this
// lexical scope.
asyncFunction(o, (param) => {
console.log('param === this?', param === this);
});
}
};
o.doSomething(); // param === this? true
화살표 기능을 사용하지 않을 때
객체 리터럴 내부.
var Actor = {
name: 'RajiniKanth',
movies: ['Kabali', 'Sivaji', 'Baba'],
getName: () => {
alert(this.name);
}
};
Actor.getName();
Actor.getName화살표 함수로 정의되지만 때문에 호출에 경고가 미정 this.name인 undefined문맥에 남아 window.
화살표 함수는 컨텍스트를 어휘 적으로 window object... 즉 외부 범위 와 바인딩하기 때문에 발생합니다 . 실행 this.name은 window.name정의되지 않은와 같습니다.
객체 프로토 타입
에 메소드를 정의 할 때도 동일한 규칙이 적용됩니다 prototype object. sayCatName 메소드를 정의하기 위해 화살표 함수를 사용하는 대신 올바르지 않은 결과가 발생합니다 context window.
function Actor(name) {
this.name = name;
}
Actor.prototype.getName = () => {
console.log(this === window); // => true
return this.name;
};
var act = new Actor('RajiniKanth');
act.getName(); // => undefined
생성자 호출
this구성 호출에서 새로 작성된 오브젝트입니다. 새 Fn ()을 실행할 때의 컨텍스트 constructor Fn는 새 객체 this instanceof Fn === true입니다.
this 엔 클로징 컨텍스트, 즉 새로 작성된 오브젝트에 지정되지 않는 외부 범위에서 설정됩니다.
var Message = (text) => {
this.text = text;
};
// Throws "TypeError: Message is not a constructor"
var helloMessage = new Message('Hello World!');
동적 컨텍스트가있는 콜백
Arrow 함수 context는 선언시 정적으로 바인딩하며 동적으로 만들 수 없습니다. DOM 요소에 이벤트 리스너를 연결하는 것은 클라이언트 측 프로그래밍에서 일반적인 작업입니다. 이벤트는이를 대상 요소로하여 핸들러 기능을 트리거합니다.
var button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log(this === window); // => true
this.innerHTML = 'Clicked button';
});
this전역 컨텍스트에 정의 된 화살표 함수의 창입니다. click 이벤트가 발생하면 브라우저는 버튼 컨텍스트로 핸들러 함수를 호출하려고 시도하지만 화살표 함수는 사전 정의 된 컨텍스트를 변경하지 않습니다. this.innerHTML에 해당 window.innerHTML하고 아무 의미가 없습니다.
대상 요소에 따라이를 변경할 수있는 함수 표현식을 적용해야합니다.
var button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log(this === button); // => true
this.innerHTML = 'Clicked button';
});
사용자가 버튼을 클릭하면 핸들러 기능에서 버튼이됩니다. 따라서 this.innerHTML = 'Clicked button'클릭 한 상태를 반영하도록 단추 텍스트를 올바르게 수정합니다.
참조 :
https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/
Fixed this bound to scope at initialisation은 한계로 생각 하십니까?