JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해

WBOY
풀어 주다: 2022-03-29 11:49:39
앞으로
1767명이 탐색했습니다.

이 기사에서는 js 엔진이 js 코드를 실행하는 방법과 관련된 문제를 주로 소개하는javascript에 대한 관련 지식을 제공합니다. js 엔진은 js 코드를 실행할 때 위에서 아래로 어휘 분석과 문법 분석도 수행합니다. , 의미 분석 및 기타 처리를 수행하고 코드 구문 분석이 완료된 후 AST를 생성하는 것이 모든 사람에게 도움이 되기를 바랍니다.

JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해

관련 추천:javascript 튜토리얼

우리는 아마도 "실행 환경", "범위", "프로토타입(체인)", "실행 컨텍스트" 등과 같은 말을 자주 듣게 될 것입니다. 그들은 무엇을 설명합니까?

JS 코드 실행

우리는 js가 약한 유형의 언어이고 변수 유형은 런타임에만 결정된다는 것을 알고 있습니다. js 엔진은 js 코드를 실행할 때 위에서 아래로어휘 분석,문법 분석,의미 분석등의 프로세스를 수행하고, 코드 분석이 완료된 후 AST(추상 구문 트리)를 생성합니다. , 그리고 마지막으로 CPU가 실행하고 실행할 수 있는 AST Machine 코드를 기반으로 생성합니다.

또한 JS 엔진은 코드를 실행할 때 다른 처리도 수행합니다. 예를 들어 V8에는 두 가지 단계가 있습니다.

  • 컴파일 단계: 이 단계에서는 변수 객체(VO) 생성을 포함하여 실행 컨텍스트를 생성합니다. 이때는 정의되지 않음으로 초기화됩니다), 범위 체인 설정, 이 지점 결정 등을 수행합니다. 다른 운영 환경에 들어갈 때마다. V8은 항상 새로운 실행 컨텍스트를 생성합니다.
  • 실행 단계: 컴파일 단계에서 생성된 실행 컨텍스트를 호출 스택에 푸시하고 실행 중인 실행 컨텍스트가 됩니다. 코드가 실행된 후 호출 스택에서 제거합니다. (여기서 VO - AO 프로세스가 있습니다. JavaScript가 변수에 값을 할당할 때 변수를 사용합니다. 이때 변수 객체는 활성 객체로 변환되며, 변환된 활성 객체에 접근할 수 있습니다.)

이는 "실행 컨텍스트"와 "범위 체인"이라는 두 가지 개념으로 이어집니다.


JavaScript 실행 컨텍스트

위에서 우리는 알 수 있습니다: js 코드가 실행 가능한 코드 조각을 실행할 때 해당 실행 컨텍스트가 생성됩니다.
우선 js에서 실행 가능한 코드에 해당하는 개념이 있습니다: "실행 환경" - 전역 환경, 함수 환경 및eval.
둘째, 모든 실행 컨텍스트에는 세 가지 중요한 속성이 있습니다.

  • 변수 개체(예: "VO")
  • Scope Chain
  • this

두 가지 코드를 살펴보겠습니다.

var JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해="global JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해";function checkJavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해(){ var JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해="local JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해"; function f(){ return JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해; } return f();}checkJavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해();
로그인 후 복사
var JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해="global JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해";function checkJavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해(){ var JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해="local JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해"; function f(){ return JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해; } return f;}checkJavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해()();
로그인 후 복사

그들은 무엇을 인쇄할 것입니까? ?
JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해

왜요? 대답은 실행 컨텍스트 스택이 다르다는 것입니다!

"실행 컨텍스트 스택"이란 무엇입니까?
실행 가능한 코드를 실행할 때 미리 준비 작업을 하게 됩니다. 여기서의 "준비 작업"을 전문적으로는 "실행 컨텍스트"라고 합니다. 그런데 함수 등 실행 가능한 코드가 늘어나는데, 이렇게 많은 실행 컨텍스트를 어떻게 관리해야 할까요? 그래서 JS 엔진은 실행 컨텍스트 스택이라는 개념을 만들었습니다.
배열을 완전히 사용하여 동작을 시뮬레이션할 수 있습니다(스택 맨 아래에는 항상 전역 실행 컨텍스트 globalContext가 있습니다)

먼저 EStack을 정의하고

EStack=[globalContext];
로그인 후 복사

한 다음 첫 번째 코드 조각을 시뮬레이션합니다.

EStack.push( functionContext);EStack.push( functionContext);EStack.pop();EStack.pop();
로그인 후 복사

