함수 호출
함수는 단지 일종의 객체입니다.
모든 Function 객체에는 호출 된 Function 객체 를 실행하는 호출 및 적용 메소드가 있습니다.
이 메소드에 대한 첫 번째 인수 this는 함수를 실행하는 동안 키워드 가 참조 할 오브젝트를 지정합니다. null또는 undefined오브젝트 인 경우 전역 오브젝트 window가에 사용됩니다 this.
따라서 함수를 호출하면 ...
whereAmI = "window";
function foo()
{
return "this is " + this.whereAmI + " with " + arguments.length + " + arguments";
}
... 괄호 - foo()- 동등 foo.call(undefined)또는 foo.apply(undefined)인 효과적으로 동일 foo.call(window)하거나 foo.apply(window).
>>> foo()
"this is window with 0 arguments"
>>> foo.call()
"this is window with 0 arguments"
추가 인수 call는 함수 호출에 인수로 전달되는 반면 단일 추가 인수 apply는 함수 호출에 대한 인수를 Array와 같은 객체로 지정할 수 있습니다.
따라서, foo(1, 2, 3)동등 foo.call(null, 1, 2, 3)하거나 foo.apply(null, [1, 2, 3]).
>>> foo(1, 2, 3)
"this is window with 3 arguments"
>>> foo.apply(null, [1, 2, 3])
"this is window with 3 arguments"
함수가 객체의 속성 인 경우 ...
var obj =
{
whereAmI: "obj",
foo: foo
};
... 목적에 따라 기능에 대한 참조에 액세스 괄호로 호출 - obj.foo()- 동등 foo.call(obj)하거나 foo.apply(obj).
그러나 객체의 속성으로 유지되는 함수는 해당 객체에 "바인드"되지 않습니다. obj위 의 정의에서 볼 수 있듯이 함수는 객체 유형일 뿐이므로 참조 할 수 있습니다 (따라서 함수 호출에 대한 참조로 전달되거나 함수 호출에서 참조로 반환 될 수 있음). 함수에 대한 참조가 전달 될 때, 그것이 전달에 대한 추가 정보 에서 입니다 그것으로 수행되고, 다음과 같은 변화가 없습니다 이유 :
>>> baz = obj.foo;
>>> baz();
"this is window with 0 arguments"
함수 참조 baz에 대한 호출은 호출에 대한 컨텍스트를 제공하지 않으므로 효과적으로와 동일 baz.call(undefined)하므로 this참조 window합니다. 우리가 원하는 경우 baz가에 속한다는 것을 알고 obj, 우리가 어떻게 든 그 정보를 제공 할 필요가 baz있다라고를 위치로 첫 번째 인수 call또는 apply폐쇄가 활동하기 시작합니다.
스코프 체인
function bind(func, context)
{
return function()
{
func.apply(context, arguments);
};
}
함수가 실행되면 새 범위가 만들어지고 모든 범위에 대한 참조가 있습니다. 위의 예제에서 익명 함수를 만들면 해당 함수가 만들어진 범위 (의 범위)에 대한 참조가 bind있습니다. 이것을 "클로저"라고합니다.
[global scope (window)] - whereAmI, foo, obj, baz
|
[bind scope] - func, context
|
[anonymous scope]
변수에 액세스하려고 할 때이 "범위 체인"은 주어진 이름을 가진 변수를 찾기 위해 안내됩니다. 현재 범위에 변수가 포함되어 있지 않으면 체인의 다음 범위를 확인합니다. 글로벌 범위. 익명 함수가 반환되고 bind실행이 완료 되면 익명 함수는 여전히 bind범위에 대한 참조를 가지 므로 bind범위가 "이탈"되지 않습니다.
위의 모든 사항을 감안할 때 이제 다음 예제에서 범위가 작동하는 방식과 특정 값으로 "사전 바인딩 된"함수를 전달하는 기술이 작동이라고하는 이유를 이해할 수 this있습니다.
>>> baz = bind(obj.foo, obj);
>>> baz(1, 2);
"this is obj with 2 arguments"
var signup = { onLoadHandler:function(){ console.log(this); return Type.createDelegate(this,this._onLoad); }, _onLoad: function (s, a) { console.log("this",this); }};