arguments.callee.caller
JavaScript 에서 속성이 더 이상 사용되지 않는 이유는 무엇 입니까?
JavaScript에서 추가 된 후 더 이상 사용되지 않지만 ECMAScript에서는 완전히 생략되었습니다. 일부 브라우저 (Mozilla, IE)는 항상 해당 브라우저를 지원했으며 지원을 제거 할 계획이 없습니다. 다른 사람들 (Safari, Opera)은 이에 대한 지원을 채택했지만 이전 브라우저에서의 지원은 신뢰할 수 없습니다.
이 귀중한 기능을 림보에 넣을만한 충분한 이유가 있습니까?
(또는 대안으로, 호출 기능을 처리하는 더 좋은 방법이 있습니까?)
답변
JavaScript의 초기 버전에서는 명명 된 함수 표현식이 허용되지 않았기 때문에 재귀 함수 표현식을 작성할 수 없었습니다.
// This snippet will work:
function factorial(n) {
return (!(n>1))? 1 : factorial(n-1)*n;
}
[1,2,3,4,5].map(factorial);
// But this snippet will not:
[1,2,3,4,5].map(function(n) {
return (!(n>1))? 1 : /* what goes here? */ (n-1)*n;
});
이 문제를 해결하기 위해 arguments.callee
추가되었습니다.
[1,2,3,4,5].map(function(n) {
return (!(n>1))? 1 : arguments.callee(n-1)*n;
});
그러나 이것은 실제로 다른 해결책, 수신자 및 발신자 문제와 관련하여 일반적인 경우에는 인라인 및 꼬리 재귀를 불가능하게하므로 실제로는 나쁜 해결책이었습니다 (추적 등을 통해 특정 경우에 달성 할 수는 있지만 최상의 코드조차도 가능합니다) 그렇지 않으면 필요하지 않은 점검으로 인해 최적이 아님). 다른 주요 문제는 재귀 호출이 다른 this
값 을 얻는다는 것 입니다. 예를 들면 다음과 같습니다.
var global = this;
var sillyFunction = function (recursed) {
if (!recursed)
return arguments.callee(true);
if (this !== global)
alert("This is: " + this);
else
alert("This is the global");
}
sillyFunction();
어쨌든 EcmaScript 3는 다음과 같은 명명 된 함수 표현식을 허용하여 이러한 문제를 해결했습니다.
[1,2,3,4,5].map(function factorial(n) {
return (!(n>1))? 1 : factorial(n-1)*n;
});
이것은 많은 이점이 있습니다 :
-
함수는 코드 내부에서 다른 것과 같이 호출 할 수 있습니다.
-
네임 스페이스를 오염시키지 않습니다.
-
값은
this
변경되지 않습니다. -
성능이 뛰어납니다 ( arguments 객체에 액세스하는 것이 비쌉니다).
으악,
그 질문은 다른 모든 것에 더해 arguments.callee.caller
또는 더 구체적 이라는 것을 깨달았습니다 Function.caller
.
어느 시점에서나 스택에서 함수의 가장 깊은 호출자를 찾을 수 있으며 위에서 언급했듯이 호출 스택을 보는 데는 하나의 주요 효과가 있습니다.
예 : 함수 f
가 알 수없는 함수를 호출하지 않을 것이라고 보장 할 수 없으면 인라인 할 수 없습니다 f
. 기본적으로 그것은 사소하게 불쾌했을 수있는 모든 호출 사이트에 많은 수의 경비원이 축적됨을 의미합니다.
function f(a, b, c, d, e) { return a ? b * c : d * e; }
js 인터프리터가 제공된 모든 인수가 호출 시점의 숫자임을 보장 할 수 없으면 인라인 코드 앞에 모든 인수에 대한 검사를 삽입하거나 함수를 인라인 할 수 없습니다.
이제이 특별한 경우에, 스마트 통역사는보다 최적의 수표를 재 배열하고 사용할 수없는 값을 검사하지 않을 수 있어야합니다. 그러나 많은 경우에 그것은 가능하지 않으므로 인라인하는 것이 불가능합니다.
답변
arguments.callee.caller
있다 없다 가의 메이크업을 사용하지 불구하고 사용되지 않는 속성을. ( 현재 기능에 대한 참조를 제공합니다)Function.caller
arguments.callee
Function.caller
ECMA3에 따르면 비표준이지만 현재 모든 주요 브라우저에서 구현 됩니다.arguments.caller
은 더 이상 사용되지 않으며 일부 현재 주요 브라우저 (예 : Firefox 3)에서는 구현되지 않습니다.Function.caller
따라서 상황이 이상적이지는 않지만 모든 주요 브라우저에서 Javascript로 호출 함수에 액세스하려는 경우 이름 지정된 함수 참조에서 직접 액세스하거나 특성을 통해 익명 함수 내에서 특성을 사용할 수 있습니다.Function.caller
arguments.callee
답변
arguments.callee보다 명명 된 함수 를 사용하는 것이 좋습니다 .
function foo () {
... foo() ...
}
~보다 낫다
function () {
... arguments.callee() ...
}
명명 된 함수는 호출자 속성을 통해 호출자에게 액세스 할 수 있습니다.
function foo () {
alert(foo.caller);
}
어느 것보다 낫다
function foo () {
alert(arguments.callee.caller);
}
더 이상 사용되지 않는 것은 현재 ECMAScript 설계 원칙 때문 입니다.
답변
확장명입니다. “this”의 값은 재귀 중에 변경됩니다. 다음 (수정 된) 예에서 factorial은 {foo : true} 객체를 가져옵니다.
[1,2,3,4,5].map(function factorial(n) {
console.log(this);
return (!(n>1))? 1 : factorial(n-1)*n;
}, {foo:true} );
처음 호출 된 계승은 객체를 가져 오지만 재귀 호출에는 해당되지 않습니다.