그리고 두 번째 코드는 다음과 같습니다:

EStack.push( functionContext);EStack.pop();EStack.push( functionContext);EStack.pop();
로그인 후 복사

그 이유는 "클로저" 개념을 먼저 공부해야 할 수도 있기 때문입니다!

그런데 "프론트엔드 모듈화"에서 "장기간 데이터 저장"을 어떻게 구현하나요?
캐싱? 아니요. 폐쇄!


JavaScript 범위 및 범위 체인

먼저 범위는 프로그램에서 변수가 정의되는 영역을 나타냅니다. 범위는 변수를 찾는 방법을 지정하며, 이는 현재 실행 중인 코드의 변수에 대한 액세스 권한을 결정합니다.
범위에는정적 범위동적 범위의 두 가지 유형이 있습니다.
JS에서 채택한 정적 범위를 "어휘 범위"라고도 합니다. 함수의 범위는 함수가 정의될 때 결정됩니다.

위에서 어휘 범위의 변수는 컴파일 과정에서 특정 범위를 갖습니다. 이 범위는 "현재 실행 컨텍스트"입니다. ES5 이후에는 실행 컨텍스트를 설명하기 위해 범위 대신 "어휘적 환경"을 사용합니다. 어휘 환경은 두 가지 구성원으로 구성됩니다.

  • 자체 어휘 환경 레코드: 자체 어휘 환경에 변수 객체를 기록하는 데 사용됩니다.
  • 외부 어휘 환경 참조: 외부 어휘 환경에 존재하는 참조를 기록하는 데 사용됩니다.

우리는 여전히 여기에 있습니다. 예를 보세요:

var JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해=1;function foo(){ console.log(JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해);}function bar(){ var JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해=2; foo();}bar();
로그인 후 복사

위의 정의를 다시 보면, 무엇을 인쇄해야 할까요?

JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해

실행 과정을 분석해 보겠습니다.
foo() 함수를 실행하고 먼저 foo 함수 내부에 지역 변수 값이 있는지 검색합니다. 그렇지 않은 경우는 정의된 위치, 즉 JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해=1을 기준으로 상위 레이어의 코드를검색하므로 결과는 1로 인쇄됩니다.

물론 그렇게 간단하지는 않고 실행 컨텍스트 관점에서 요약할 수 있습니다.

建立作用域链

上面我们说了词法环境(作用域)的两个组成。再结合执行上下文,我们不难发现:通过外部词法环境的引用,作用域可以顺着栈层层拓展,建立起从当前环境向外延伸的一条链式结构。

再来看一个例子:

function foo(){ console.dir(bar); var a=1; function bar(){ a=2; }}console.dir(foo);foo();
로그인 후 복사

由静态作用域,全局函数foo创建了一个自身对象的[[JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해]]属性

foo[[JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해]]=[globalContext];
로그인 후 복사

而当我们执行foo()时,也会先后进入foo函数的定义期和执行期。在foo函数的定义期时,函数bar的[[JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해]]将会包含全局内置JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해和foo的内置JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해

bar[[JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해]]=[fooContext,globalContext];
로그인 후 복사

这证明了这一点:“JS会通过外部词法环境引用来创建变量对象的一个作用域链,从而保证对执行环境有权访问的变量和函数的有序访问。”

让我们再回头看看执行上下文中的那道题,在前面我们说了它们有什么不同,这里说下为什么它们相同地打印了“local JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해”:还是那句话“JS采用的是词法作用域,函数的作用域取决于函数创建的位置” —— JS函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해一定是指局部变量,不管何时何地执行 f() ,这种绑定在执行 f() 时依然有效。

基于作用域链的变量查询

当某个变量无法在自身词法环境记录中找到时,可以根据外部词法环境引用向外层进行寻找,直到最外层的词法环境中外部词法环境引用为null
与此相似的是“对象中基于原型链的查找”:

  • 原型:每一个JS对象(null 除外)在创建时就会与另一个对象关联,这个对象就是我们说的原型。每一个对象都会从原型中“继承”属性。
  • 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还找不到,就去找原型的原型,一直到最顶层(__proto__为null)为止

它们的区别也显而易见:原型链是通过 prototype 属性建立对象继承的链接;而作用域链是指内部函数能访问到外部函数的闭包。不管直接还是间接,所有函数的作用域链最终都链接到全局上下文。

相关推荐:javascript学习教程

위 내용은 JavaScript 엔진이 JS 코드를 실행하는 방법에 대한 깊은 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:csdn.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!