찾다
웹 프론트엔드JS 튜토리얼JS의 세 가지 산인 범위 및 폐쇄, 프로토타입 및 프로토타입 체인, 비동기 및 단일 스레드에 대한 자세한 설명

js는 프런트엔드의 백본 역할을 합니다. 그렇다면 자바스크립트의 3대 산이 무엇인지 아시나요?

1️⃣ 범위 및 폐쇄

범위作用域 指代码当前上下文,控制着变量和函数的可见性和生命周期。最大的作用是隔离变量,不同作用域下同名变量不会冲突。

作用域链 指如果在当前作用域中没有查到值,就会向上级作用域查询,直到全局作用域,这样一个查找过程所形成的链条就被称之为作用域链。【推荐学习:javascript视频教程

作用域可以堆叠成层次结构,子作用域可以访问父作用域,反之则不行。

作用域具体可细分为四种:全局作用域模块作用域函数作用域块级作用域

全局作用域: 代码在程序的任何地方都能被访问,例如 window 对象。但全局变量会污染全局命名空间,容易引起命名冲突。

模块作用域: 早期 js 语法中没有模块的定义,因为最初的脚本小而简单。后来随着脚本越来越复杂,就出现了模块化方案(AMD、CommonJS、UMD、ES6模块等)。通常一个模块就是一个文件或者一段脚本,而这个模块拥有自己独立的作用域。

函数作用域: 顾名思义由函数创建的作用域。闭包就是在该作用域下产生,后面我们会单独介绍。

块级作用域: 由于 js 变量提升存在变量覆盖、变量污染等设计缺陷,所以 ES6 引入了块级作用域关键字来解决这些问题。典型的案例就是 let 的 for 循环和 var 的 for 循环。

// var demo
for(var i=0; i<10; i++) {
    console.log(i);
}
console.log(i); // 10

// let demo
for(let i=0; i<10; i++) {
    console.log(i);
}
console.log(i); //ReferenceError:i is not defined

了解完作用域再来谈谈 闭包 函数A里包含了函数B,而函数B使用了函数A的变量,那么函数B被称为闭包或者闭包就是能够读取函数A内部变量的函数。

可以看出闭包是函数作用域下的产物,闭包会随着外层函数的执行而被同时创建,它是一个函数以及其捆绑的周边环境状态的引用的组合。换而言之,闭包是内层函数对外层函数变量的不释放

闭包的特征:

  • 函数中存在函数;
  • 内部函数可以访问外层函数的作用域;
  • 参数和变量不会被 GC,始终驻留在内存中;
  • 有内存地方才有闭包。

所以使用闭包会消耗内存、不正当使用会造成内存溢出的问题,在退出函数之前,需要将不使用的局部变量全部删除。如果不是某些特定需求,在函数中创建函数是不明智的,闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

以下整理了闭包的应用场景:

// demo1 输出 3 3 3
for(var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
} 
// demo2 输出 0 1 2
for(let i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
// demo3 输出 0 1 2
for(let i = 0; i < 3; i++) {
    (function(i){
        setTimeout(function() {
        console.log(i);
        }, 1000);
    })(i)
}
/* 模拟私有方法 */
// 模拟对象的get与set方法
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
    privateCounter += val;
}
return {
    increment: function() {
    changeBy(1);
    },
    decrement: function() {
    changeBy(-1);
    },
    value: function() {
    return privateCounter;
    }
}
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
/* setTimeout中使用 */
// setTimeout(fn, number): fn 是不能带参数的。使用闭包绑定一个上下文可以在闭包中获取这个上下文的数据。
function func(param){ return function(){ alert(param) }}
const f1 = func(1);setTimeout(f1,1000);
/* 生产者/消费者模型 */
// 不使用闭包
// 生产者
function producer(){
    const data = new(...)
    return data
}
// 消费者
function consumer(data){
    // do consume...
}
const data = producer()

// 使用闭包
function process(){
    var data = new (...)
    return function consumer(){
        // do consume data ...
    }
}
const processer = process()
processer()
/* 实现继承 */
// 以下两种方式都可以实现继承,但是闭包方式每次构造器都会被调用且重新赋值一次所以,所以实现继承原型优于闭包
// 闭包
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}
// 原型
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

