다양한 실행 컨텍스트의 변수 개체
변수 개체의 일부 작업(예: 변수 초기화) 및 동작은 모든 유형의 실행 컨텍스트에 공통됩니다. 이러한 관점에서 보면 가변 객체를 추상적이고 기본적인 것으로 이해하는 것이 더 쉽습니다. 변수 개체와 관련된 추가 콘텐츠도 함수 컨텍스트에서 정의됩니다.
抽象变量对象VO (变量初始化过程的一般行为) ║ ╠══> 全局上下文变量对象GlobalContextVO ║ (VO === this === global) ║ ╚══> 函数上下文变量对象FunctionContextVO (VO === AO, 并且添加了<arguments>和<formal parameters>)
자세히 살펴보겠습니다:
전역 컨텍스트의 변수 개체
먼저 전역 개체에 명확한 정의를 제공해야 합니다.
글로벌 객체(Global object)는 어떤 실행 컨텍스트에 들어가기 전에 생성된 객체입니다. 이 개체의 복사본은 하나만 있으며 프로그램의 어느 곳에서나 해당 속성에 액세스할 수 있습니다. 전역 개체의 수명 주기는 프로그램이 종료되는 순간 종료됩니다.
전역 객체의 초기 생성 단계에서는 Math, String, Date,parseInt가 자체 속성으로 사용되며, 기타 속성은 추가로 생성된 다른 객체도 속성으로 초기화될 수 있습니다. 전역 객체 자체에). 예를 들어 DOM에서 전역 객체의 window 속성은 전역 객체 자체를 참조할 수 있습니다(물론 모든 특정 구현이 이와 같은 것은 아닙니다).
global = { Math: <...>, String: <...> ... ... window: global //引用自身 };
전역 객체의 속성은 이름으로 직접 액세스할 수 없으므로 접두사를 제거합니다. 그러나 우리는 여전히 전역 컨텍스트를 통해 전역 객체에 접근할 수 있고, 재귀적으로 그 자체를 참조할 수도 있습니다. 예를 들어 DOM의 창입니다. 요약하자면, 코드는 다음과 같이 단축될 수 있습니다:
String(10); // 就是global.String(10); // 带有前缀 window.a = 10; // === global.window.a = 10 === global.a = 10; this.b = 20; // global.b = 20;
그래서 전역 컨텍스트의 변수 개체로 돌아가서 여기서 변수 개체는 전역 개체 자체입니다.
VO(globalContext) === global;
이 원칙에 따라 해당 대응이 전역 컨텍스트에서 선언된 경우에만 해당 속성을 통해 간접적으로 액세스할 수 있습니다. 전역 객체(예를 들어 변수 이름을 미리 알지 못한 채).
var a = new String('test'); alert(a); // 直接访问,在VO(globalContext)里找到:"test" alert(window['a']); // 间接通过global访问:global === VO(globalContext): "test" alert(a === this.a); // true var aKey = 'a'; alert(window[aKey]); // 间接通过动态属性名称访问:"test"
함수 컨텍스트 내 변수 객체
함수 실행 컨텍스트에서는 VO에 직접 접근할 수 없습니다. 이때 활성화 객체(약칭 AO)가 VO Role 역할을 합니다.
VO(functionContext) === AO;
함수 컨텍스트에 진입하면 활성 객체가 생성되며, 함수의 인수 속성을 통해 초기화됩니다. Arguments 특성의 값은 Arguments 개체입니다.
AO = { arguments: <ArgO> };
Arguments 개체는 다음 특성을 포함하는 활성 개체의 특성입니다.
callee — 현재 개체에 대한 참조 function
length — 실제로 전달된 매개변수의 수
properties-indexes(문자열 유형의 정수) 속성의 값은 함수의 매개변수 값입니다(왼쪽에서 오른쪽으로 정렬됨). 매개변수 목록). Properties-indexes 내부의 요소 수는 Argument.length와 동일합니다. Properties-indexes의 값은 실제로 전달된 매개변수와 공유됩니다.
예:
function foo(x, y, z) { // 声明的函数参数数量arguments (x, y, z) alert(foo.length); // 3 // 真正传进来的参数个数(only x, y) alert(arguments.length); // 2 // 参数的callee是函数自身 alert(arguments.callee === foo); // true // 参数共享 alert(x === arguments[0]); // true alert(x); // 10 arguments[0] = 20; alert(x); // 20 x = 30; alert(arguments[0]); // 30 // 不过,没有传进来的参数z,和参数的第3个索引值是不共享的 z = 40; alert(arguments[2]); // undefined arguments[2] = 50; alert(z); // 40 } foo(10, 20);
이 예제의 코드에는 현재 버전의 Google Chrome에 버그가 있습니다. 매개변수 z가 전달되지 않더라도 z 및 인수[2]는 아직도 공유 중입니다.