programing

Chrome 디버거가 닫힌 로컬 변수가 정의되지 않았다고 생각하는 이유는 무엇입니까?

starjava 2023. 8. 15. 09:41
반응형

Chrome 디버거가 닫힌 로컬 변수가 정의되지 않았다고 생각하는 이유는 무엇입니까?

다음 코드로:

function baz() {
  var x = "foo";

  function bar() {
    debugger;
  };
  bar();
}
baz();

다음과 같은 예상치 못한 결과를 얻었습니다.

enter image description here

코드를 변경하는 경우:

function baz() {
  var x = "foo";

  function bar() {
    x;
    debugger;
  };
  bar();
}

예상되는 결과를 얻었습니다.

enter image description here

또한, 다음과 같은 연락이 있을 경우eval함수 는 내 에 내가 할 수 . (eval).

한편, Firefox 개발 도구는 두 상황 모두에서 예상되는 동작을 제공합니다.

디버거가 파이어폭스보다 덜 편리하게 작동하는 크롬은 어떻게 된 겁니까?이 동작은 버전 41.0.2272.43 베타(64비트)까지 한동안 관찰되었습니다.

크롬의 자바스크립트 엔진이 할 수 있을 때 기능을 "평탄하게" 만드는 것입니까?

흥미롭게도, 내 함수에서 참조되는 두 번째 변수를 추가하면,x변수가 아직 정의되지 않았습니다.

대화형 디버거를 사용할 때 범위와 변수 정의가 있는 퀘이크가 종종 있다는 것을 이해하지만, 언어 사양에 기초하여 이러한 퀘이크에 대한 "최상의" 해결책이 있어야 한다고 생각합니다.그래서 저는 이것이 파이어폭스보다 크롬이 더 최적화했기 때문인지 매우 궁금합니다.또한 이러한 최적화를 개발 중에 쉽게 비활성화할 수 있는지 여부(개발 도구가 열려 있을 때 비활성화해야 하는지 여부)도 고려해야 합니다.

또한 중단점뿐만 아니라 이것을 재현할 수 있습니다.debugger진술.

저는 당신이 요청하는 것과 정확히 일치하는 v8 이슈 보고서를 찾았습니다.

이번 호 보고서에서 언급된 내용을 요약하자면...v8은 스택의 함수 또는 힙에 있는 "스택" 개체에 로컬인 변수를 저장할 수 있습니다.함수가 로컬 변수를 참조하는 내부 함수를 포함하지 않는 한 스택에 로컬 변수를 할당합니다.이것은 최적화입니다.내부 함수가 로컬 변수를 참조하는 경우 이 변수는 컨텍스트 개체(즉, 스택이 아닌 힙)에 배치됩니다.의 경우eval는 특별합니다. 내부 함수에 의해 호출되는 경우 모든 로컬 변수가 컨텍스트 개체에 들어갑니다.

컨텍스트 개체의 이유는 일반적으로 외부 함수에서 내부 함수를 반환하면 외부 함수가 실행되는 동안 존재했던 스택을 더 이상 사용할 수 없기 때문입니다.그래서 내부 함수가 접근하는 모든 것은 외부 함수를 살아남고 스택이 아닌 힙에서 살아야 합니다.

디버거는 스택에 있는 변수를 검사할 수 없습니다.디버깅에서 발생한 문제에 대해 한 프로젝트 구성원은 다음과 같이 말합니다.

제가 생각할 수 있는 유일한 해결책은 devtools가 켜질 때마다 모든 코드를 제거하고 강제 컨텍스트 할당으로 다시 컴파일하는 것입니다.하지만 devtools가 활성화된 상태에서는 성능이 크게 저하됩니다.

다음은 "내부 함수가 변수를 참조하는 경우 컨텍스트 개체에 배치"의 예입니다.하면 이을실면액수있다습니할것에 접속할 수 xdebugger진술을 하더라도.x는 됩니다.foo호출되지 않는 함수!

