2013-11-27 1 views
1

내가 실험하고이 매우 간단한 프레임 워크를 가지고 (내가 깊이에 더 많은 자바 스크립트의 함수 프로토 타입을 배울 수 있도록합니다.)왜 bind() 또는 apply()가 여기서 작동하지 않지만 call()은 작동합니까?

(function(){ 
var app = { 
    ui: { 
     app: document.querySelector('.app'), 
     settings: document.querySelector('.settings'), 
    }, 
    actions: 'click settings openSidebar' 
    , 
    functions: { 
     openSidebar: function(e){ 
      console.log(this); // <- expected value of this is 'app.ui' 
     } 
    }, 
    run: function(){ 
     var a1 = this.actions.split("\n"); 
     var a2 = this.actions.split(" "); 

     var self = this; 
     this.ui[a2[1]].addEventListener(a2[0], function(e){ 
      app.functions.openSidebar.call(self.ui,e); 
     }); 
    } 
}; 
app.run(); 
})(); 

이 잘 작동합니다. 콘솔의 출력은 다음과 같습니다 그러나

Object {ui: Object, actions: "click settings openSidebar", functions: Object, run: function} 

, 나는 이런 식으로 작업을 수행하려고하면

var self = this; 
this.ui[a2[1]].addEventListener(a2[0], function(e){ 
    app.functions.openSidebar(e); 
}.bind(this)); 

openSidebar()에서 this의 문맥 openSidebar (일명 바인드 효과가 없습니다)입니다. 콘솔 출력 : 그러나

Object {openSidebar: function} 

, 내가 지금처럼 apply 기능을 사용하려고하면

app.functions.openSidebar.apply(self.ui,e); 

그것은 인수 (e)이되지 않는다는 점을 제외 (openSidebar에서 thisapp.ui입니다) 잘 작동 통과 되니, e == undefined.

여기 간다 :

1. 왜 첫 번째 예에서 일을 (전혀)에 결합하지 않는 이유는 무엇입니까?

2. 적용이 인수를 사용하지 않고 작동하는 이유는 무엇입니까 (e (이벤트))?

그리고 추가 브라우니 포인트

은 :

3. 왜 통화 작업이 예상 않는?

답변

1

왜 첫 번째 예에서 일을 (전혀)에 결합하지 않는 이유는 무엇입니까?

"작동"하면 예상대로 작동하지 않습니다.

귀하의 안쪽 기능 this은 실제로 bind에 의해 설정된 값입니다. 그러나 객체의 속성이기도 한 함수 (functions.openSidebar)를 호출하면 해당 호출에 대해 this이 함수 내부의 해당 객체 (예 : this === functions)에 자동으로 바인딩됩니다. 상위 컨텍스트의 this 값은 결코 호출 체인에서 "상속"되지 않습니다.

왜 인수를 전달하지 않고 적용이 적용됩니까? (e (이벤트))?

apply 배열로 처리하여 자신의 두 번째 인수 e에서 통화의 인수를 가져 오는 때문입니다. 즉, 먼저 length 속성을 확인합니다. 이벤트 객체에 length이 없으므로 applyundefined 값을 가져오고 빈 배열을 전달한 것처럼 효과적으로 작동합니다. annotated ES5 reference for the details을 참조하십시오.

전화가 예상대로 작동하는 이유는 무엇입니까?

이것은 이상한 질문입니다. 이 아닌 이유는일까요? 당신은 그것을 사용하는 것과 똑같이 사용하고 있습니다.

+0

자세한 답변을 해주셔서 대단히 감사합니다. 존. 그것은 많은 도움이됩니다. 그리고 나는 동의해야한다. 질문 3은 회상에서 이상한 질문이었다 :-) – subZero

1
  1. 당신은이 작업을 수행해야합니다 :

    this.ui[a2[1]].addEventListener(a2[0], app.functions.openSidebar.bind(this));

당신이 아니에요 때문에 바인딩은 당신이 통과 어떤의 수동 설정 문맥 당신에게 새로운 기능을 반환합니다. 올바른 함수에 bind를 사용하면 호출 된 함수의 왼쪽에 app.functions으로 함수를 호출합니다.이 함수는 호출 된 함수 안에 this으로 알려집니다.

  1. 적용은 ... 배열, 이름없는 매개 변수로 인수를

  2. 나는이 작품을 호출하는 방법을 할 수있는 것은 세 번째를 설명 할 수 없다!

+0

감사합니다. 요점은 작업 코드 예제에서도 마찬가지입니다. 감사합니다. – subZero

관련 문제