对于闭包的概念好像懂了但又好像缺少了啥?意犹未尽。我也曾也闭包中迷失,但是看完闭包的生命周期让我重新找回自己。

JS의 세 가지 산인 범위 및 폐쇄, 프로토타입 및 프로토타입 체인, 비동기 및 단일 스레드에 대한 자세한 설명

学完就来一波牛刀小试

function test(a, b){
  console.log(b);
  return {
    test: function(c) {
      return test(c,a);
    }
  }
}

var a = test(100);a.test(101);a.test(102);
var b = test(200).test(201).test(202);
var c = test(300).test(301);c.test(302);

// undefined  100  100
// undefined  200 201
// undefined  300 301

2️⃣ 原型和原型链

有对象的地方就有 原型,每个对象都会在其内部初始化一个属性,就是prototype(原型),原型中存储共享的属性和方法。当我们访问一个对象的属性时,js引擎会先看当前对象中是否有这个属性,如果没有的就会查找他的prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。这么一个寻找的过程就形成了 原型链는 변수와 함수의 가시성과 수명 주기를 제어하는 ​​코드의 현재 컨텍스트를 나타냅니다. 가장 큰 기능은 변수를 격리하여 다른 범위에서 동일한 이름을 가진 변수가 충돌하지 않도록 하는 것입니다.

Scope Chain

은 현재 범위에서 값을 찾을 수 없으면 전역 범위까지 상위 범위를 쿼리한다는 의미입니다. 이러한 검색 프로세스로 형성된 체인을 범위라고 합니다. 체인. [추천 학습: javascript 비디오 튜토리얼]🎜🎜 범위는 계층 구조로 쌓일 수 있으며 하위 범위는 상위 범위에 액세스할 수 있지만 그 반대는 불가능합니다. 🎜🎜범위는 네 가지 유형으로 나눌 수 있습니다: 🎜전역 범위🎜, 🎜모듈 범위🎜, 🎜함수 범위🎜 , 🎜 블록 수준 범위🎜🎜🎜🎜전역 범위: 🎜 코드는 창 개체 등 프로그램 내 어디에서나 액세스할 수 있습니다. 그러나 전역 변수는 전역 네임스페이스를 오염시키고 쉽게 이름 충돌을 일으킬 수 있습니다. 🎜🎜🎜모듈 범위: 🎜 원래 스크립트가 작고 단순했기 때문에 초기 js 구문에는 모듈 정의가 없었습니다. 나중에 스크립트가 점점 더 복잡해지면서 모듈식 솔루션(AMD, CommonJS, UMD, ES6 모듈 등)이 등장했습니다. 일반적으로 모듈은 파일이나 스크립트이며 이 모듈은 자체적인 독립적인 범위를 갖습니다. 🎜🎜🎜함수 범위:🎜 이름에서 알 수 있듯이 함수에 의해 생성된 범위입니다. 클로저는 이 범위에서 생성되며 나중에 별도로 소개하겠습니다. 🎜🎜🎜블록 수준 범위: 🎜 js 변수 승격에는 변수 적용 범위 및 변수 오염과 같은 설계 결함이 있으므로 ES6에서는 이러한 문제를 해결하기 위해 블록 수준 범위 키워드를 도입했습니다. 일반적인 경우는 let의 for 루프와 var의 for 루프입니다. 🎜
const arr = [1, 2, 3];
arr.__proto__ === Array.prototype; // true
arr.__proto__.__proto__ === Object.prototype; // true
Array.__proto__ === Function.prototype; // true
🎜스코프를 이해한 후 이야기해 봅시다🎜클로저:🎜 함수 A는 함수 B를 포함하고, 함수 B는 함수 A의 변수를 사용하며, 함수 B를 클로저 또는 클로저 A 패키지라고 합니다. 함수 A의 내부 변수를 읽을 수 있는 함수입니다. 🎜🎜클로저는 함수 범위의 산물임을 알 수 있습니다. 클로저는 외부 함수가 실행됨과 동시에 함수와 주변 환경 상태에 대한 번들 참조가 결합된 것입니다. 즉, 🎜 클로저는 외부 함수 변수를 해제 🎜 하지 않는 내부 함수입니다. 🎜🎜🎜클로저의 특징: 🎜🎜
  • 함수 내에 함수가 있습니다.
  • 내부 함수는 외부 함수의 범위에 액세스할 수 있습니다.
  • 매개변수와 변수는 액세스할 수 없습니다. GC가 되며 항상 메모리에 상주합니다.
  • 메모리가 있는 경우에만 클로저가 있습니다.
