>  기사  >  웹 프론트엔드  >  Javascript의 실행 컨텍스트에 관한 기사

Javascript의 실행 컨텍스트에 관한 기사

青灯夜游
青灯夜游앞으로
2023-02-14 19:41:062313검색

이 기사에서는 Javascript의 실행 컨텍스트에 대해 이야기하고 사고 질문을 공유합니다. 사고 질문 분석을 통해 실행 컨텍스트에 대해 더 깊이 이해하게 될 것입니다.

Javascript의 실행 컨텍스트에 관한 기사

이전 기사에서는 실행 컨텍스트의 세 가지 중요한 구성원인 변수 객체, 범위 체인 및 this에 대해 심층적으로 이해했습니다. 이 기사는 처음 네 기사의 내용을 모아서 정리한 것입니다. .흩어진 지식 포인트를 간단하게 통합합니다. 지난 글에서 질문을 남기신 분이 계시는지 모르겠습니다. 질문 분석을 통해 실행 맥락에 대해 더 깊이 이해할 수 있게 되었습니다.

생각하는 질문

사례를 좀 더 복잡하게 만들기 위해 몇 가지 수정 사항을 적용했지만 원래 질문에서 검토한 사항은 변경되지 않았습니다.

function func(value){
    getValue = function(){
        console.log(value);
    };
    return this
}
            
function getValue(){
    console.log(5);
}

Func(1).getValue(); //为什么是1呢?

특정 실행 분석

전역 코드 실행, 전역 실행 컨텍스트 생성, 전역 컨텍스트가 실행 컨텍스트 스택으로 푸시됨

ECStack = [ globalContext ];

전역 컨텍스트 초기화

globalContext = {
    VO: {
        func: reference to function func(){},
        getValue: reference to function getValue(){}
    },
    Scope: [globalContext.VO],
    this: globalContext.VO //全局上下文
}

전역 컨텍스트 초기화 및 두 가지 함수 생성 동시에 저장되므로 상위 범위 체인은 내부 속성 [[scope]] 내에 있습니다.

func.[[scope]] = [
     globalContext.VO
];
getValue.[[scope]] = [
     globalContext.VO
];

이 시점에서 코드 실행이 시작됩니다. 마지막 문이 실행되면 func 함수가 먼저 실행되어 생성됩니다. 단계별 func 함수 실행 컨텍스트:

  • 함수 [[scope]] 속성을 복사하여 범위 체인을 만듭니다

  • 인수를 사용하여 활성 개체 만들기

  • 활성 개체 초기화

  • 활성 개체를 checksfunccope 범위 체인의 맨 위로 밀어 넣습니다.

  • 다음과 같은 간단한 분석을 생성합니다. MemberExpression 값은 func이고, func는 함수 객체(물론 참조)입니다. 여기서 기본 값은 EnvironmentRecord이므로 이 값은 ImplicitThisValue(ref)이고 반환 값은 항상 정의되지 않습니다. , 엄격하지 않은 모드에서는 해당 값이 암시적으로 전역 객체로 변환됩니다.

funcContext = {
    AO: {
        arguments: { // 数组
            0: 1,
            length: 1
        }
    },
    Scope: [AO, globalContext.VO],
    this: undefined
}

어떤 사람들은 질문이 있을 수 있습니다. func의 getValue는 어떻습니까? , 변수 선언이 없기 때문에 실제로는 나중에 런타임 시 실행되는 속성 할당 작업입니다.

함수 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시합니다

    ECStack = [
        funcContext,
        globalContext
    ];

함수가 실행되기 시작합니다. 이것이 최종 출력이 1인 이유의 핵심입니다. 먼저 funcContext.AO를 찾습니다. 그런 다음 범위 체인을 검색하여 globalContext.VO를 찾습니다. 이번에는 전역 범위에서 getValue 속성을 재할당하여 함수 범위를 다시 생성하고 이 새 getValue 함수의 상위 범위 체인을 내부 속성에 저장하는 함수의 새 버전을 할당합니다. ] 내부:

getValue .[[scope]] = [ funcContext.AO, globalContext.VO ];

그런 다음 계속해서 이것을 반환하고 funcContext에서 이것을 찾으십시오. 즉, func 실행 컨텍스트가 스택에서 튀어나옵니다

ECStack = [ globalContext ];

계속 Func(1).getValue()를 실행합니다. > 의 경우 전반부는 정의되지 않은 값을 반환합니다. 이때 시스템은 암시적으로 전역 변수 객체로 변환하고 전역 변수 객체에서 getValue 속성을 찾습니다. 이때 우리는 getValue가 더 이상 그 당시의 소년이 아니라는 것을 발견했습니다. 새 getValue를 실행하는 함수 실행 컨텍스트가 스택에 푸시되었습니다.

getValueContext = {
    AO: {
        arguments: { // 数组
            length: 0
        }
    },
    Scope: [ AO, funcContext.AO, globalContext.VO ],
    this: undefined
} ECStack = [
    getValueContext,
    globalContext
 ];
Func(1).getValue(),前半部分返回了 undefined ,此时系统隐式转换为全局变量对象,从全局变量对象中找到 getValue 属性。这时候我们发现 getValue 早已不是当年那个少年,执行全新的 getValue 的函数执行上下文并入栈:

rrreee

函数开始执行,发现她要输出 value함수가 실행되기 시작했고 value, 범위를 따라 검색했습니다. getValueContext.AO에 해당 속성이 없습니다. 계속해서 funcContext.AO를 찾으세요(Attention!). , 해당 값이 출력되고 1이 출력됩니다.

함수 실행이 완료되고 getValueContext와 globalContext가 스택에서 팝되어 차례로 소멸되며 코드가 완성됩니다.

Summary

이 영화는 JS 코드가 실행될 때 실행 컨텍스트의 작업 프로세스를 완벽하게 분석하기 위해 간단하지만 단순하지 않은 예제를 사용합니다. . 그러나 주의깊은 학생들은 위의 예에서 getValue 함수를 실행하는 동안 속성값을 찾는 단계(위치를 표시하는 단계)부터 그 때 분명히 func 함수가 실행되었다는 사실을 발견했을지 궁금합니다. 실행 컨텍스트가 해제되었는데 왜 여전히 실행 컨텍스트에서 value 속성을 찾을 수 있나요? 이것이 실제로 클로저 생성의 원리입니다. 다음 기사에서는 이 예제를 사용하여 클로저 생성의 원리를 배울 것입니다.

【추천 학습: javascript 고급 튜토리얼

위 내용은 Javascript의 실행 컨텍스트에 관한 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제