function baz() {
  var x = "x value";
  var z = "z value";

  function foo () {
    console.log(x);
  }

  function bar() {
    debugger;
  };

  bar();
}
baz();

@Louis가 말했듯이 v8 최적화로 인해 발생합니다.콜 스택을 이 변수가 표시되는 프레임으로 이동할 수 있습니다.

call1 call2

는대체로 대체합니다.debugger와 함께

eval('debugger');

eval현재 청크를 선택 취소합니다.

나는 nodjs에서도 이것을 발견했습니다.저는 (그리고 이것은 추측일 뿐이라는 것을 인정합니다) 코드가 컴파일될 때, 만약x에나 않음지나 안에 .bar말도 안 됩니다x 내가이한의 내에서 bar 더입니다; 는 비록 그것을 것입니다. 문제는 누군가가 그것이 없어도 그것을 잊어버렸거나 신경쓰지 않았다는 것입니다.xbar디버거를 실행하기로 결정할 수 있으므로 여전히 액세스해야 합니다.xbar.

와, 정말 흥미롭군요!

다른 사람들이 언급했듯이, 이것은 다음과 관련이 있는 것으로 보입니다.scope하지만 더 구체적으로 말하면, 관련이와 관련이 있습니다.debugger scope주입된 스크립트가 개발자 도구에서 평가될 때, 그것은 다음을 결정하는 것처럼 보입니다.ScopeChain(검사자/검사자 범위에 구속되기 때문에) 약간의 특이성이 발생합니다.게시한 내용의 변형은 다음과 같습니다.

(편집 - 사실, 당신은 원래 질문에서 이것을 언급했습니다, 이런, 잘못입니다!)

function foo() {
  var x = "bat";
  var y = "man";

  function bar() {
    console.log(x); // logs "bat"

    debugger; // Attempting to access "y" throws the following
              // Uncaught ReferenceError: y is not defined
              // However, x is available in the scopeChain. Weird!
  }
  bar();
}
foo();

야심이 있거나 호기심이 많은 분들은 출처를 파악하여 상황을 확인하시기 바랍니다.

https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/inspector https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/debugger

저는 이것이 변수와 함수 호이스트와 관련이 있다고 생각합니다.JavaScript는 모든 변수 및 함수 선언을 정의된 함수의 맨 위로 가져옵니다.자세한 내용은 http://jamesallardice.com/explaining-function-and-variable-hoisting-in-javascript/ 에서 확인할 수 있습니다.

함수에 다른 것이 없기 때문에 Chrome은 변수를 스코프에서 사용할 수 없는 상태에서 브레이크 포인트를 호출하고 있을 것입니다.이것은 효과가 있는 것 같습니다.

function baz() {
  var x = "foo";

  function bar() {
    console.log(x); 
    debugger;
  };
  bar();
}

이 경우:

function baz() {
  var x = "foo";

  function bar() {
    debugger;
    console.log(x);     
  };
  bar();
}

이 기능 및/또는 위 링크가 도움이 되기를 바랍니다.이것들은 제가 가장 좋아하는 SO 질문들입니다, BTW :)

에 접근할 수 있는 것 같습니다._this.어디에this크롬 인스펙터에 정의되어 있지 않습니다._this적절한 맥락을 참조하는 것처럼 보입니다. (그리고 아마도 그것은.> local > this스택 추적 검사기에서?).

이것이 약간 오래된 것이라는 것을 알지만, 제 문제는 바벨을 사용한 미니화였습니다. 즉, --presetsminify.

Js 코드가 생성되고 축소되었을 때 로컬 변수가 정의되지 않았습니다. 축소되지 않았을 때 콘솔에서 변수 값을 볼 수 있었습니다.

언급URL : https://stackoverflow.com/questions/28388530/why-does-chrome-debugger-think-closed-local-variable-is-undefined

반응형