🎜따라서 클로저를 사용하면 메모리가 소모되며, 부적절하게 사용하면 함수를 종료하기 전에 사용되지 않는 모든 지역 변수를 삭제해야 합니다. 특정 요구 사항이 아닌 경우 함수 내에 함수를 만드는 것은 현명하지 않습니다. 클로저는 처리 속도와 메모리 소비 측면에서 스크립트 성능에 부정적인 영향을 미칩니다. 🎜🎜🎜클로저 적용 시나리오는 다음과 같습니다. 🎜🎜rrreeerrreeerrreeerrreeerrreee🎜클로저의 개념을 이해한 것 같은데 뭔가 빠진 것 같나요? 의미는 아직 끝나지 않았습니다. 나 또한 클로저에 대해 길을 잃었지만, 클로저의 수명주기를 읽고 나서 다시 나를 발견했습니다. 🎜🎜한 그림에서 클로저의 수명주기를 이해하세요🎜🎜배운 후 간단한 테스트를 해보자🎜rrreee

🎜2️⃣ 프로토타입과 프로토타입 체인🎜🎜🎜객체가 있는 곳에는🎜프로토타입이 있다 code >🎜, 각 객체는 그 내부의 속성, 즉 프로토타입을 초기화하고 프로토타입은 공유 속성과 메서드를 저장합니다. 객체의 속성에 접근할 때, js 엔진은 먼저 현재 객체에 이 속성이 있는지 확인하고, 그렇지 않다면 해당 프로토타입 객체에 이 속성이 있는지 확인하며, Object 내장 객체가 검색될 때까지 계속됩니다. 이러한 검색 과정이 🎜<code>프로토타입 체인🎜이라는 개념을 형성했습니다. 🎜🎜프로토타입을 이해하는 데 가장 중요한 것은 __proto__, 프로토타입 및 생성자 간의 관계를 명확히 하는 것입니다. 먼저 몇 가지 개념을 살펴보겠습니다. 🎜
  • __proto__属性在所有对象中都存在,指向其构造函数的prototype对象;prototype对象只存在(构造)函数中,用于存储共享属性和方法;constructor属性只存在于(构造)函数的prototype中,指向(构造)函数本身。
  • 一个对象或者构造函数中的隐式原型__proto__的属性值指向其构造函数的显式原型 prototype 属性值,关系表示为:instance.__proto__ === instance.constructor.prototype
  • 除了 Object,所有对象或构造函数的 prototype 均继承自 Object.prototype,原型链的顶层指向 null:Object.prototype.__proto__ === null
  • Object.prototype 中也有 constructor:Object.prototype.constructor === Object
  • 构造函数创建的对象(Object、Function、Array、普通对象等)都是 Function 的实例,它们的 __proto__ 均指向 Function.prototype。

看起来是不是有点乱??别慌!!一张图帮你整理它们之间的关系

JS의 세 가지 산인 범위 및 폐쇄, 프로토타입 및 프로토타입 체인, 비동기 및 단일 스레드에 대한 자세한 설명

相同的配方再来一刀

const arr = [1, 2, 3];
arr.__proto__ === Array.prototype; // true
arr.__proto__.__proto__ === Object.prototype; // true
Array.__proto__ === Function.prototype; // true

3️⃣ 异步和单线程

JavaScript 是 单线程 语言,意味着只有单独的一个调用栈,同一时间只能处理一个任务或一段代码。队列、堆、栈、事件循环构成了 js 的并发模型,事件循环 是 JavaScript 的执行机制。

为什么js是一门单线程语言呢?最初设计JS是用来在浏览器验证表单以及操控DOM元素,为了避免同一时间对同一个DOM元素进行操作从而导致不可预知的问题,JavaScript从一诞生就是单线程。

既然是单线程也就意味着不存在异步,只能自上而下执行,如果代码阻塞只能一直等下去,这样导致很差的用户体验,所以事件循环的出现让 js 拥有异步的能力。

