화살표 함수에서 'this'를 바인딩 할 수 있습니까?


133

나는 잠시 동안 ES6을 실험 해 왔으며 약간의 문제가 생겼습니다.

나는 화살표 기능을 사용하는 것을 정말로 좋아하며 가능할 때마다 사용합니다.

그러나 바인딩 할 수없는 것처럼 보입니다!

기능은 다음과 같습니다.

var f = () => console.log(this);

다음은 함수를 바인딩하려는 객체입니다.

var o = {'a': 42};

그리고 여기에 바인딩하는 방법 f이 있습니다 o.

var fBound = f.bind(o);

그런 다음 전화 할 수 있습니다 fBound.

fBound();

이것 ( o객체) 이 출력됩니다 :

{'a': 42}

멋있는! 아름다운! 작동하지 않는 것을 제외하고. o객체 를 출력하는 대신 객체를 출력 window합니다.

그래서 알고 싶습니다 : 화살표 기능을 바인딩 할 수 있습니까? (그렇다면 어떻게?)


Chrome 48 및 Firefox 43에서 위의 코드를 테스트했으며 결과는 동일합니다.


29
화살표 기능의 핵심은 this부모 범위를 사용한다는 것 입니다.
loganfsmyth

답변:


158

화살표 기능 에는 리 바인드 할 수 없습니다 this. 항상 정의 된 컨텍스트로 정의됩니다. this의미가 필요한 경우 정상적인 기능을 사용해야합니다.

로부터 ECMAScript를 2,015 사양 :

ArrowFunction 내 인수, super, this 또는 new.target에 대한 모든 참조는 어휘 환경에서 바인딩으로 해석되어야합니다. 일반적으로 이것은 즉시 둘러싸는 기능의 기능 환경입니다.


7
이 답변의 첫 문장이 잘못되었습니다. 아마도 질문이 바인딩을 혼동하기 때문일 것 this입니다. 두 사람은 관련되어 있지만 동일하지는 않습니다. this화살표 함수 내부는 항상 포함 this범위에서 '상속'합니다 . 이것이 화살표 기능의 특징입니다. 그러나 여전히 bind화살표 기능의 다른 모든 매개 변수 를 사용할 수 있습니다 . 그냥 아닙니다 this.
Stijn de Witt

54

완료하려면 다시 바인딩 기능을 화살표, 당신은 단지의 의미를 변경할 수 없습니다 this.

bind 여전히 함수 인수에 대한 가치가 있습니다.

((a, b, c) => {
  console.info(a, b, c) // 1, 2, 3
}).bind(undefined, 1, 2, 3)()

여기에서보십시오 : http://jsbin.com/motihanopi/edit?js,console


1
참조하지 않고 (화살표로 정의 된) (화살표) 함수가 바인딩 된 객체를 감지하거나 사용하는 방법이 this있습니까?
Florrie

3
문맥에 인수를 사용하십시오 : ((context) => {someOtherFunction.apply (context)}). bind (willBeIgnored, context) ()
cvazac

13

로부터 MDN :

화살표 함수 표현식은 함수 표현식에 비해 구문이 짧으며이 값을 어휘 적으로 바인딩합니다 (자체 값, 인수, super 또는 new.target을 바인딩하지 않음). 화살표 기능은 항상 익명입니다.

이는 this원하는 값을 바인딩 할 수 없음을 의미합니다 .


6

수년 동안 js 개발자는 컨텍스트 바인딩으로 어려움을 겪고 this자바 스크립트에서 변경된 이유를 물었 습니다. 컨텍스트 바인딩과 this자바 스크립트와 this다른 OOP 언어 의 의미의 차이로 인해 수년 동안 많은 혼란이있었습니다 .

이 모든 것이 내게 왜, 왜, 물어 보게한다! 왜 화살표 기능을 리 바인드하지 않을 것입니까! 이 모든 문제와 혼동을 해결하기 위해 특별히 만든 곳 bind이나 call기능의 범위를 유지 하기 위해 또는 다른 방법을 사용하지 마십시오 .

TL; DR

아니오, 화살표 기능을 리 바인드 할 수 없습니다.


7
보다 깨끗하고 빠른 구문을 제공하기 위해 먼저 화살표 기능이 작성되었습니다. 람다 미적분을 생각하십시오. 기능적인 JS 프로그래머의 삶을 괴롭히는 OO-zealots가 너무 나빠서 호출 컨텍스트를 지정할 자유를 빼앗을 기회를 얻었습니다.
Marco Faustinelli

5
사용 this이 작동하지 않습니다. 람다는이어야합니다 arguments => output. 외부 컨텍스트가 필요한 경우이를 전달하십시오. thisOO 패턴의 모든 구두를 언어에 사용하는 것이 바로 그 존재입니다 . "javascript class"라는 용어가 없으면 들어 본 적이 없을 것입니다.
erich2k8

