이 특정 행동을 이해하기 위해 깊이 파고 들었고 좋은 설명을 찾은 것 같습니다.
별칭을 사용할 수없는 이유를 알아보기 전에 document.getElementById
JavaScript 함수 / 객체의 작동 방식을 설명하려고합니다.
JavaScript 함수를 호출 할 때마다 JavaScript 인터프리터는 범위를 결정하고이를 함수에 전달합니다.
다음 기능을 고려하십시오.
function sum(a, b)
{
return a + b;
}
sum(10, 20);
이 함수는 Window 범위에서 선언되며이를 호출 this
하면 sum 함수 내부의 값이 전역 Window
개체가됩니다.
'sum'함수의 경우 'this'가 사용하지 않기 때문에 값이 무엇인지는 중요하지 않습니다.
다음 기능을 고려하십시오.
function Person(birthDate)
{
this.birthDate = birthDate;
this.getAge = function() { return new Date().getFullYear() - this.birthDate.getFullYear(); };
}
var dave = new Person(new Date(1909, 1, 1));
dave.getAge();
당신이 dave.getAge 함수를 호출 할 때, 자바 스크립트 인터프리터는 당신이에 getAge 함수를 호출하는 것을보고 dave
는 설정 때문에, 객체 this
로 dave
하고, 호출 getAge
기능. getAge()
올바르게 반환 100
됩니다.
JavaScript에서 apply
메서드를 사용하여 범위를 지정할 수 있음을 알 수 있습니다 . 시도해 봅시다.
var dave = new Person(new Date(1909, 1, 1));
var bob = new Person(new Date(1809, 1, 1));
dave.getAge.apply(bob);
위 줄에서 JavaScript가 범위를 결정하도록하는 대신 수동으로 범위를 bob
객체 로 전달 합니다. getAge
이제 개체 에 대해 200
'생각'했음에도 불구하고 반환됩니다 .getAge
dave
위의 모든 것의 요점은 무엇입니까? 함수는 JavaScript 객체에 '느슨하게'연결됩니다. 예를 들어 할 수 있습니다.
var dave = new Person(new Date(1909, 1, 1));
var bob = new Person(new Date(1809, 1, 1));
bob.getAge = function() { return -1; };
bob.getAge();
dave.getAge();
다음 단계로 넘어 갑시다.
var dave = new Person(new Date(1909, 1, 1));
var ageMethod = dave.getAge;
dave.getAge();
ageMethod();
ageMethod
실행하면 오류가 발생합니다! 어떻게 된 거예요?
주의 깊게 내 위의 포인트를 읽는다면, 당신은주의 할 dave.getAge
메소드가 호출되었습니다 dave
로 this
자바 스크립트의 '범위'판별 할 수 없습니다 반면 개체를 ageMethod
실행합니다. 그래서 글로벌 '창'을 'this'로 전달했습니다. 이제 속성 window
이 없으므로 실행이 실패합니다.birthDate
ageMethod
이 문제를 해결하는 방법? 단순한,
ageMethod.apply(dave);
위의 모든 내용이 이해가 되었습니까? 그렇다면 별칭을 사용할 수없는 이유를 설명 할 수 있습니다 document.getElementById
.
var $ = document.getElementById;
$('someElement');
$
로 호출 window
로 this
하고있는 경우 getElementById
구현이 기대 this
될 document
, 그것은 실패합니다.
다시이 문제를 해결하려면 다음을 수행 할 수 있습니다.
$.apply(document, ['someElement']);
그렇다면 Internet Explorer에서 작동하는 이유는 무엇입니까?
getElementById
IE 의 내부 구현을 모르지만 jQuery 소스 ( inArray
메서드 구현) 의 주석은 IE에서 window == document
. 이 경우 앨리어싱 document.getElementById
은 IE에서 작동합니다.
이것을 더 설명하기 위해 나는 정교한 예를 만들었습니다. Person
아래 기능을 살펴보십시오 .
function Person(birthDate)
{
var self = this;
this.birthDate = birthDate;
this.getAge = function()
{
if(this.constructor == Person)
return new Date().getFullYear() - this.birthDate.getFullYear();
else
return -1;
};
this.getAgeSmarter = function()
{
return self.getAge();
};
this.getAgeSmartest = function()
{
var scope = this.constructor == Person ? this : self;
return scope.getAge();
};
}
Person
위 의 기능에 대해 다양한 getAge
메서드가 작동 하는 방식은 다음과 같습니다.
Person
함수를 사용하여 두 개의 객체를 만들어 보겠습니다 .
var yogi = new Person(new Date(1909, 1,1));
var anotherYogi = new Person(new Date(1809, 1, 1));
console.log(yogi.getAge());
곧바로 getAge 메소드는 yogi
객체를로 가져오고 this
출력 100
합니다.
var ageAlias = yogi.getAge;
console.log(ageAlias());
자바 스크립트 인터프리터는 window
객체를로 설정 this
하고 getAge
메서드는 -1
.
console.log(ageAlias.apply(yogi));
올바른 범위를 설정하면 ageAlias
방법 을 사용할 수 있습니다 .
console.log(ageAlias.apply(anotherYogi));
다른 사람 개체를 전달해도 나이를 올바르게 계산합니다.
var ageSmarterAlias = yogi.getAgeSmarter;
console.log(ageSmarterAlias());
이 ageSmarter
함수는 원래 this
객체를 캡처 하므로 이제 올바른 범위를 제공하는 것에 대해 걱정할 필요가 없습니다.
console.log(ageSmarterAlias.apply(anotherYogi));
문제 ageSmarter
는 범위를 다른 개체로 설정할 수 없다는 것입니다.
var ageSmartestAlias = yogi.getAgeSmartest;
console.log(ageSmartestAlias());
console.log(ageSmartestAlias.apply(document));
ageSmartest
유효 범위가 공급되면 함수는 원래의 범위를 이용할 것이다.
console.log(ageSmartestAlias.apply(anotherYogi));
여전히 다른 Person
개체를 에 전달할 수 있습니다 getAgeSmartest
. :)