


Detaillierte Erläuterung der drei Berge von JS: Umfang und Abschluss, Prototyp und Prototypkette, Asynchronität und einzelner Thread
js dient als Rückgrat des Frontends. Wissen Sie also, was die drei großen Berge von Javascript sind?
1️⃣ Geltungsbereich und Abschluss
Scope
作用域
指代码当前上下文,控制着变量和函数的可见性和生命周期。最大的作用是隔离变量,不同作用域下同名变量不会冲突。
作用域链
指如果在当前作用域中没有查到值,就会向上级作用域查询,直到全局作用域,这样一个查找过程所形成的链条就被称之为作用域链。【推荐学习: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; };
对于闭包的概念好像懂了但又好像缺少了啥?意犹未尽。我也曾也闭包中迷失,但是看完闭包的生命周期让我重新找回自己。
学完就来一波牛刀小试
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 内建对象。这么一个寻找的过程就形成了 原型链
bezieht sich auf den aktuellen Kontext des Codes, der die Sichtbarkeit und den Lebenszyklus von Variablen und Funktionen steuert. Die größte Funktion besteht darin, Variablen zu isolieren, sodass Variablen mit demselben Namen in unterschiedlichen Bereichen nicht in Konflikt geraten.
Scope-Kette
Globaler Bereich
🎜, 🎜Modulbereich
🎜, 🎜Funktionsbereich
🎜 , 🎜 Gültigkeitsbereich auf Blockebene
🎜🎜🎜🎜Globaler Gültigkeitsbereich: 🎜 Auf den Code kann überall im Programm zugegriffen werden, beispielsweise auf das Fensterobjekt. Allerdings verschmutzen globale Variablen den globalen Namensraum und verursachen leicht Namenskonflikte. 🎜🎜🎜Modulumfang: 🎜 In der frühen js-Syntax gab es keine Moduldefinition, da die ursprünglichen Skripte klein und einfach waren. Später, als Skripte immer komplexer wurden, entstanden modulare Lösungen (AMD-, CommonJS-, UMD-, ES6-Module usw.). Normalerweise ist ein Modul eine Datei oder ein Skript, und dieses Modul hat seinen eigenen unabhängigen Bereich. 🎜🎜🎜Funktionsbereich: 🎜 Wie der Name schon sagt, der von der Funktion erstellte Bereich. In diesem Bereich werden Abschlüsse generiert, die wir später separat vorstellen werden. 🎜🎜🎜Geltungsbereich auf Blockebene: 🎜 Da die js-Variablenförderung Designfehler wie Variablenabdeckung und Variablenverschmutzung aufweist, hat ES6 das Schlüsselwort für den Bereich auf Blockebene eingeführt, um diese Probleme zu lösen. Typische Fälle sind die for-Schleife von let und die for-Schleife von var. 🎜const arr = [1, 2, 3]; arr.__proto__ === Array.prototype; // true arr.__proto__.__proto__ === Object.prototype; // true Array.__proto__ === Function.prototype; // true
Closure
:🎜 Funktion A enthält Funktion B und Funktion B verwendet die Variablen von Funktion A, dann wird Funktion B als Abschluss oder Abschluss-A-Paket bezeichnet ist eine Funktion, die die internen Variablen der Funktion A lesen kann. 🎜🎜Es ist ersichtlich, dass der Abschluss ein Produkt des Funktionsumfangs ist und gleichzeitig mit der Ausführung der äußeren Funktion erstellt wird. Es handelt sich um eine Kombination aus einer Funktion und ihrem gebündelten Verweis auf den umgebenden Umgebungszustand. Mit anderen Worten: 🎜 Abschluss bedeutet, dass die innere Funktion die äußere Funktionsvariable nicht freigibt. 🎜🎜🎜Eigenschaften von Abschlüssen: 🎜🎜- Es gibt Funktionen innerhalb von Funktionen
- Innere Funktionen können auf den Umfang äußerer Funktionen zugreifen
- Parameter und Variablen nicht Es wird GC sein und sich immer im Speicher befinden.
- Es gibt nur dort einen Abschluss, wo Speicher vorhanden ist.