3
화살표 기능을 리 바인드 있습니다 . 그냥 아닙니다 this.
Stijn de Witt

6

화살표 함수 내부 bind의 값을 변경하는 데 사용할 수 없습니다 this. 그러나 이전 화살표 기능과 동일한 기능을 수행하는 일반 함수를 새로 만든 다음 call또는 평소처럼 bind또는를 사용 하여 다시 바인딩 할 수 this있습니다.

우리는 사용 eval하면 보통의 함수로 전달 화살표 기능을 다시 여기에 전화를 한 후 사용하는 call다른과를 호출 this:

var obj = {value: 10};
function arrowBind(context, fn) {
  let arrowFn;
  (function() {
    arrowFn = eval(fn.toString());
    arrowFn();
  }).call(context);
}
arrowBind(obj, () => {console.log(this)});


3
화살표 함수를 다른 컨텍스트에 바인딩하는 방법에 대한이 예제를 공유해 주셔서 감사합니다! 미래 독자들이 이해하기 쉽도록 답변을 편집 하려면 코드 작동 방식 및 이유를 설명하기 위해 편집 할 수 있습니까?
Florrie

4

JavaScript에서 ES6 화살표 기능이“이것”을 실제로 해결합니까?

위의 링크는 화살표 기능 thisbind, call, apply기능에 따라 변경되지 않음을 설명합니다 .

아주 좋은 예를 들어 설명합니다.

node v4"예상 된"동작을보기 위해 이것을 실행 하십시오.

this.test = "attached to the module";
var foo = { test: "attached to an object" };
foo.method = function(name, cb){ 
    // bind the value of "this" on the method 
    // to try and force it to be what you want 
    this[name] = cb.bind(this); };
foo.method("bar", () => { console.log(this.test); });
foo.bar(); 

답변 자체에보다 관련성있는 정보를 제공하도록 요청하십시오. 샘플 코드 또는 편집 된 질문 버전 일 수 있습니다.
Jithin Scaria

// 노드 v4에서이를 실행하여 "예상 된"동작을 확인합니다. this.test = "모듈에 연결됨"; var foo = {테스트 : "객체에 연결되었습니다"}; foo.method = function (name, cb) {// 메소드에서 "this"의 값을 바인딩하여 // 원하는 값이되도록 시도합니다. [name] = cb.bind (this); }; foo.method ( "bar", () => {console.log (this.test);}); foo.bar ();
Prithvi Raj Vuppalapati

여기서 흥미로운 점은 이것을 시도한 다음 다시 시도하는 것입니다. foo.method ( 'bar', () => {console.log (this.test);}); foo.method ( 'bar', function () {console.log (this.test);}); -첫 번째 버전 로그는 "모듈에 연결됨"과 두 번째 로그는 "개체에 연결됨"-화살표 기능을 사용하여 "이것"을보다 안정적으로 처리하는 것을 선호합니다. 다른 패턴을 사용하여 다른 효과를 계속 얻을 수 있으며 결과는 더 읽기 쉽고 예측 가능한 IMO입니다.
Methodianian


2

짧은은, 당신은 수없는 바인딩 기능을 화살표 만에 읽을 수 :

이 화살표 기능이 this콘솔에 인쇄 되어 있다고 상상해보십시오 .

const myFunc = ()=> console.log(this);

따라서 빠른 수정은 정상적인 기능을 사용하므로 다음과 같이 변경하십시오.

function myFunc() {console.log(this)};

그럼 당신은 사용하는 어휘 환경에 바인딩 할 수 있습니다 bind또는 call또는 apply:

const bindedFunc = myFunc.bind(this);

의 경우에 전화하십시오 bind.

bindedFunc();

eval()그것을 사용 하는 방법도 있지만 권장하지 않습니다 .


function myFunc구속력이있는 것 외에 행동면에서 차이가있다. 더 가깝게 일치합니다 const myFunc = function() {...}. 나는 eval을 사용함으로써 당신이 의미하는 바가 궁금합니다. 왜냐하면 그것은 이전에 어떤 대답도 여기에서 공유하지 않았다고 생각하는 접근법이기 때문입니다-그것이 어떻게 수행되었는지 확인한 다음 왜 그렇게 강하게 낙담하지 않았는지를 읽는 것이 흥미로울 것입니다.
플로리

1

어쩌면이 예제가 도움이 될 것입니다.

let bob = {
   _name: "Bob",
   _friends: ["stackoverflow"],
   printFriends:(x)=> {
      x._friends.forEach((f)=> {
         console.log(x._name + " knows " + f);
      });
   }
}

bob.printFriends = (bob.printFriends).bind(null,bob);
bob.printFriends();


gøød stuff ... mildly intérésting
Aleks
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.