오랜시간 JavaScript를 배워왔습니다
오늘은 스코프에 대한 지식을 복습해 보려고 합니다
스코프에 대한 지식은 매우 기본적이고 매우 중요합니다
요약하자면 JavaScript의 범위에 대한 지식 범위 및 범위 체인에 대한 지식
범위
범위란 무엇인가요?
범위는변수를 참조하고 함수가 적용되는 영역
메모리 공간에서 값을 얻고 수정하는 능력을 제한합니다
범위는 모든 언어에 존재합니다
범위를 js 엔진이 이름을 기준으로 변수를 찾는 일련의 규칙
범위를 이해하면 클로저와 같은 일련의 문제를 이해할 수 있습니다
[[Scope ]]
우리 모두 알고 있듯이 함수는 특별한 실행 가능 객체입니다
객체이기 때문에 속성을 가질 수 있습니다
내부 속성인 [[Scope]]가 있습니다. 함수 (사용할 수 없습니다. js 엔진에서 사용)
함수가 생성되면 이 내부 속성에는 함수가 생성된 범위의 객체 컬렉션이 포함됩니다.
이 컬렉션은 체인으로 연결되어 있으며 를 함수의 범위 체인이라고 합니다
범위 체인의 각 개체를 변수 개체(Variable Object)라고 합니다.
모든 변수 개체는 키-값 쌍의 형태로 존재합니다
예를 들어보세요. 다음 전역 함수
var a = 1;function foo(){ ...}
foo 함수가 생성되면 전역적으로 정의된 모든 변수를 포함하여 전역 객체 GO(Global Object)가 스코프 체인에 삽입됩니다.
// 伪代码 foo.[[Scope]] = { GO: { this: window , window: ... , document: ... , ...... a: undefined, // 预编译阶段还不知道a值是多少 foo: function(){...}, } }
실행 환경
함수가 실행되면 실행 환경/실행 컨텍스트라는 내부 객체가 생성됩니다
함수가 실행될 때의 환경을 정의합니다
실행 환경은 함수가 실행될 때마다 고유합니다
함수는 여러 번 호출됩니다. 실행 환경
은 한 번 생성되고 함수가 실행된 후에는 실행 환경이 삭제됩니다.
실행 환경에는 식별자를 구문 분석하는 데 사용되는 자체 범위 체인이 있습니다. >
[[Scope]]와 실행 컨텍스트는 스코프 체인을 저장하지만 서로 다릅니다
차이점을 명확히 해보자
[[범위] ]속성은 함수가 생성될 때 생성되며 항상 존재합니다
그리고 실행 컨텍스트는 함수가 실행될 때 생성됩니다.
var a = 1;function foo(x, y){ var b = 2; function bar(){ var c = 3; } bar(); } foo(100, 200);이제 다음 코드를 통해 스코프 체인과 실행 환경을 자세히 설명하겠습니다
그래도 제가 작성한 pre-compilation을 모든 학생들에게 꼭 보길 권합니다
- 먼저 실행 흐름에서 foo() 함수가 글로벌 환경에서 생성됩니다(생성됨). 사전 컴파일 단계에서) foo 함수에는 [[Scope]]
// 伪代码:foo函数创建产生[[Scope]]对象 foo.[[Scope]] = { GO: { this: window , window: ... , document: ... , a: undefined, //预编译阶段还不知道a的值是多少,执行过程中会修改 foo: function(){...}, ...... } }
- 속성이 있습니다. foo 함수가 실행되기 전에 실행 컨텍스트는 다음과 같습니다. (실행 컨텍스트는 당분간 EC로 작성하겠습니다. 내부 이름은 모르겠습니다.) 실행 컨텍스트는 foo라는 내부 이름을 얻습니다. [[Scope]에 의해 저장된 스코프 체인(복사본) ] 속성은 foo 함수를 실행하기 전에 사전 컴파일되어 활성 객체 AO(Active Object)를 생성합니다. 이 객체는 EC 범위 체인
// 伪代码:foo函数执行前产生执行期上下文EC复制foo中[[Scope]]属性保存的作用域链 foo.EC = { GO: { this: window , window: ... , document: ... , a: 1, foo: function(){...}, ...... } }
// 伪代码:foo函数预编译产生AO活动对象,挂载到foo中EC作用域链的最前端 foo.EC = { AO: { this: window, arguments: [100,200], x: 100, y: 200, b: undefined, bar: function(){...} }, GO: { this: window , window: ... , document: ... , a: 1, foo: function(){...}, ...... } }
- foo 함수는 컴파일 전 단계에서 bar 함수를 생성했기 때문에 bar 함수는 bar가 생성된 범위의 객체 컬렉션을 포함하는 [[Scope]] 속성을 생성했으며, foo.EC
-
// 伪代码:bar函数创建产生[[Scope]]对象 bar.[[Scope]] = { AO: { this: window, arguments: [100,200], x: 100, y: 200, b: undefined, bar: function(){...} }, GO: { this: window , window: ... , document: ... , a: 1, foo: function(){...}, ...... } }
- bar 함수 실행과 프로세스가 유사합니다. 최종 결과를 직접 작성했습니다
-
.
// 伪代码:bar函数执行产生执行上下文 bar.EC = { AO: { this: window, arguments: [], c: undefined, }, AO: { this: window, arguments: [100,200], x: 100, y: 200, b: 2, bar: function(){...} }, GO: { this: window , window: ... , document: ... , a: 1, foo: function(){...}, ...... } }
- bar 함수가 실행되고 실행 환경이 파괴되는데 이는
delete bar.EC
foo 함수가 실행되고 실행 환경이 파괴됩니다. 이는 프로그램이 delete foo.EC
- 변수 구문 분석 프로세스
에서 종료되는 것과 동일합니다. 제가 그렇게 많이 쓴 내용을 이해하셨는지 모르겠습니다
js 엔진은 스코프 체인의 규칙을 통해 변수를 검색합니다(정확하게는 실행 컨텍스트의 스코프 체인이어야 합니다)검색은 프로세스는 위 코드를 예로 들어 bar 함수에 한 줄을 추가합니다
그런 다음 bar 함수가 실행되면 js 엔진이 a를 인쇄하려고 하므로 범위 체인으로 이동합니다. find console.log(a);
첫 번째 레이어 AO를 찾을 수 없습니다
두 번째 레이어 AO를 찾을 수 없습니다
세 번째 레이어 GO는 변수 a
를 찾은 다음 변수 a의 값을 반환합니다
. 범위를 이해하면 글로벌 환경이 로컬 환경에 접근할 수 없는 이유를 이해하게 됩니다
性能问题
今天写high了,像吃了炫迈一样,那就顺便把性能问题也说清楚了吧
js引擎查找作用域链是为了解析标识符
占用了时间理所当然的产生了性能开销
所以解析标识符有代价,你的变量在执行环境作用域链的位置越深,读写速度就越慢
这很容易理解
在函数中读写局部变量总是最快的,读写全局变量通常最慢
当然了,这些额外的性能开销对于优化js引擎(比如chrome的V8 (⊙▽⊙))来说可能微不足道,甚至可以毫不夸张的说没有性能损失
但是还是要照顾大多浏览器
所以推荐大家养成这样的编码习惯:尽量使用局部变量(缓存)
我举一个小例子
function demo(){ var a = document.getElementById('a'); var b = document.getElementById('b'); var c = document.getElementById('c'); a.onclick = function(){ ... } a.style.left = ...; a.style.top = ...; b.style.backgroundColor = ...; c.className = ...; document.body.appendChild(...); document.body.appendChild(...); document.body.appendChild(...); }
这段代码看起来缓存了,优化了代码
但其实这段代码执行过程中,js引擎解析标识符,要查找6次document
而且document存在于window对象
也就是作用域链的最末尾
所以我们再进行缓存,包括document.body、a.style
再加上单一var原则
重构函数
function demo(){ var doc = document, bd = doc.body, a = doc.getElementById('a'), b = doc.getElementById('b'), styleA = a.style; a.onclick = function(){ ... } styleA.left = ...; styleA.top = ...; styleA.backgroundColor = ...; b.className = ...; bd.appendChild(...); bd.appendChild(...); bd.appendChild(...); }
总结
其实写了这么多,还有一个问题我没写到,就是作用域链在某些特殊情况下是可以动态改变的
比如with()、eval()等等,当然这些都不建议使用,我总结了一篇文章
有兴趣的同学可以看看 ->传送门还是总结一下今天写的作用域链相关知识
作用域是变量能够引用、函数能够生效的区域
函数创建时,产生内部属性[[Scope]]包含函数被创建的作用域中对象的集合(作用域链)
作用域链上每个对象称为可变对象(Variable Obejct),
每一个可变对象都以键值对形式存在(VO要细分的话,全局对象GO和活动对象AO)函数执行时,创建内部对象叫做执行环境/执行上下文(execution context)
它定义了一个函数执行时的环境,函数每次执行时的执行环境独一无二
函数执行结束便会销毁js引擎就通过函数执行上下文的作用域链规则来进行解析标识符(用于读写),从作用域链顶端依次向下查找
尽量缓存局部变量,减少作用域查找性能开销(照顾未优化浏览器)
以上就是JavaScript内部属性[[Scope]]与作用域链及其性能问题的内容,更多相关内容请关注PHP中文网(www.php.cn)!

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.

Python은 데이터 과학 및 기계 학습에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명하며 데이터 분석 및 웹 개발에 적합합니다. 2. JavaScript는 프론트 엔드 개발의 핵심입니다. Node.js는 서버 측 프로그래밍을 지원하며 풀 스택 개발에 적합합니다.

JavaScript는 이미 최신 브라우저에 내장되어 있기 때문에 설치가 필요하지 않습니다. 시작하려면 텍스트 편집기와 브라우저 만 있으면됩니다. 1) 브라우저 환경에서 태그를 통해 HTML 파일을 포함하여 실행하십시오. 2) Node.js 환경에서 Node.js를 다운로드하고 설치 한 후 명령 줄을 통해 JavaScript 파일을 실행하십시오.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.