JS의 세 가지 산인 범위 및 폐쇄, 프로토타입 및 프로토타입 체인, 비동기 및 단일 스레드에 대한 자세한 설명

更多编程相关知识,请访问:编程教学!!

위 내용은 JS의 세 가지 산인 범위 및 폐쇄, 프로토타입 및 프로토타입 체인, 비동기 및 단일 스레드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 掘金社区에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
Python vs. JavaScript : 성능 및 효율성 고려 사항Python vs. JavaScript : 성능 및 효율성 고려 사항Apr 30, 2025 am 12:08 AM

파이썬과 자바 스크립트 간의 성능과 효율성의 차이는 주로 다음과 같이 반영됩니다. 1) 해석 된 언어로서, 파이썬은 느리게 실행되지만 개발 효율이 높고 빠른 프로토 타입 개발에 적합합니다. 2) JavaScript는 브라우저의 단일 스레드로 제한되지만 멀티 스레딩 및 비동기 I/O는 Node.js의 성능을 향상시키는 데 사용될 수 있으며 실제 프로젝트에서는 이점이 있습니다.

JavaScript의 기원 : 구현 언어 탐색JavaScript의 기원 : 구현 언어 탐색Apr 29, 2025 am 12:51 AM

JavaScript는 1995 년에 시작하여 Brandon Ike에 의해 만들어졌으며 언어를 C로 실현했습니다. 1.C Language는 JavaScript의 고성능 및 시스템 수준 프로그래밍 기능을 제공합니다. 2. JavaScript의 메모리 관리 및 성능 최적화는 C 언어에 의존합니다. 3. C 언어의 크로스 플랫폼 기능은 자바 스크립트가 다른 운영 체제에서 효율적으로 실행하는 데 도움이됩니다.

무대 뒤에서 : 어떤 언어의 힘이 자바 스크립트입니까?무대 뒤에서 : 어떤 언어의 힘이 자바 스크립트입니까?Apr 28, 2025 am 12:01 AM

JavaScript는 브라우저 및 Node.js 환경에서 실행되며 JavaScript 엔진을 사용하여 코드를 구문 분석하고 실행합니다. 1) 구문 분석 단계에서 초록 구문 트리 (AST)를 생성합니다. 2) 컴파일 단계에서 AST를 바이트 코드 또는 기계 코드로 변환합니다. 3) 실행 단계에서 컴파일 된 코드를 실행하십시오.

파이썬과 자바 스크립트의 미래 : 트렌드와 예측파이썬과 자바 스크립트의 미래 : 트렌드와 예측Apr 27, 2025 am 12:21 AM

Python 및 JavaScript의 미래 추세에는 다음이 포함됩니다. 1. Python은 과학 컴퓨팅 분야에서의 위치를 ​​통합하고 AI, 2. JavaScript는 웹 기술의 개발을 촉진하고, 3. 교차 플랫폼 개발이 핫한 주제가되고 4. 성능 최적화가 중점을 둘 것입니다. 둘 다 해당 분야에서 응용 프로그램 시나리오를 계속 확장하고 성능이 더 많은 혁신을 일으킬 것입니다.

Python vs. JavaScript : 개발 환경 및 도구Python vs. JavaScript : 개발 환경 및 도구Apr 26, 2025 am 12:09 AM

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.

JavaScript가 C로 작성 되었습니까? 증거를 검토합니다JavaScript가 C로 작성 되었습니까? 증거를 검토합니다Apr 25, 2025 am 12:15 AM

예, JavaScript의 엔진 코어는 C로 작성되었습니다. 1) C 언어는 효율적인 성능과 기본 제어를 제공하며, 이는 JavaScript 엔진 개발에 적합합니다. 2) V8 엔진을 예를 들어, 핵심은 C로 작성되며 C의 효율성 및 객체 지향적 특성을 결합하여 C로 작성됩니다.

JavaScript의 역할 : 웹 대화식 및 역동적 인 웹JavaScript의 역할 : 웹 대화식 및 역동적 인 웹Apr 24, 2025 am 12:12 AM

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript : 연결이 설명되었습니다C 및 JavaScript : 연결이 설명되었습니다Apr 23, 2025 am 12:07 AM

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.