🎜2️⃣ Prototyp und Prototypenkette🎜🎜🎜Wo immer Objekte sind, sind auch🎜Prototypen</ Code >🎜, jedes Objekt initialisiert eine darin enthaltene Eigenschaft, den Prototyp, und der Prototyp speichert gemeinsame Eigenschaften und Methoden. Wenn wir auf die Eigenschaften eines Objekts zugreifen, prüft die js-Engine zunächst, ob das aktuelle Objekt über diese Eigenschaft verfügt. Wenn nicht, prüft sie, ob ihr Prototypobjekt über diese Eigenschaft verfügt, und so weiter, bis das integrierte Objekt abgerufen wird. Ein solcher Suchprozess bildete das Konzept der 🎜<code>Prototype Chain
🎜. 🎜🎜Um den Prototyp zu verstehen, ist es am wichtigsten, die Beziehung zwischen __proto__, Prototyp und Konstruktor zu klären: 🎜- __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。
instance.__proto__ === instance.constructor.prototype
Object.prototype.__proto__ === null
Object.prototype.constructor === Object
看起来是不是有点乱??别慌!!一张图帮你整理它们之间的关系
相同的配方再来一刀
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 拥有异步的能力。
更多编程相关知识,请访问:编程教学!!
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der drei Berge von JS: Umfang und Abschluss, Prototyp und Prototypkette, Asynchronität und einzelner Thread. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

PHP und Vue: eine perfekte Kombination von Front-End-Entwicklungstools In der heutigen Zeit der rasanten Entwicklung des Internets ist die Front-End-Entwicklung immer wichtiger geworden. Da Benutzer immer höhere Anforderungen an das Erlebnis von Websites und Anwendungen stellen, müssen Frontend-Entwickler effizientere und flexiblere Tools verwenden, um reaktionsfähige und interaktive Schnittstellen zu erstellen. Als zwei wichtige Technologien im Bereich der Front-End-Entwicklung können PHP und Vue.js in Kombination als perfekte Waffe bezeichnet werden. In diesem Artikel geht es um die Kombination von PHP und Vue sowie um detaillierte Codebeispiele, die den Lesern helfen sollen, diese beiden besser zu verstehen und anzuwenden

In Front-End-Entwicklungsinterviews decken häufige Fragen ein breites Themenspektrum ab, darunter HTML/CSS-Grundlagen, JavaScript-Grundlagen, Frameworks und Bibliotheken, Projekterfahrung, Algorithmen und Datenstrukturen, Leistungsoptimierung, domänenübergreifende Anfragen, Front-End-Engineering, Designmuster sowie neue Technologien und Trends. Interviewerfragen sollen die technischen Fähigkeiten, die Projekterfahrung und das Verständnis des Kandidaten für Branchentrends beurteilen. Daher sollten Kandidaten in diesen Bereichen umfassend vorbereitet sein, um ihre Fähigkeiten und Fachkenntnisse unter Beweis zu stellen.

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

Django ist ein in Python geschriebenes Webanwendungs-Framework, das Wert auf schnelle Entwicklung und saubere Methoden legt. Obwohl Django ein Web-Framework ist, müssen Sie zur Beantwortung der Frage, ob Django ein Front-End oder ein Back-End ist, ein tiefes Verständnis der Konzepte von Front-End und Back-End haben. Das Front-End bezieht sich auf die Schnittstelle, mit der Benutzer direkt interagieren, und das Back-End bezieht sich auf serverseitige Programme. Sie interagieren mit Daten über das HTTP-Protokoll. Wenn das Front-End und das Back-End getrennt sind, können die Front-End- und Back-End-Programme unabhängig voneinander entwickelt werden, um Geschäftslogik bzw. interaktive Effekte sowie den Datenaustausch zu implementieren.

Als schnelle und effiziente Programmiersprache erfreut sich Go im Bereich der Backend-Entwicklung großer Beliebtheit. Allerdings assoziieren nur wenige Menschen die Go-Sprache mit der Front-End-Entwicklung. Tatsächlich kann die Verwendung der Go-Sprache für die Front-End-Entwicklung nicht nur die Effizienz verbessern, sondern Entwicklern auch neue Horizonte eröffnen. In diesem Artikel wird die Möglichkeit der Verwendung der Go-Sprache für die Front-End-Entwicklung untersucht und spezifische Codebeispiele bereitgestellt, um den Lesern ein besseres Verständnis dieses Bereichs zu erleichtern. In der traditionellen Frontend-Entwicklung werden häufig JavaScript, HTML und CSS zum Erstellen von Benutzeroberflächen verwendet

Django: Ein magisches Framework, das sowohl Front-End- als auch Back-End-Entwicklung bewältigen kann! Django ist ein effizientes und skalierbares Webanwendungs-Framework. Es unterstützt mehrere Webentwicklungsmodelle, einschließlich MVC und MTV, und kann problemlos hochwertige Webanwendungen entwickeln. Django unterstützt nicht nur die Back-End-Entwicklung, sondern kann auch schnell Front-End-Schnittstellen erstellen und durch die Vorlagensprache eine flexible Ansichtsanzeige erreichen. Django kombiniert Front-End-Entwicklung und Back-End-Entwicklung zu einer nahtlosen Integration, sodass sich Entwickler nicht auf das Lernen spezialisieren müssen
