programing

arguments.callee.caller 속성이 JavaScript에서 폐지된 이유는 무엇입니까?

bestcode 2022. 11. 17. 21:13
반응형

arguments.callee.caller 속성이 JavaScript에서 폐지된 이유는 무엇입니까?

왜?arguments.callee.callerJavaScript에서 더 이상 사용되지 않는 속성?

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, 또는 보다 구체적으로는.

언제든지 스택 상의 함수 중 가장 깊은 곳에 있는 발신자를 찾을 수 있습니다.앞서 설명한 바와 같이 콜스택을 조사하는 것은 하나의 큰 효과를 가져옵니다.따라서 많은 최적화가 불가능하거나 훨씬 더 어려워집니다.

예를 들어, 어떤 기능이f알 수 없는 함수를 호출하지 않기 때문에 인라인화할 수 없습니다.f기본적으로는 신뢰할 수 없는 콜사이트에 다수의 경비원이 축적되어 있는 것을 의미합니다.

 function f(a, b, c, d, e) { return a ? b * c : d * e; }

js 인터프리터는 제공된 인수가 모두 콜이 발신된 시점에서 수치임을 보증할 수 없는 경우 인라인 코드 앞에 모든 인수에 대한 체크를 삽입해야 합니다.그렇지 않으면 함수를 인라인화할 수 없습니다.

이 경우 스마트 인터프리터는 체크를 보다 최적화하도록 재배치할 수 있어야 하며 사용되지 않는 값은 체크하지 않아야 합니다.그러나 대부분의 경우 이는 불가능하기 때문에 인라인화가 불가능합니다.

arguments.callee.caller는 사용되지 않지만 속성을 사용합니다.(arguments.callee현재 기능에 대한 참조만 제공합니다.)

  • Function.callerECMA3에 따르면 비표준이지만 현재 모든 주요 브라우저에 구현되어 있습니다.
  • arguments.caller 위해 추천되지 않는다.Function.caller파이어폭스 3)를 사용합니다.

이상적인에 액세스하려면 할 수 .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" 값은 재귀 중에 변경됩니다.다음(수정된) 예제에서는 factor가 {foo:true} 개체를 가져옵니다.

[1,2,3,4,5].map(function factorial(n) {
  console.log(this);
  return (!(n>1))? 1 : factorial(n-1)*n;
},     {foo:true}     );

처음 호출된 요인에서 개체를 가져오지만 재귀 호출의 경우 그렇지 않습니다.

언급URL : https://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in-javascript

반응형