<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.eijux.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Eijux</id>
	<title>Wikioe - 用户贡献 [zh-cn]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.eijux.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Eijux"/>
	<link rel="alternate" type="text/html" href="http://wiki.eijux.com/%E7%89%B9%E6%AE%8A:%E7%94%A8%E6%88%B7%E8%B4%A1%E7%8C%AE/Eijux"/>
	<updated>2026-05-15T10:24:30Z</updated>
	<subtitle>用户贡献</subtitle>
	<generator>MediaWiki 1.38.2</generator>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%EF%BC%9A%E5%AF%B9%E8%B1%A1%E4%B8%8E%E7%B1%BB&amp;diff=6671</id>
		<title>核心技术：对象与类</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%EF%BC%9A%E5%AF%B9%E8%B1%A1%E4%B8%8E%E7%B1%BB&amp;diff=6671"/>
		<updated>2024-10-12T04:42:35Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 【关于：Java类对象初始化顺序】 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaCore]]&lt;br /&gt;
&lt;br /&gt;
== oop ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
面向对象的程序时由对象组成的，每个对象包含对用户公开的特定功能部分和隐藏的实现部分。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# 面向对象：&lt;br /&gt;
# 面向过程：&lt;br /&gt;
# 面向切面：&lt;br /&gt;
&lt;br /&gt;
[[File:面向过程与面向对象.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== 类 与 对象 ===&lt;br /&gt;
# 类是构造对象的模板或蓝图，对象是类的实例化&lt;br /&gt;
# 由类构造（construct）对象的过程称为创建类的实例（instance）&lt;br /&gt;
# 封装（encapsulation，有时称为数据隐藏）：将数据（实例域，instance field）和行为（方法，用于操纵数据）组合在一个包中，并对对象的使用者隐藏了数据的实现方式&lt;br /&gt;
# 对象的实例域的几个就是这个对象的当前状态（state）&lt;br /&gt;
# 通过扩展一个类来建立另一个类的过程称为继承（inheritance）&lt;br /&gt;
&lt;br /&gt;
* “Object”是所有类的超类&lt;br /&gt;
* 对象状态的改变必须通过调用方法实现（封装的意义）&lt;br /&gt;
* 开发过程中，分析问题中的名词对应着类和类的实例域，动词对应着类的方法；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 对象的封装应该实现：&lt;br /&gt;
*: 一个私有的数据与；&lt;br /&gt;
*: 一个公有的域访问器方法；&lt;br /&gt;
*: 一个共有的域更改器方法；&lt;br /&gt;
&lt;br /&gt;
=== 类之间的关系 ===&lt;br /&gt;
# 依赖（“uses-a”）：一个类的方法操纵另一个类的对象&lt;br /&gt;
# 聚合（“has-a”）：一个类中包含另一个类的对象&lt;br /&gt;
# 继承（“is-a”）：一个类由另一个类扩展而来&lt;br /&gt;
&lt;br /&gt;
[[File:类关系的UML符号.png|800px]]&lt;br /&gt;
&lt;br /&gt;
==== 实例（UML）====&lt;br /&gt;
===== 关联（Association） =====&lt;br /&gt;
# 单向关联：&lt;br /&gt;
#: [[File:单向关联.png|400px]]&lt;br /&gt;
# 双向关联：&lt;br /&gt;
#: [[File:双向关联.png|400px]]&lt;br /&gt;
# 自身关联：&lt;br /&gt;
#: [[File:自身关联.png|400px]]&lt;br /&gt;
# 多维关联：&lt;br /&gt;
#: [[File:多维关联.png|400px]]&lt;br /&gt;
===== 聚合（Aggregation） =====&lt;br /&gt;
:[[File:聚合（Aggregation）.png|400px]]&lt;br /&gt;
===== 组合（复合，Composition） =====&lt;br /&gt;
:[[File:组合（复合，Composition）.png|400px]]&lt;br /&gt;
* 聚合的成员可独立，复合的成员必须依赖于整体才有意义&lt;br /&gt;
===== 泛化（Generalization） =====&lt;br /&gt;
泛化指的是类与类之间的继承关系和类与接口之间的实现关系。&lt;br /&gt;
# 继承：&lt;br /&gt;
#: [[File:泛化（Generalization）：继承.png|400px]]&lt;br /&gt;
# 实现：&lt;br /&gt;
#: [[File:泛化（Generalization）：实现.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 使用预定义类 ==&lt;br /&gt;
&lt;br /&gt;
* 并非所有的类都具有面向对象特征；（如，Math、Date类，只封装了功能，没有也不需要隐藏数据）&lt;br /&gt;
&lt;br /&gt;
=== 对象与对象变量 ===&lt;br /&gt;
&lt;br /&gt;
# 构造器（constructor）是一种特殊的方法，用来构造并初始化对象；&lt;br /&gt;
# 构造器的名字应该与类名相同；&lt;br /&gt;
# 一个对象变量并不包含一个对象，而是引用一个对象；&lt;br /&gt;
# 局部变量不会自动地初始化为null，必须通过new或将其设置为null来进行初始化；&lt;br /&gt;
&lt;br /&gt;
* Java中要获得对象的完整拷贝，应该使用“clone”方法；&lt;br /&gt;
&lt;br /&gt;
=== Date 与 LocalDate 类 ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Date类的时间，使用一个固定时间点（纪元，epoch）的毫秒数（可正可负）来表示的；&lt;br /&gt;
&lt;br /&gt;
纪元：UTC时间 1970年1月1日 00:00:00&lt;br /&gt;
UTC（Coordinated Universal Time），与GMT（Greenwich Mean Time，格林威治时间）一样。&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Date 类提供的日期处理并没有太大的用途。如“December 31, 1999, 23:59:59”这样的时间只是阳历的固有习惯，虽然遵循了世界上大多数地区使用的阳历表示法。但是，统一时间点采用中国的农历或希伯来的阴历表示就很不一样。&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
类库设计者决定将保存时间与给时间点命名分开，所以标准Java类库分别包含了两个类：&lt;br /&gt;
# 一个是用来表示时间点的'''Date'''类&lt;br /&gt;
# 另一个是用来表示大家熟悉的日历表示法的'''LocalDate'''类&lt;br /&gt;
*（Java SE 8 引入了另一些类来处理日期和时间的不同方面）&lt;br /&gt;
将时间与日历分开就是一种很好的面向对象设计。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
关于LocalDate的使用：&lt;br /&gt;
* 不要使用构造器来构造LocalDate的对象，而应该使用静态工厂方法；&lt;br /&gt;
# 用当前时间构造一个新对象：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
LocalDate.now()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 提供年月日来构造一个特定时间的对象：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
LocalDate.of(1999, 12, 31)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将构造的对象保存在一个对象变量中：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
LocalDate newYearEve = LocalDate.of(1999, 12, 31);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 有了LocalDate对象，就可以使用getYear、getMonthValue、getDayOfMonth来得到年、月、日，以及其他操纵日历的方法：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
int year = newYearEve.getYear();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''不应该使用Date类中诸如getYear、getMonth、getDay等方法'''。&lt;br /&gt;
* 调用后会修改对象状态的方法是“更改器方法”，只访问对象而不修改对象的方法是“访问器方法”&lt;br /&gt;
&lt;br /&gt;
== 用户自定义类 ==&lt;br /&gt;
&lt;br /&gt;
* 构造器总是伴随 new 操作符的执行被调用；而不能对一个已经存在的对象调用构造器来重设实例域。&lt;br /&gt;
* 不应该在构造器中定义域实例域重名的局部变量&lt;br /&gt;
&lt;br /&gt;
构造器：&lt;br /&gt;
# 与类同名&lt;br /&gt;
# 每个类可以有一个以上的构造器&lt;br /&gt;
# 构造器可以有0、1或多个参数&lt;br /&gt;
# 构造器没有返回值&lt;br /&gt;
# 构造器总是伴随着 new 操作一起调用&lt;br /&gt;
&lt;br /&gt;
== 静态域与静态方法 ==&lt;br /&gt;
&lt;br /&gt;
=== 静态变量 ===&lt;br /&gt;
静态域、类域，即静态变量；&lt;br /&gt;
如：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static int nextId = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 类的所有实例将会共享一个静态域&lt;br /&gt;
&lt;br /&gt;
=== 静态常量 ===&lt;br /&gt;
# 静态：static&lt;br /&gt;
# 常量：final&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final double PI = 3.1415926;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 对于 public：&lt;br /&gt;
*# 不应该把域设置为 public，因为每个类对象都可以对共有域进行修改；&lt;br /&gt;
*# 但将公用常量设置为 public 没问题，因为被 final修饰，不会被更改；&lt;br /&gt;
&lt;br /&gt;
* 关于final：&lt;br /&gt;
*: “System”类中有“setOut”方法，可以将“System.out”，设置为不同的流（“public final static PrintStream out = null;”）&lt;br /&gt;
*: 此处可以修改 final 变量 out的值，是因为“setOut”调用了一个“Native”方法（“private static native void setOut0(){}”），可以绕过Java的存取控制机制。&lt;br /&gt;
&lt;br /&gt;
=== 静态方法 ===&lt;br /&gt;
# 静态方法可以使用类名、类的实例调用；&lt;br /&gt;
# 静态方法只能访问静态域，而不能访问实例域，即不能操作对象；&lt;br /&gt;
&lt;br /&gt;
* 关于静态方法main：每个类可以有一个main方法，用作单元测试&lt;br /&gt;
&lt;br /&gt;
=== 工厂方法 ===&lt;br /&gt;
静态方法的另一种常见用途：类似 LocalDate 和 NumberFormat 的类使用静态工厂方法来构造对象。&lt;br /&gt;
&lt;br /&gt;
== 方法参数 ==&lt;br /&gt;
&lt;br /&gt;
# 按值调用（“call by value”）：表示方法接受的是调用者提供的值。&lt;br /&gt;
# 按引用调用（“call by reference”）：表示方法接收的是调用者提供的变量地址。&lt;br /&gt;
# 一个方法可以修改传递引用锁对应的变量值，而不能修改值传递调用所对眼的变量值&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Java 总是采用 &amp;lt;div&amp;gt;&amp;lt;span style=&amp;quot;color:Chocolate; font-weight:bold; font-size:150%;&amp;quot;&amp;gt;按值调用&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;'''！！！&lt;br /&gt;
&lt;br /&gt;
即，方法得到的是所有参数值的一个拷贝，并不能修改传递值给它的变量的内容。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Java中方法参数的使用情况：&lt;br /&gt;
# 一个方法'''不能修改一个基本数据类型的参数'''；&lt;br /&gt;
# 一个方法'''可以更改一个对象参数的状态'''；&lt;br /&gt;
# 一个方法'''不能让对象参数引用一个新的对象'''；&lt;br /&gt;
&lt;br /&gt;
== 对象构造 ==&lt;br /&gt;
&lt;br /&gt;
=== 重载 ===&lt;br /&gt;
* 重载（overloading）：多个方法有相同的名字、不同的参数。如参数个数或类型不同的构造函数；&lt;br /&gt;
* 方法的签名（signature）：方法名以及参数类型（返回值不是方法签名的一部分）；&lt;br /&gt;
&lt;br /&gt;
=== 默认域初始化 ===&lt;br /&gt;
如果在构造器中没有显示地给域赋予初值，那么就会被自动地赋为默认值（数值为0，布尔值为false，对象引用为null）。&lt;br /&gt;
&lt;br /&gt;
=== 显示域初始化 ===&lt;br /&gt;
在执行构造器之前，先执行赋值操作（当一个类的所有构造器都希望把相同的值赋予某个特定的实例域时，十分有用）。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
class Employee&lt;br /&gt;
{&lt;br /&gt;
   private static int nextId;&lt;br /&gt;
   private int id = assingId();&lt;br /&gt;
   ...&lt;br /&gt;
   private static int assingId()&lt;br /&gt;
   {&lt;br /&gt;
      int r = nextId;&lt;br /&gt;
      nextId++;&lt;br /&gt;
      return r;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 无参构造器 ===&lt;br /&gt;
* 当类没有提供任何构造器时，系统会提供一个默认的无参构造器。&lt;br /&gt;
*: 这个构造器将所有的实例域设置为默认值；&lt;br /&gt;
* 当类中提供了至少一个构造器，但未提供无参构造器时，如果构造对象没有提供参数会被视为不合法。&lt;br /&gt;
&lt;br /&gt;
=== 调用另一个构造器 ===&lt;br /&gt;
如果构造器的第一个语句形如“this(...)”，则构造器将会调用同一个类的另一个构造器：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
   public Employee(double s)&lt;br /&gt;
   {&lt;br /&gt;
      this(&amp;quot;Employee #&amp;quot; + nextId, s);&lt;br /&gt;
      nextId++;&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 这样公共的构造器代码部分只编写一次即可。&lt;br /&gt;
&lt;br /&gt;
=== 初始化块 ===&lt;br /&gt;
初始化数域的方法：&lt;br /&gt;
# 在构造器中设置值&lt;br /&gt;
# 在声明中赋值&lt;br /&gt;
# 初始化块&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
class Employee&lt;br /&gt;
{&lt;br /&gt;
   private static int nextid;&lt;br /&gt;
   &lt;br /&gt;
   private int id;&lt;br /&gt;
   private String name;&lt;br /&gt;
   private double salary;&lt;br /&gt;
   &lt;br /&gt;
   //初始化块&lt;br /&gt;
   {&lt;br /&gt;
       id = nextId;&lt;br /&gt;
       nextId++;&lt;br /&gt;
   }&lt;br /&gt;
   public Employee(String n, double s)&lt;br /&gt;
   {&lt;br /&gt;
       name = n;&lt;br /&gt;
       salary = s;&lt;br /&gt;
   }&lt;br /&gt;
   public Employee()&lt;br /&gt;
   {&lt;br /&gt;
       name = &amp;quot;&amp;quot;;&lt;br /&gt;
       s = 0;&lt;br /&gt;
   }&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 首先运行初始化块，然后再运行构造器的主体部分&lt;br /&gt;
&lt;br /&gt;
即，无论使用哪个构造器构造对象，id域都在对象初始化块中被初始化。&lt;br /&gt;
&lt;br /&gt;
==== 【关于：Java类对象初始化顺序】 ====&lt;br /&gt;
 参考：'''[[深入理解JVM：虚拟机类加载机制#初始化]]'''&lt;br /&gt;
&lt;br /&gt;
# 父：静态变量&lt;br /&gt;
#:   静态初始化块&lt;br /&gt;
# 子：静态变量&lt;br /&gt;
#:   静态初始化块&lt;br /&gt;
# main&lt;br /&gt;
# 父：变量&lt;br /&gt;
#:   初始化块&lt;br /&gt;
#:   构造器&lt;br /&gt;
# 子：变量&lt;br /&gt;
#:   初始化块&lt;br /&gt;
#:   构造器&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 先初始化静态内容&lt;br /&gt;
* 先初始化父类的内容&lt;br /&gt;
* 变量先于初始块，初始快先于构造器&lt;br /&gt;
&lt;br /&gt;
=== 对象析构 与 finalize方法 ===&lt;br /&gt;
&lt;br /&gt;
# 面向过程的程序设计语言，有显示的析构刚嘎，如C++&lt;br /&gt;
# 而Java中有GC，不需要手动回收内存，所以Java不支持析构器&lt;br /&gt;
&lt;br /&gt;
但，当某些对象使用了内存以外的资源（如文件等），这种情况下当资源不再需要时，将其回收和再利用将十分重要。&amp;lt;br/&amp;gt;&lt;br /&gt;
可以为任何一个类添加'''finalize'''方法，用于回收资源：&lt;br /&gt;
* finalize 将在垃圾回收器清楚对象之前调用；&lt;br /&gt;
* 但是不能知道调用的时间，所以不应该依赖于它进行资源回收；&lt;br /&gt;
&lt;br /&gt;
== 包 ==&lt;br /&gt;
Java中使用包（package）来将类组织起来，用于确定类名的唯一性（不同包下的同名类不冲突）。&lt;br /&gt;
* 所有标准的Java包，都处于java（核心）和javax（扩展）包层次中；&lt;br /&gt;
* 嵌套的包之间没有任何关系，如“java.util”与“java.util.jar”&lt;br /&gt;
&lt;br /&gt;
=== 类的导入 ===&lt;br /&gt;
一个类可以使用所属包中的所有类，以及其他包中的公有类（pubic class）。&lt;br /&gt;
&lt;br /&gt;
使用其他包的公有类：&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
java.time.LocalDate today = java.time.LocalDate.now();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
//源文件头部&lt;br /&gt;
import java.util.*;&lt;br /&gt;
&lt;br /&gt;
//代码中&lt;br /&gt;
LocalDate today = LocalDate.now();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 只能使用“*”导入一个包，而不能使用“import java.*”或“import java.*.*”来导入所有java前缀的包；&lt;br /&gt;
&lt;br /&gt;
=== 静态导入 ===&lt;br /&gt;
import 导入静态方法和静态域：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// 源文件头部&lt;br /&gt;
import static java.lang.System.*;     // 或导入特定的方法或域“import static java.lang.System.out”、“import static java.lang.System.exit”&lt;br /&gt;
&lt;br /&gt;
//代码中，可以使用System类的静态方法和静态域，而不必加类名前缀&lt;br /&gt;
out.println(&amp;quot;Goodbyr, world!&amp;quot;);      // System.out&lt;br /&gt;
exit(0);                     // System.exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 将类放入包中 ===&lt;br /&gt;
要将类放入包中，则必须将包的名字放在源文件的开头：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.eijux.wiki;&lt;br /&gt;
&lt;br /&gt;
public class Wikioe&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 包作用域 ===&lt;br /&gt;
包密封（package sealing）：如果将一个包密封起来，就不能再向这个包添加类了。&lt;br /&gt;
&lt;br /&gt;
== 类路径 ==&lt;br /&gt;
&lt;br /&gt;
== 文档注释 ==&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=IDEA%E5%BF%AB%E6%8D%B7%E9%94%AE%EF%BC%9AWindows%EF%BC%88%E4%B8%AA%E4%BA%BA%E6%95%B4%E7%90%86%EF%BC%89&amp;diff=6670</id>
		<title>IDEA快捷键：Windows（个人整理）</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=IDEA%E5%BF%AB%E6%8D%B7%E9%94%AE%EF%BC%9AWindows%EF%BC%88%E4%B8%AA%E4%BA%BA%E6%95%B4%E7%90%86%EF%BC%89&amp;diff=6670"/>
		<updated>2024-04-08T12:36:47Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 编辑 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:IDEA]]&lt;br /&gt;
&lt;br /&gt;
== 常用快捷键 ==&lt;br /&gt;
=== IDEA ===&lt;br /&gt;
# 系统设置：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;&lt;br /&gt;
# 项目设置：&amp;lt;code&amp;gt;Ctrl + Shift + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;&lt;br /&gt;
# 专注编辑器（隐藏所有工件窗口）：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 恢复默认布局：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 导航 ===&lt;br /&gt;
# '''切换器'''：'''&amp;lt;code&amp;gt;Ctrl + Tab&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 打开工具窗口：&lt;br /&gt;
## 项目：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
## 文件结构：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;7&amp;lt;/code&amp;gt;&lt;br /&gt;
##*（弹出窗口）&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''文件打开位置'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F1&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 用于选择在哪里打开或定位当前文件；&lt;br /&gt;
&lt;br /&gt;
=== 窗口 ===&lt;br /&gt;
# 新窗口打开（当前文件）：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F4&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''最近的文件列表'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;E&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 最近的位置列表（查看 / 修改）：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;E&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''最近的拷贝列表'''：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 版本控制常用操作：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + '''&amp;lt;code&amp;gt;`&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
=== Search Everywhere 窗口 ===&lt;br /&gt;
（以下打开的是同一窗口）&lt;br /&gt;
# 所有：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; x2&lt;br /&gt;
# 类：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;&lt;br /&gt;
# 文件：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;&lt;br /&gt;
# 符号：&amp;lt;code&amp;gt;Ctrl + Alt + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;&lt;br /&gt;
# 操作：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;&lt;br /&gt;
* 在窗口中，可通过 &amp;lt;code&amp;gt;Ctrl + Tab&amp;lt;/code&amp;gt; 切换上述 Tab 页&lt;br /&gt;
&lt;br /&gt;
=== 编辑 ===&lt;br /&gt;
# 当前查找：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;（等效于：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F3&amp;lt;/code&amp;gt;）&lt;br /&gt;
#* 下一个：&amp;lt;code&amp;gt;F3&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 上一个：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F3&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''全局查找'''：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt;''' + '''&amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;'''：自定义位置的全局查找&lt;br /&gt;
# 替换：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;&lt;br /&gt;
# 撤销：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 取消撤销：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt;&lt;br /&gt;
# 复制行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 复制并插入：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt;&lt;br /&gt;
# 删除行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt;&lt;br /&gt;
# 剪切行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;&lt;br /&gt;
# 注释行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 注释块：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
# 移动行：&amp;lt;code&amp;gt;Alt + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;↑&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;↓&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 移动方法：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;↑&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;↓&amp;lt;/code&amp;gt;&lt;br /&gt;
# 上/下一个方法：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;↑&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;↓&amp;lt;/code&amp;gt;&lt;br /&gt;
# 大/小写轮换：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;&lt;br /&gt;
# 递进式选择：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;W&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 递进式取消选择：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;W&amp;lt;/code&amp;gt;&lt;br /&gt;
# 切换编辑页：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;←&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;→&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 后退/前进导航：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;←&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;→&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 代码 ===&lt;br /&gt;
 '''代码模板'''、'''后缀补全'''，见：[[FAQ:IDEA#IDEA_设置：代码模板]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''错误：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''下一个错误/警告'''：'''&amp;lt;code&amp;gt;F2&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 上一个错误/警告：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F2&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''错误描述'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F1&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''信息查看：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''快速文档'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 显示包含光标处符号（变量 / 类名 / 方法名）的文档（也可以在提示补充的时候按）&lt;br /&gt;
# '''快速定义'''：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 显示包含光标处符号（变量 / 类名 / 方法名）的文档&lt;br /&gt;
# 类型信息：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''形参信息'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 显示（光标处）方法的形式参数提示&lt;br /&gt;
# 上下文信息：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''层次结构：'''&lt;br /&gt;
## '''类型层次结构'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##* 区别于“当前类的结构”（文件结构）：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;7&amp;lt;/code&amp;gt;（或：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;）&lt;br /&gt;
## 方法层次结构：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;&lt;br /&gt;
## 调用层次结构：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;&lt;br /&gt;
##* 与“查找调用”（&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;）结果一致，只是：前者只列出了层层调用关系，而后者对调用进行了分类，且信息更详细；&lt;br /&gt;
# '''文件结构'''（'''类信息'''）：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 工具窗口“文件结构”：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;7&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''图表'''：&lt;br /&gt;
## 固定窗口：'''&amp;lt;code&amp;gt;Ctrl + Shift + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;'''&lt;br /&gt;
## 弹出窗口：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''查找跳转：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''转到声明 / 查找调用'''：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;（或：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + 点击'''；或：“点击中键”）&lt;br /&gt;
#: 作用：&lt;br /&gt;
## 在调用处：跳转到“类 / 方法 / 属性”的声明；&lt;br /&gt;
## 在声明处：显示“类 / 方法 / 属性”所有的调用处；（等效于：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;）&lt;br /&gt;
# '''转到 super 方法'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 转到被“重载/实现”方法的“父类 / 接口”的方法定义处；&lt;br /&gt;
# '''查找实现'''：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;（或：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + 点击'''）&lt;br /&gt;
#: 查找当前“类 / 方法”所有的实现；&lt;br /&gt;
# '''查找调用'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 查找“方法 / 变量 / 类”所有的被调用处；&lt;br /&gt;
#* 弹窗显示：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 转到类型声明：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;（或：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + 点击）&lt;br /&gt;
#: 跳转到当前“方法 / 属性”的类型声明处；&lt;br /&gt;
# 转到测试：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''生成代码：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''生成'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Insert&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 包括：构造函数、toString、重新方法、测试、版权；&lt;br /&gt;
#* 在编辑 '''pom.xml''' 等内容时，也可使用；&lt;br /&gt;
# '''重写方法'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;O&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''继承方法'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''环绕方式'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 用以下代码环绕选中的代码：if/else”、“while”、“for”、“try/catch”、“synchronized”、“Runnable”等&lt;br /&gt;
#* 解除环绕：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Delete&amp;lt;/code&amp;gt;&lt;br /&gt;
# 生成单元测试类：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''优化导入的类'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;O&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''代码重构：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''重命名'''：'''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F6&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取变量'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取字段'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取常数'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取方法'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取参数'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''内联'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 复制：&amp;lt;code&amp;gt;F5&amp;lt;/code&amp;gt;&lt;br /&gt;
# 移动：&amp;lt;code&amp;gt;F6&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''重构此…'''：'''&amp;lt;code&amp;gt;Ctrl + Shift + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 包含'''重构操作列表'''的上下文感知弹出窗口&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''辅助优化：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''格式化代码'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;L&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''显示快速修复'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 在代码需要 '''import''' 某些包、类时，可以使用该快捷键。&lt;br /&gt;
# 代码补全：&lt;br /&gt;
## '''基本补全'''（Basic completion）：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Space&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【基本代码补全功能可帮助您补全可见范围内的类，方法，字段和关键字。 当您调用代码补全功能时，IntelliJ IDEA 会分析上下文并提供可用的“建议列表”（建议中还将包括“Live templates”）】&lt;br /&gt;
&lt;br /&gt;
如果将基本代码补全应用于字段，参数或变量声明的一部分，则 IntelliJ IDEA 会根据项目类型提供可用的“建议列表”。&lt;br /&gt;
&lt;br /&gt;
第二次调用（按两次 Ctrl+Space）：将显示不可访问的类和成员（这些类和成员需要可以通过 Intention actions 公开）。【！！！】&lt;br /&gt;
&lt;br /&gt;
第三次调用（按三次 Ctrl+Space）：IntelliJ IDEA 将在整个项目中查找类和接口，而不考虑依赖关系。如果必要的类尚未导入，则将自动导入该类。【！！！】&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
##* &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''第二三次调用，在整个项目中搜索类和接口，而不考虑依赖关系。'''&amp;lt;/span&amp;gt; 【非常有用！！！】&lt;br /&gt;
##* 默认与 Windows 输入法快捷键冲突，建议修改为“&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + '''&amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;'''”&lt;br /&gt;
##* 第二基本补全: '''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Space&amp;lt;/code&amp;gt;'''&lt;br /&gt;
## '''智能补全'''（Smart completion）：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Space&amp;lt;/code&amp;gt;'''（基于预期类型补全代码）&lt;br /&gt;
##:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【智能代码补全功能会过滤“建议列表”，并仅显示适用于当前上下文的类型】&lt;br /&gt;
&lt;br /&gt;
在可以确定类型的情况下，智能补全非常有用：&lt;br /&gt;
 ● 在赋值语句的右侧；&lt;br /&gt;
 ● 在变量初始化时；&lt;br /&gt;
 ● 在 return 语句中；&lt;br /&gt;
 ● 在方法调用的参数列表中；&lt;br /&gt;
 ● 在对象声明中的 new 关键字之后；&lt;br /&gt;
 ● 在链式表达式中；&lt;br /&gt;
 &lt;br /&gt;
如有必要，再次按 Ctrl+Shift+Space 这样就可以完成：&lt;br /&gt;
 ● 集合，列表和数组。 —— IntelliJ IDEA 搜索具有相同组件类型的符号，并建议对其转换。&lt;br /&gt;
 ● 静态方法调用或常量引用。 —— IntelliJ IDEA 扫描静态方法和字段，并建议适合当前上下文的方法和字段。&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
## '''语句补全'''（Statement completion）：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【您可以使用语句补全来创建语法正确的代码构造。 —— 它插入必要的语法元素（括号，花括号和分号），并使光标处于可以开始键入下一条语句的位置】&lt;br /&gt;
&lt;br /&gt;
常用方式：&lt;br /&gt;
 ● 补全方法声明；&lt;br /&gt;
 ● 补全代码结构；&lt;br /&gt;
 ● 包裹方法的调用参数；&lt;br /&gt;
 ● 快速补全行末分号。&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
## '''Hippie 补全'''（Hippie completion）：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【Hippie completion 是一个补全引擎，可以分析可见范围内的文本并根据当前上下文生成建议。它可以帮助您补全当前打开的任何文件中的任何单词。】&lt;br /&gt;
&lt;br /&gt;
—— 说人话：会选择当前编辑器中适合的单词直接拿过来补全当前输入内容。&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 按辅键分类 ==&lt;br /&gt;
=== 字母、数字 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''字母、数字'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''1～9'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 定位到对应数值的书签位置&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 显示对应数值的选项卡&lt;br /&gt;
* 其中 '''1''' 是 Project，用得最多&lt;br /&gt;
* 其中 '''7''' 是 文件结构，常用&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 快速添加指定数值的书签&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''A'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''查找“动作 / 设置”'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''B'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 进入光标所在的“方法/变量”的“接口/定义”处&lt;br /&gt;
* 等效于“&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + 左键单击”&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 在某个调用的方法名上使用会跳到具体的实现处，可以跳过接口&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 跳转到类型声明处&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''C'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 复制光标所在行（或：选择的内容）&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 复制当前文件磁盘路径到剪贴板&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 查看最近操作项目的变化情况列表&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 复制参考信息&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''D'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 复制并插入复制光标所在行（或：选择的内容），并把复制的内容插入光标位置后&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''E'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''显示最近打开的文件记录列表'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 显示最近修改的文件列表的弹出层&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 在当前文件进行文本查找&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' + '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''根据输入内容查找整个项目（或：指定目录内文件）'''——【'''（自定义）全局查找'''】&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 显示添加到收藏夹弹出层 / 添加到收藏夹&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''G'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 在当前文件跳转到指定行处&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''H'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 显示'''当前类的层次结构'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 调用层次&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 显示方法层次结构&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''I'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''选择可继承的方法'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 光标所在行（或：选中部分）进行自动代码缩进，有点类似格式化&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 快速查看光标所在的“方法 / 类”的定义&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 查看项目当前文件&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''J'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + J || 插入自定义动态代码模板&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''弹出模板选择窗口'''，讲选定的代码加入动态模板中&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 自动将下一行合并到当前行末尾 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''K'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; ||版本控制：提交项目，需要此项目有加入到版本控制才可用&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''L'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''格式化代码'''&lt;br /&gt;
* 可以对当前文件和整个包目录使用&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''N'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 根据输入的“类名”'''查找类文件'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 通过文件名“定位 / 打开”“文件 / 目录”，打开目录需要在输入的内容后面多加一个正斜杠&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || “选择 / 添加”task&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 前往指定的“变量 / 方法”&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''O'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''选择可重写的方法'''&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''优化导入的类'''&lt;br /&gt;
* 可以对当前文件和整个包目录使用&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''P'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''方法参数提示显示'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''Q'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 光标所在的“变量 / 类名 / 方法名”等上面（也可以在提示补充的时候按），显示文档内容&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 弹出一个提示，显示当前类的“声明 / 上下文”信息&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''R'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 在当前文件进行文本替换&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 根据输入内容替换对应内容，范围为整个项目（或：指定目录内文件）&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''S'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''打开 IntelliJ IDEA 系统设置'''&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''打开当前项目设置'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''T'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 版本控制：更新项目，需要此项目有加入到版本控制才可用&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''对选中的代码弹出环绕选项弹出层'''&lt;br /&gt;
* “if/else”、“while”、“for”、“try/catch”、“synchronized”、“Runnable”等&lt;br /&gt;
* 可使用 '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Delete&amp;lt;/code&amp;gt;''' 接触代码环绕。&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''对当前类生成单元测试类'''，如果已经存在的单元测试类则可以进行选择&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''U'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 前往当前光标所在'''方法的“父类方法 / 接口”定义'''处&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || 对选中的代码进行'''“大 / 小写”轮流转换'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''V'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 快速引进变量&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || '''弹出“缓存的最近拷贝的内容”管理器弹出层'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 无格式黏贴&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''W'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 递进式选择代码块&lt;br /&gt;
* 可选中光标所在的单词或段落，连续按会在原有选中的基础上再扩展选中范围&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 递进式取消选择代码块&lt;br /&gt;
* 可选中光标所在的单词或段落，连续按会在原有选中的基础上再扩展选中范围&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''X'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 剪切光标所在行（或：选择的内容）&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''Y'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 删除光标所在行（或：选中的行）&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 同步、刷新&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''Z'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 撤销&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 取消撤销&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== F1～F12 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''F1～F12'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F1'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 在光标所在的错误代码出显示'''错误信息'''&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''显示当前文件的“选择目标弹出层”'''（在哪里打开当前文件），弹出层中有很多目标可以进行选择&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || （如果有外部文档）可以连接外部文档&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F2'''&lt;br /&gt;
|  || '''跳转到下一个高亮错误'''（或：警告位置）&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 对于前面页面，显示各类浏览器打开目标选择弹出层&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''跳转到上一个高亮错误'''（或：警告位置）&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F3'''&lt;br /&gt;
|  || 在查找模式下，定位到下一个匹配处&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 调转到所选中的词的下一个引用位置&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''选中文本，逐个往下查找相同文本，并高亮显示'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 在查找模式下，查找匹配上一个&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F4'''&lt;br /&gt;
|  || 编辑源&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 关闭当前编辑文件&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''对当前打开的文件，使用新 Windows 窗口打开，旧窗口保留'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F6'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || 对“文件 / 文件夹”重命名&lt;br /&gt;
* 在编辑框对“字段”重命名&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F7'''&lt;br /&gt;
|  ||【Debug 模式下，步入】：如果当前行断点是一个方法，则进入当前方法体内，如果该方法体还有方法，则不会进入该内嵌的方法中&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 查找光标所在的'''“方法 / 变量 / 类”被调用的地方'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，智能步入】：断点所在行上有多个方法调用，会弹出进入哪个方法&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 显示使用的地方。寻找被该类或是变量被调用的地方，用弹出框的方式找出来&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 高亮显示所有该选中文本，按 Esc 高亮消失&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，强制步入】：进入当前方法体内，如果方法体还有方法，则会进入该内嵌的方法中，依此循环进入&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F8'''&lt;br /&gt;
|  ||【Debug 模式下，步过】：如果当前行断点是一个方法，则不进入当前方法体内&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; ||【Debug 模式下，“设置/取消”断点】&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; ||【Debug 模式下，评估表达式】：选中对象，弹出可输入计算表达式调试框，查看该输入内容的调试结果&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，步出】：表现出来的效果跟 &amp;lt;code&amp;gt;F9&amp;lt;/code&amp;gt; 一样&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，指定断点进入条件】&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F9'''&lt;br /&gt;
|  ||【Debug 模式下，恢复程序运行】：但是如果该断点下面代码还有断点则停在下一个断点上&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 执行 Make Project（构建项目） 操作&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; ||【Debug 模式下，运行到光标处】&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 等效于点击工具栏的 Debug 按钮&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 编译选中的“文件 / 包 / Module”&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''弹出 Debug 的可选择菜单'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F10'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 等效于点击工具栏的 Run 按钮&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''弹出 Run 的可选择菜单'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F11'''&lt;br /&gt;
|  || 添加书签&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 选中“文件 / 文件夹”，使用助记符“设定 / 取消”书签&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || '''弹出书签显示层'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 切换全屏模式&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F12'''&lt;br /&gt;
|  || 回到前一个工具窗口&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''弹出当前文件结构层'''，可以在弹出的层上直接输入，进行筛选&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 编辑器最大化&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 符号 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''符号'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''`'''&amp;lt;span&amp;gt;&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''显示版本控制常用操作菜单弹出层'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''+'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 展开代码&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 展开所有代码&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''-'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 折叠代码&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 折叠所有代码&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''/'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || '''注释'''光标所在行代码&lt;br /&gt;
* 会根据当前不同文件类型使用不同的注释符号&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 代码块注释&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''['''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 移动光标到当前所在代码的花括号开始位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中从光标所在位置到它的顶部中括号位置&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | ''']'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 移动光标到当前所在代码的花括号结束位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中从光标所在位置到它的底部中括号位置&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 操作 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''操作'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''←'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 光标跳转到当前“单词 / 中文句”的左侧开头位置&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''向左切换'''（当前已打开的）'''文件视图'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 退回到上一个操作的地方&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 在代码文件上，光标跳转到当前“单词 / 中文句”的左侧开头位置，同时选中该“单词 / 中文句”&lt;br /&gt;
* 在光标焦点是在工具选项卡上，缩小选项卡区域&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''→'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 光标跳转到当前“单词 / 中文句”的右侧开头位置&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''向右切换'''（当前已打开的）'''文件视图'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 前进到上一个操作的地方&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 在代码文件上，光标跳转到当前“单词 / 中文句”的右侧开头位置，同时选中该“单词 / 中文句”&lt;br /&gt;
* 在光标焦点是在工具选项卡上，扩大选项卡区域&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''↑'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 等效于鼠标滚轮向前效果&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 当前光标跳转到当前文件的'''前一个方法名'''位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 在查找模式下，跳到上个查找的文件&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向上调整方法排序'''：光标放在“方法名所在行”上，将方法移动到上一个方法前面&lt;br /&gt;
* 光标放在“普通行”上，等同于“&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + ↑”&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向上移动光标所在行'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''↓'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 等效于鼠标滚轮向后效果&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 当前光标跳转到当前文件的'''后一个方法名'''位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 在查找模式下，跳到下个查找的文件&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向下调整方法排序'''：光标放在“方法名所在行”上，将方法移动到下一个方法后面&lt;br /&gt;
* 光标放在“普通行”上，等同于“&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + ↓”&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向下移动光标所在行'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''ESC'''&lt;br /&gt;
|  || 从工具窗口进入代码文件窗口&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 隐藏当前（或：最后一个激活的）工具窗口&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Tab'''&lt;br /&gt;
|  || 缩进&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''编辑窗口切换'''，如果在切换的过程又加按上 delete，则是关闭对应选中的窗口&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 取消缩进&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Space'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''基础代码补全'''&lt;br /&gt;
* 默认在 Windows 系统上被输入法占用，需要进行修改，建议修改为“&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + 逗号”&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''类名自动完成'''&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''智能代码提示'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Enter'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 智能分隔行&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 根据光标所在问题，提供'''快速修复'''选择，光标放在的位置不同提示的结果也不同&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 开始新一行。光标所在行下空出一行，光标定位到新行位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 光标所在行上空出一行，光标定位到新行&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 自动结束代码，行末自动添加分号&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Home'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 跳到文件头&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || “定位 / 显示”到当前文件的 Navigation Bar&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中光标到当前行头位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 弹出跟当前文件有关联的文件弹出层&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''End'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 跳到文件尾&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中光标到当前行尾位置&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Insert'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''代码自动生成'''，如生成对象的“ set / get 方法，构造函数，toString()”等&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Delete'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 删除光标后面的单词或是中文句&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''BackSpace'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 删除光标前面的单词或是中文句&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 退回到上次修改的地方&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【光标定位】&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 按 &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; 不要松开，会显示光标所在的'''类信息摘要'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【左键单击】&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 在打开的文件标题上，弹出该'''文件路径'''&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || 在打开的文件名上按此快捷键，可以'''关闭当前打开文件'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【左键双击】&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选择被双击的“单词 / 中文句”，按住不放，可以同时选择其他“单词 / 中文句”&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【滚轮前后滚动】&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 当前文件的横向滚动轴滚动&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【连按两次 '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;'''】&lt;br /&gt;
|  || '''弹出 Search Everywhere 窗口'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=IDEA%E5%BF%AB%E6%8D%B7%E9%94%AE%EF%BC%9AWindows%EF%BC%88%E4%B8%AA%E4%BA%BA%E6%95%B4%E7%90%86%EF%BC%89&amp;diff=6669</id>
		<title>IDEA快捷键：Windows（个人整理）</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=IDEA%E5%BF%AB%E6%8D%B7%E9%94%AE%EF%BC%9AWindows%EF%BC%88%E4%B8%AA%E4%BA%BA%E6%95%B4%E7%90%86%EF%BC%89&amp;diff=6669"/>
		<updated>2024-04-08T12:34:08Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 字母、数字 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:IDEA]]&lt;br /&gt;
&lt;br /&gt;
== 常用快捷键 ==&lt;br /&gt;
=== IDEA ===&lt;br /&gt;
# 系统设置：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;&lt;br /&gt;
# 项目设置：&amp;lt;code&amp;gt;Ctrl + Shift + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt;&lt;br /&gt;
# 专注编辑器（隐藏所有工件窗口）：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 恢复默认布局：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 导航 ===&lt;br /&gt;
# '''切换器'''：'''&amp;lt;code&amp;gt;Ctrl + Tab&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 打开工具窗口：&lt;br /&gt;
## 项目：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;&lt;br /&gt;
## 文件结构：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;7&amp;lt;/code&amp;gt;&lt;br /&gt;
##*（弹出窗口）&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''文件打开位置'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F1&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 用于选择在哪里打开或定位当前文件；&lt;br /&gt;
&lt;br /&gt;
=== 窗口 ===&lt;br /&gt;
# 新窗口打开（当前文件）：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F4&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''最近的文件列表'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;E&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 最近的位置列表（查看 / 修改）：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;E&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''最近的拷贝列表'''：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 版本控制常用操作：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + '''&amp;lt;code&amp;gt;`&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
=== Search Everywhere 窗口 ===&lt;br /&gt;
（以下打开的是同一窗口）&lt;br /&gt;
# 所有：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; x2&lt;br /&gt;
# 类：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;&lt;br /&gt;
# 文件：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;&lt;br /&gt;
# 符号：&amp;lt;code&amp;gt;Ctrl + Alt + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;&lt;br /&gt;
# 操作：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;&lt;br /&gt;
* 在窗口中，可通过 &amp;lt;code&amp;gt;Ctrl + Tab&amp;lt;/code&amp;gt; 切换上述 Tab 页&lt;br /&gt;
&lt;br /&gt;
=== 编辑 ===&lt;br /&gt;
# 查找：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;（等效于：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F3&amp;lt;/code&amp;gt;）&lt;br /&gt;
#* 下一个：&amp;lt;code&amp;gt;F3&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 上一个：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F3&amp;lt;/code&amp;gt;&lt;br /&gt;
# 替换：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;&lt;br /&gt;
# 撤销：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 取消撤销：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt;&lt;br /&gt;
# 复制行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 复制并插入：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt;&lt;br /&gt;
# 删除行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt;&lt;br /&gt;
# 剪切行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;&lt;br /&gt;
# 注释行：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 注释块：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&lt;br /&gt;
# 移动行：&amp;lt;code&amp;gt;Alt + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;↑&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;↓&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 移动方法：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;↑&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;↓&amp;lt;/code&amp;gt;&lt;br /&gt;
# 上/下一个方法：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;↑&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;↓&amp;lt;/code&amp;gt;&lt;br /&gt;
# 大/小写轮换：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;&lt;br /&gt;
# 递进式选择：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;W&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 递进式取消选择：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;W&amp;lt;/code&amp;gt;&lt;br /&gt;
# 切换编辑页：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;←&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;→&amp;lt;/code&amp;gt;&lt;br /&gt;
#* 后退/前进导航：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;←&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;→&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 代码 ===&lt;br /&gt;
 '''代码模板'''、'''后缀补全'''，见：[[FAQ:IDEA#IDEA_设置：代码模板]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''错误：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''下一个错误/警告'''：'''&amp;lt;code&amp;gt;F2&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 上一个错误/警告：&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F2&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''错误描述'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F1&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''信息查看：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''快速文档'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 显示包含光标处符号（变量 / 类名 / 方法名）的文档（也可以在提示补充的时候按）&lt;br /&gt;
# '''快速定义'''：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 显示包含光标处符号（变量 / 类名 / 方法名）的文档&lt;br /&gt;
# 类型信息：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''形参信息'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 显示（光标处）方法的形式参数提示&lt;br /&gt;
# 上下文信息：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''层次结构：'''&lt;br /&gt;
## '''类型层次结构'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##* 区别于“当前类的结构”（文件结构）：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;7&amp;lt;/code&amp;gt;（或：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;）&lt;br /&gt;
## 方法层次结构：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;&lt;br /&gt;
## 调用层次结构：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;H&amp;lt;/code&amp;gt;&lt;br /&gt;
##* 与“查找调用”（&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;）结果一致，只是：前者只列出了层层调用关系，而后者对调用进行了分类，且信息更详细；&lt;br /&gt;
# '''文件结构'''（'''类信息'''）：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 工具窗口“文件结构”：&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;7&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''图表'''：&lt;br /&gt;
## 固定窗口：'''&amp;lt;code&amp;gt;Ctrl + Shift + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;'''&lt;br /&gt;
## 弹出窗口：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''查找跳转：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''转到声明 / 查找调用'''：&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;（或：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + 点击'''；或：“点击中键”）&lt;br /&gt;
#: 作用：&lt;br /&gt;
## 在调用处：跳转到“类 / 方法 / 属性”的声明；&lt;br /&gt;
## 在声明处：显示“类 / 方法 / 属性”所有的调用处；（等效于：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;）&lt;br /&gt;
# '''转到 super 方法'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;U&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 转到被“重载/实现”方法的“父类 / 接口”的方法定义处；&lt;br /&gt;
# '''查找实现'''：&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;（或：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + 点击'''）&lt;br /&gt;
#: 查找当前“类 / 方法”所有的实现；&lt;br /&gt;
# '''查找调用'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 查找“方法 / 变量 / 类”所有的被调用处；&lt;br /&gt;
#* 弹窗显示：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F7&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 转到类型声明：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;（或：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + 点击）&lt;br /&gt;
#: 跳转到当前“方法 / 属性”的类型声明处；&lt;br /&gt;
# 转到测试：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''生成代码：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''生成'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Insert&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 包括：构造函数、toString、重新方法、测试、版权；&lt;br /&gt;
#* 在编辑 '''pom.xml''' 等内容时，也可使用；&lt;br /&gt;
# '''重写方法'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;O&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''继承方法'''：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''环绕方式'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 用以下代码环绕选中的代码：if/else”、“while”、“for”、“try/catch”、“synchronized”、“Runnable”等&lt;br /&gt;
#* 解除环绕：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Delete&amp;lt;/code&amp;gt;&lt;br /&gt;
# 生成单元测试类：&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''优化导入的类'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;O&amp;lt;/code&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''代码重构：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''重命名'''：'''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F6&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取变量'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取字段'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取常数'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取方法'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;M&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''提取参数'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''内联'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;N&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# 复制：&amp;lt;code&amp;gt;F5&amp;lt;/code&amp;gt;&lt;br /&gt;
# 移动：&amp;lt;code&amp;gt;F6&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''重构此…'''：'''&amp;lt;code&amp;gt;Ctrl + Shift + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#: 包含'''重构操作列表'''的上下文感知弹出窗口&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;'''辅助优化：'''&amp;lt;/span&amp;gt; ====&lt;br /&gt;
# '''格式化代码'''：'''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;L&amp;lt;/code&amp;gt;'''&lt;br /&gt;
# '''显示快速修复'''：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;'''&lt;br /&gt;
#* 在代码需要 '''import''' 某些包、类时，可以使用该快捷键。&lt;br /&gt;
# 代码补全：&lt;br /&gt;
## '''基本补全'''（Basic completion）：'''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Space&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【基本代码补全功能可帮助您补全可见范围内的类，方法，字段和关键字。 当您调用代码补全功能时，IntelliJ IDEA 会分析上下文并提供可用的“建议列表”（建议中还将包括“Live templates”）】&lt;br /&gt;
&lt;br /&gt;
如果将基本代码补全应用于字段，参数或变量声明的一部分，则 IntelliJ IDEA 会根据项目类型提供可用的“建议列表”。&lt;br /&gt;
&lt;br /&gt;
第二次调用（按两次 Ctrl+Space）：将显示不可访问的类和成员（这些类和成员需要可以通过 Intention actions 公开）。【！！！】&lt;br /&gt;
&lt;br /&gt;
第三次调用（按三次 Ctrl+Space）：IntelliJ IDEA 将在整个项目中查找类和接口，而不考虑依赖关系。如果必要的类尚未导入，则将自动导入该类。【！！！】&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
##* &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''第二三次调用，在整个项目中搜索类和接口，而不考虑依赖关系。'''&amp;lt;/span&amp;gt; 【非常有用！！！】&lt;br /&gt;
##* 默认与 Windows 输入法快捷键冲突，建议修改为“&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + '''&amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;'''”&lt;br /&gt;
##* 第二基本补全: '''&amp;lt;code&amp;gt;Ctrl + Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Space&amp;lt;/code&amp;gt;'''&lt;br /&gt;
## '''智能补全'''（Smart completion）：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Space&amp;lt;/code&amp;gt;'''（基于预期类型补全代码）&lt;br /&gt;
##:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【智能代码补全功能会过滤“建议列表”，并仅显示适用于当前上下文的类型】&lt;br /&gt;
&lt;br /&gt;
在可以确定类型的情况下，智能补全非常有用：&lt;br /&gt;
 ● 在赋值语句的右侧；&lt;br /&gt;
 ● 在变量初始化时；&lt;br /&gt;
 ● 在 return 语句中；&lt;br /&gt;
 ● 在方法调用的参数列表中；&lt;br /&gt;
 ● 在对象声明中的 new 关键字之后；&lt;br /&gt;
 ● 在链式表达式中；&lt;br /&gt;
 &lt;br /&gt;
如有必要，再次按 Ctrl+Shift+Space 这样就可以完成：&lt;br /&gt;
 ● 集合，列表和数组。 —— IntelliJ IDEA 搜索具有相同组件类型的符号，并建议对其转换。&lt;br /&gt;
 ● 静态方法调用或常量引用。 —— IntelliJ IDEA 扫描静态方法和字段，并建议适合当前上下文的方法和字段。&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
## '''语句补全'''（Statement completion）：'''&amp;lt;code&amp;gt;Ctrl + Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【您可以使用语句补全来创建语法正确的代码构造。 —— 它插入必要的语法元素（括号，花括号和分号），并使光标处于可以开始键入下一条语句的位置】&lt;br /&gt;
&lt;br /&gt;
常用方式：&lt;br /&gt;
 ● 补全方法声明；&lt;br /&gt;
 ● 补全代码结构；&lt;br /&gt;
 ● 包裹方法的调用参数；&lt;br /&gt;
 ● 快速补全行末分号。&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
## '''Hippie 补全'''（Hippie completion）：'''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;'''&lt;br /&gt;
##: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
【Hippie completion 是一个补全引擎，可以分析可见范围内的文本并根据当前上下文生成建议。它可以帮助您补全当前打开的任何文件中的任何单词。】&lt;br /&gt;
&lt;br /&gt;
—— 说人话：会选择当前编辑器中适合的单词直接拿过来补全当前输入内容。&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 按辅键分类 ==&lt;br /&gt;
=== 字母、数字 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''字母、数字'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''1～9'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 定位到对应数值的书签位置&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 显示对应数值的选项卡&lt;br /&gt;
* 其中 '''1''' 是 Project，用得最多&lt;br /&gt;
* 其中 '''7''' 是 文件结构，常用&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 快速添加指定数值的书签&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''A'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''查找“动作 / 设置”'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''B'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 进入光标所在的“方法/变量”的“接口/定义”处&lt;br /&gt;
* 等效于“&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + 左键单击”&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 在某个调用的方法名上使用会跳到具体的实现处，可以跳过接口&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 跳转到类型声明处&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''C'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 复制光标所在行（或：选择的内容）&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 复制当前文件磁盘路径到剪贴板&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 查看最近操作项目的变化情况列表&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 复制参考信息&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''D'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 复制并插入复制光标所在行（或：选择的内容），并把复制的内容插入光标位置后&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''E'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''显示最近打开的文件记录列表'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 显示最近修改的文件列表的弹出层&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 在当前文件进行文本查找&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' + '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''根据输入内容查找整个项目（或：指定目录内文件）'''——【'''（自定义）全局查找'''】&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 显示添加到收藏夹弹出层 / 添加到收藏夹&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''G'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 在当前文件跳转到指定行处&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''H'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 显示'''当前类的层次结构'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 调用层次&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 显示方法层次结构&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''I'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''选择可继承的方法'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 光标所在行（或：选中部分）进行自动代码缩进，有点类似格式化&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 快速查看光标所在的“方法 / 类”的定义&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 查看项目当前文件&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''J'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + J || 插入自定义动态代码模板&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''弹出模板选择窗口'''，讲选定的代码加入动态模板中&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 自动将下一行合并到当前行末尾 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''K'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; ||版本控制：提交项目，需要此项目有加入到版本控制才可用&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''L'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''格式化代码'''&lt;br /&gt;
* 可以对当前文件和整个包目录使用&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''N'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 根据输入的“类名”'''查找类文件'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 通过文件名“定位 / 打开”“文件 / 目录”，打开目录需要在输入的内容后面多加一个正斜杠&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || “选择 / 添加”task&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 前往指定的“变量 / 方法”&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''O'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''选择可重写的方法'''&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''优化导入的类'''&lt;br /&gt;
* 可以对当前文件和整个包目录使用&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''P'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''方法参数提示显示'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''Q'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 光标所在的“变量 / 类名 / 方法名”等上面（也可以在提示补充的时候按），显示文档内容&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 弹出一个提示，显示当前类的“声明 / 上下文”信息&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''R'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 在当前文件进行文本替换&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 根据输入内容替换对应内容，范围为整个项目（或：指定目录内文件）&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''S'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''打开 IntelliJ IDEA 系统设置'''&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''打开当前项目设置'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''T'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 版本控制：更新项目，需要此项目有加入到版本控制才可用&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''对选中的代码弹出环绕选项弹出层'''&lt;br /&gt;
* “if/else”、“while”、“for”、“try/catch”、“synchronized”、“Runnable”等&lt;br /&gt;
* 可使用 '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Delete&amp;lt;/code&amp;gt;''' 接触代码环绕。&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''对当前类生成单元测试类'''，如果已经存在的单元测试类则可以进行选择&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''U'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 前往当前光标所在'''方法的“父类方法 / 接口”定义'''处&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || 对选中的代码进行'''“大 / 小写”轮流转换'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''V'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 快速引进变量&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || '''弹出“缓存的最近拷贝的内容”管理器弹出层'''&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 无格式黏贴&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''W'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 递进式选择代码块&lt;br /&gt;
* 可选中光标所在的单词或段落，连续按会在原有选中的基础上再扩展选中范围&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 递进式取消选择代码块&lt;br /&gt;
* 可选中光标所在的单词或段落，连续按会在原有选中的基础上再扩展选中范围&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''X'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 剪切光标所在行（或：选择的内容）&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''Y'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 删除光标所在行（或：选中的行）&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 同步、刷新&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''Z'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 撤销&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 取消撤销&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== F1～F12 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''F1～F12'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F1'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 在光标所在的错误代码出显示'''错误信息'''&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''显示当前文件的“选择目标弹出层”'''（在哪里打开当前文件），弹出层中有很多目标可以进行选择&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || （如果有外部文档）可以连接外部文档&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F2'''&lt;br /&gt;
|  || '''跳转到下一个高亮错误'''（或：警告位置）&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 对于前面页面，显示各类浏览器打开目标选择弹出层&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''跳转到上一个高亮错误'''（或：警告位置）&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F3'''&lt;br /&gt;
|  || 在查找模式下，定位到下一个匹配处&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 调转到所选中的词的下一个引用位置&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''选中文本，逐个往下查找相同文本，并高亮显示'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 在查找模式下，查找匹配上一个&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F4'''&lt;br /&gt;
|  || 编辑源&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 关闭当前编辑文件&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''对当前打开的文件，使用新 Windows 窗口打开，旧窗口保留'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F6'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || 对“文件 / 文件夹”重命名&lt;br /&gt;
* 在编辑框对“字段”重命名&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F7'''&lt;br /&gt;
|  ||【Debug 模式下，步入】：如果当前行断点是一个方法，则进入当前方法体内，如果该方法体还有方法，则不会进入该内嵌的方法中&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 查找光标所在的'''“方法 / 变量 / 类”被调用的地方'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，智能步入】：断点所在行上有多个方法调用，会弹出进入哪个方法&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 显示使用的地方。寻找被该类或是变量被调用的地方，用弹出框的方式找出来&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 高亮显示所有该选中文本，按 Esc 高亮消失&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，强制步入】：进入当前方法体内，如果方法体还有方法，则会进入该内嵌的方法中，依此循环进入&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F8'''&lt;br /&gt;
|  ||【Debug 模式下，步过】：如果当前行断点是一个方法，则不进入当前方法体内&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; ||【Debug 模式下，“设置/取消”断点】&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; ||【Debug 模式下，评估表达式】：选中对象，弹出可输入计算表达式调试框，查看该输入内容的调试结果&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，步出】：表现出来的效果跟 &amp;lt;code&amp;gt;F9&amp;lt;/code&amp;gt; 一样&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; ||【Debug 模式下，指定断点进入条件】&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F9'''&lt;br /&gt;
|  ||【Debug 模式下，恢复程序运行】：但是如果该断点下面代码还有断点则停在下一个断点上&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 执行 Make Project（构建项目） 操作&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; ||【Debug 模式下，运行到光标处】&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 等效于点击工具栏的 Debug 按钮&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 编译选中的“文件 / 包 / Module”&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''弹出 Debug 的可选择菜单'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F10'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 等效于点击工具栏的 Run 按钮&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''弹出 Run 的可选择菜单'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F11'''&lt;br /&gt;
|  || 添加书签&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 选中“文件 / 文件夹”，使用助记符“设定 / 取消”书签&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || '''弹出书签显示层'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 切换全屏模式&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''F12'''&lt;br /&gt;
|  || 回到前一个工具窗口&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''弹出当前文件结构层'''，可以在弹出的层上直接输入，进行筛选&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 编辑器最大化&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 符号 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''符号'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''`'''&amp;lt;span&amp;gt;&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''显示版本控制常用操作菜单弹出层'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''+'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 展开代码&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 展开所有代码&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''-'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 折叠代码&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 折叠所有代码&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''/'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || '''注释'''光标所在行代码&lt;br /&gt;
* 会根据当前不同文件类型使用不同的注释符号&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 代码块注释&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | '''['''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 移动光标到当前所在代码的花括号开始位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中从光标所在位置到它的顶部中括号位置&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | ''']'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 移动光标到当前所在代码的花括号结束位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中从光标所在位置到它的底部中括号位置&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 操作 ===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center;&amp;quot;| &amp;lt;span style=&amp;quot;font-size:34px; color:LightSlateGray&amp;quot;&amp;gt;'''操作'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 辅键 !! 主键 !! 描述 &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''←'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 光标跳转到当前“单词 / 中文句”的左侧开头位置&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''向左切换'''（当前已打开的）'''文件视图'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 退回到上一个操作的地方&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 在代码文件上，光标跳转到当前“单词 / 中文句”的左侧开头位置，同时选中该“单词 / 中文句”&lt;br /&gt;
* 在光标焦点是在工具选项卡上，缩小选项卡区域&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''→'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 光标跳转到当前“单词 / 中文句”的右侧开头位置&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''向右切换'''（当前已打开的）'''文件视图'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 前进到上一个操作的地方&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 在代码文件上，光标跳转到当前“单词 / 中文句”的右侧开头位置，同时选中该“单词 / 中文句”&lt;br /&gt;
* 在光标焦点是在工具选项卡上，扩大选项卡区域&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''↑'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 等效于鼠标滚轮向前效果&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 当前光标跳转到当前文件的'''前一个方法名'''位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 在查找模式下，跳到上个查找的文件&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向上调整方法排序'''：光标放在“方法名所在行”上，将方法移动到上一个方法前面&lt;br /&gt;
* 光标放在“普通行”上，等同于“&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + ↑”&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向上移动光标所在行'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; style=&amp;quot;text-align:center;&amp;quot; | &amp;lt;span style=&amp;quot;font-size:20px;&amp;quot;&amp;gt;'''↓'''&amp;lt;/span&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 等效于鼠标滚轮向后效果&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 当前光标跳转到当前文件的'''后一个方法名'''位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 在查找模式下，跳到下个查找的文件&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向下调整方法排序'''：光标放在“方法名所在行”上，将方法移动到下一个方法后面&lt;br /&gt;
* 光标放在“普通行”上，等同于“&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; + ↓”&lt;br /&gt;
|- &lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''向下移动光标所在行'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''ESC'''&lt;br /&gt;
|  || 从工具窗口进入代码文件窗口&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 隐藏当前（或：最后一个激活的）工具窗口&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Tab'''&lt;br /&gt;
|  || 缩进&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''编辑窗口切换'''，如果在切换的过程又加按上 delete，则是关闭对应选中的窗口&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 取消缩进&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Space'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || '''基础代码补全'''&lt;br /&gt;
* 默认在 Windows 系统上被输入法占用，需要进行修改，建议修改为“&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + 逗号”&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''类名自动完成'''&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || '''智能代码提示'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Enter'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 智能分隔行&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || 根据光标所在问题，提供'''快速修复'''选择，光标放在的位置不同提示的结果也不同&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 开始新一行。光标所在行下空出一行，光标定位到新行位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 光标所在行上空出一行，光标定位到新行&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 自动结束代码，行末自动添加分号&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Home'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 跳到文件头&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || “定位 / 显示”到当前文件的 Navigation Bar&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中光标到当前行头位置&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; || 弹出跟当前文件有关联的文件弹出层&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''End'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 跳到文件尾&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选中光标到当前行尾位置&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Insert'''&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt;''' || '''代码自动生成'''，如生成对象的“ set / get 方法，构造函数，toString()”等&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''Delete'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 删除光标后面的单词或是中文句&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| '''BackSpace'''&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; || 删除光标前面的单词或是中文句&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 退回到上次修改的地方&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【光标定位】&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 按 &amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt; 不要松开，会显示光标所在的'''类信息摘要'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【左键单击】&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Ctrl&amp;lt;/code&amp;gt;''' || 在打开的文件标题上，弹出该'''文件路径'''&lt;br /&gt;
|-&lt;br /&gt;
| '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;''' || 在打开的文件名上按此快捷键，可以'''关闭当前打开文件'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【左键双击】&lt;br /&gt;
| &amp;lt;code&amp;gt;Alt&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 选择被双击的“单词 / 中文句”，按住不放，可以同时选择其他“单词 / 中文句”&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【滚轮前后滚动】&lt;br /&gt;
| &amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt; || 当前文件的横向滚动轴滚动&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;  style=&amp;quot;text-align:center;&amp;quot;| 【连按两次 '''&amp;lt;code&amp;gt;Shift&amp;lt;/code&amp;gt;'''】&lt;br /&gt;
|  || '''弹出 Search Everywhere 窗口'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=InnoDB%EF%BC%9AInnoDB_%E4%BA%8B%E5%8A%A1%E6%A8%A1%E5%9E%8B&amp;diff=6668</id>
		<title>InnoDB：InnoDB 事务模型</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=InnoDB%EF%BC%9AInnoDB_%E4%BA%8B%E5%8A%A1%E6%A8%A1%E5%9E%8B&amp;diff=6668"/>
		<updated>2024-01-18T14:30:10Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* “READ COMMITTED” */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:MySQL文档]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
在 InnoDB 事务模型中，目标是将 multi-versioning 数据库的最佳属性与传统的两阶段锁定【？】相结合。 InnoDB在行级别上执行锁定，并且默认情况下以 Oracle 风格将查询作为非锁定 consistent reads 运行。 InnoDB 中的锁信息以节省空间的方式存储，因此不需要锁升级。通常，允许几个用户锁定 InnoDB 表中的每一行或该行的任何随机子集，而不会导致 InnoDB 内存耗尽。&lt;br /&gt;
&lt;br /&gt;
== '''事务隔离级别''' ==&lt;br /&gt;
事务隔离是数据库处理的基础之一。隔离是缩写“ACID”中的“I”；隔离级别是一种设置，用于在多个事务同时进行更改和执行查询时微调性能与结果的可靠性，一致性和可重复性之间的平衡。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
InnoDB提供了 SQL：1992 标准描述的所有四个事务隔离级别：“'''READ UNCOMMITTED'''”，“'''READ COMMITTED'''”，“'''REPEATABLE READ'''”和“'''SERIALIZABLE'''”。 &lt;br /&gt;
* InnoDB 的默认隔离级别是“REPEATABLE READ”。&lt;br /&gt;
* 用户可以使用“'''SET TRANSACTION'''”语句更改单个会话或所有后续连接的隔离级别。要为所有连接设置服务器的默认隔离级别，请在命令行或选项文件中使用“'''--transaction-isolation'''”选项。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
InnoDB 使用不同的锁定策略支持此处描述的每个事务隔离级别。&lt;br /&gt;
: 您可以对“ACID”合规性很重要的关键数据进行操作，与默认“REPEATABLE READ”级别保持高度一致性。&lt;br /&gt;
: 或者，您可以使用“READ COMMITTED”甚至是“READ UNCOMMITTED”放宽一致性规则，例如在批量报告中，精确的一致性和可重复的结果不如最小化锁定开销重要。 &lt;br /&gt;
: “SERIALIZABLE”强制执行比“REPEATABLE READ”更为严格的规则，并且主要用于特殊情况下，例如 XA 事务以及对并发和死锁进行故障排除。&lt;br /&gt;
&lt;br /&gt;
=== “REPEATABLE READ” ===&lt;br /&gt;
这是 InnoDB 的默认隔离级别。'''同一事务中的 Consistent reads（一致性读）读取由第一次读取构建的 snapshot（快照）'''。&lt;br /&gt;
# 【非锁定读】这意味着，如果您在同一事务中发出几个简单的（非锁定）SELECT语句，则这些 SELECT 语句彼此之间也是一致的。&lt;br /&gt;
# 【锁定读、更新】对于锁定读取（带有“FOR UPDATE”或“LOCK IN SHARE MODE”的SELECT），“UPDATE”和“DELETE”语句，锁定取决于该语句是使用具有唯一搜索条件的唯一索引还是范围类型搜索条件。【？？】&lt;br /&gt;
## 对于具有唯一搜索条件的唯一索引，InnoDB 仅锁定找到的索引记录，而不锁定之前的间隙。&lt;br /&gt;
## 对于其他搜索条件，InnoDB 锁定扫描的索引范围，使用“gap locks”（间隙锁）或“next-key locks”（下一键锁）阻止其他会话插入该范围所覆盖的间隙。&lt;br /&gt;
&lt;br /&gt;
=== “READ COMMITTED” ===&lt;br /&gt;
'''即使在同一事务中，每个一致的读取都将设置并读取其自己的新快照'''。&lt;br /&gt;
# 【锁定读、更新】对于锁定读取（带有“FOR UPDATE”或“LOCK IN SHARE MODE”的SELECT），“UPDATE”和“DELETE”语句，InnoDB 仅锁定索引记录，而不锁定它们之间的间隙，因此允许在锁定记录旁边自由插入新记录。间隙锁定仅用于外键约束检查和重复键检查。&lt;br /&gt;
#* 由于禁用了间隙锁定，因此可能会产生幻影问题，因为其他会话可以在间隙中插入新行。&lt;br /&gt;
# “READ COMMITTED”隔离级别仅支持基于行的二进制日志记录。如果将“READ COMMITTED”与“binlog_format=MIXED”一起使用，则服务器将自动使用基于行的日志记录。【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用“READ COMMITTED”具有其他效果：&lt;br /&gt;
# 对于“UPDATE”和“DELETE”语句，InnoDB 仅对其更新或删除的行保持锁定。 MySQL 评估“WHERE”条件后，将释放不匹配行的记录锁。（这大大降低了死锁的可能性，但是仍然可以发生。）&lt;br /&gt;
# 对于“UPDATE”语句，如果某行已被锁定，则 InnoDB 执行“半一致”读取，将最新的提交版本返回给 MySQL，以便 MySQL 可以确定该行是否与“UPDATE”的“WHERE”条件匹配。如果该行匹配（必须更新），则 MySQL 再次读取该行，这一次 InnoDB 要么锁定它，要么 await 对其进行锁定。【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例 1：【？】&amp;lt;br/&amp;gt;&lt;br /&gt;
有如下表，'''表没有索引'''，因此搜索和索引扫描'''将隐藏的聚集索引用于记录锁定，而不是使用索引列'''。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;&lt;br /&gt;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);&lt;br /&gt;
COMMIT;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
假设一个会话使用以下语句执行“UPDATE”：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
# Session A&lt;br /&gt;
START TRANSACTION;&lt;br /&gt;
UPDATE t SET b = 5 WHERE b = 3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
还假设第二个会话通过在第一个会话的语句之后执行以下语句来执行“UPDATE”：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
# Session B&lt;br /&gt;
UPDATE t SET b = 4 WHERE b = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
当 InnoDB 执行每个“UPDATE”时，它首先为其读取的每一行获取一个排他锁，然后确定是否对其进行修改。如果 InnoDB 不修改该行，它将释放锁定。否则，InnoDB 保留锁，直到事务结束。这会影响事务处理，如下所示。&lt;br /&gt;
&lt;br /&gt;
# 使用默认的“REPEATABLE READ”隔离级别时：&lt;br /&gt;
#: 第一个“UPDATE”会在其读取的每一行上获得一个 x 锁，并且不会释放其中的任何一个：【！&amp;lt;span style=&amp;quot;color:Chocolate; font-weight:bold;&amp;quot;&amp;gt;因为没有使用索引，所以导致全表扫面，而又因为 RR 使用“临键锁”，所以每一条记录的索引都被使用“临键锁”，相当于“全表锁定”&amp;lt;span&amp;gt;】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); retain x-lock&lt;br /&gt;
x-lock(2,3); update(2,3) to (2,5); retain x-lock&lt;br /&gt;
x-lock(3,2); retain x-lock&lt;br /&gt;
x-lock(4,3); update(4,3) to (4,5); retain x-lock&lt;br /&gt;
x-lock(5,2); retain x-lock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 第二个“UPDATE”会在尝试获取任何锁时立即阻止（因为第一次更新已在所有行上保留了锁），并且直到第一个“UPDATE”提交或回滚后才继续进行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); block and wait for first UPDATE to commit or roll back&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 如果改为使用“READ COMMITTED”：&lt;br /&gt;
#: 则第一个“UPDATE”会在其读取的每一行上获取一个 x 锁，并释放其未修改的行的 x 锁：【！&amp;lt;span style=&amp;quot;color:Chocolate; font-weight:bold;&amp;quot;&amp;gt;因为没有使用索引，所以导致全表扫面，而又 RC 不使用“临键锁”（间隙锁），所以只会锁定有对应值的记录&amp;lt;span&amp;gt;】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); unlock(1,2)&lt;br /&gt;
x-lock(2,3); update(2,3) to (2,5); retain x-lock&lt;br /&gt;
x-lock(3,2); unlock(3,2)&lt;br /&gt;
x-lock(4,3); update(4,3) to (4,5); retain x-lock&lt;br /&gt;
x-lock(5,2); unlock(5,2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 对于第二个“UPDATE”，InnoDB 进行“半一致”读取，将它读取的每一行的最新提交版本返回给 MySQL，以便 MySQL 可以确定该行是否与“UPDATE”的“WHERE”条件匹配：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); update(1,2) to (1,4); retain x-lock&lt;br /&gt;
x-lock(2,3); unlock(2,3)&lt;br /&gt;
x-lock(3,2); update(3,2) to (3,4); retain x-lock&lt;br /&gt;
x-lock(4,3); unlock(4,3)&lt;br /&gt;
x-lock(5,2); update(5,2) to (5,4); retain x-lock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例 2：【？】&amp;lt;br/&amp;gt;&lt;br /&gt;
但是，如果“WHERE”条件'''包含索引列'''，并且 InnoDB 使用索引，则在获取和保留记录锁时'''仅考虑索引列'''。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t (a INT NOT NULL, b INT, c INT, INDEX (b)) ENGINE = InnoDB;&lt;br /&gt;
INSERT INTO t VALUES (1,2,3),(2,2,4);&lt;br /&gt;
COMMIT;&lt;br /&gt;
&lt;br /&gt;
# Session A&lt;br /&gt;
START TRANSACTION;&lt;br /&gt;
UPDATE t SET b = 3 WHERE b = 2 AND c = 3;&lt;br /&gt;
&lt;br /&gt;
# Session B&lt;br /&gt;
UPDATE t SET b = 4 WHERE b = 2 AND c = 4;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
在上面的示例中，第一个“UPDATE”在 b = 2 的每一行上获取并保留一个 x 锁。第二个“UPDATE”尝试获取同一记录上的 x 锁时将阻塞，因为它也使用在 b 列上定义的索引。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用“READ COMMITTED”隔离级别的效果与启用已弃用的“innodb_locks_unsafe_for_binlog”配置选项相同，但以下情况除外：&lt;br /&gt;
* 启用“innodb_locks_unsafe_for_binlog”是全局设置，会影响所有会话，而隔离级别可以针对所有会话全局设置，也可以针对每个会话单独设置。&lt;br /&gt;
* “innodb_locks_unsafe_for_binlog”只能在服务器启动时设置，而隔离级别可以在启动时设置或在运行时更改。&lt;br /&gt;
因此“READ COMMITTED”比“innodb_locks_unsafe_for_binlog”提供了更好，更灵活的控制。&lt;br /&gt;
&lt;br /&gt;
=== “READ UNCOMMITTED” ===&lt;br /&gt;
SELECT 语句以'''非锁定'''方式执行，但是可能会使用'''行的早期版本'''。因此，使用此隔离级别，此类读取不一致。这也称为 '''dirty read（脏读）'''。否则，此隔离级别的作用类似于“READ COMMITTED”。&lt;br /&gt;
&lt;br /&gt;
=== “SERIALIZABLE” ===&lt;br /&gt;
此级别类似于“REPEATABLE READ”，但是&lt;br /&gt;
# InnoDB 如果禁用了autocommit，则将所有普通 SELECT 语句隐式转换为“'''SELECT ... LOCK IN SHARE MODE'''”。&lt;br /&gt;
# 如果启用了autocommit，则 SELECT 是其自身的事务。&lt;br /&gt;
因此，它被认为是'''只读的'''，并且如果以一致的（非锁定）读取方式执行并且不需要阻塞其他事务就可以序列化。&lt;br /&gt;
*（如果其他事务已修改所选行，则要强制普通 SELECT 阻止，请禁用autocommit。）&lt;br /&gt;
&lt;br /&gt;
== 自动提交，提交和回滚 ==&lt;br /&gt;
在 InnoDB 中，所有用户活动都发生在事务内部。如果启用了 autocommit 模式，则'''每个 SQL 语句将自己形成一个事务'''。默认情况下，MySQL 为启用了 autocommit 的每个新连接启动会话，因此，如果每个 SQL 语句未返回错误，则 MySQL 都会在该 SQL 语句之后进行提交。如果一条语句返回错误，则提交或回滚行为取决于该错误。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# 启用了 autocommit 的会话可以通过以显式“START TRANSACTION”或“BEGIN”语句开始，并以“COMMIT”或“ROLLBACK”语句结束来执行'''多语句事务'''。【！】&lt;br /&gt;
# 如果在具有“SET autocommit = 0”的会话中禁用了 autocommit 模式，则该会话'''始终具有打开的事务'''。“COMMIT”或“ROLLBACK”语句结束当前事务，然后开始新的事务。【！】&lt;br /&gt;
#* 如果禁用了 autocommit 的会话在没有显式提交最终事务的情况下结束，则 MySQL 将回滚该事务。【！】&lt;br /&gt;
# 某些语句隐式结束事务，就像您在执行该语句之前已经完成“COMMIT”一样。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
“COMMIT”表示在当前事务中所做的更改将成为永久性的，并在其他会话中可见。另一方面，“ROLLBACK”语句会取消当前事务所做的所有修改。'''“COMMIT”和“ROLLBACK”都释放在当前事务期间设置的所有 InnoDB 锁'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 将 DML 操作与事务分组 ===&lt;br /&gt;
默认情况下，与 MySQL 服务器的连接从启用 autocommit 模式开始，此模式会在您执行时自动提交每个 SQL 语句。如果您有其他数据库系统的经验，则可能不熟悉这种操作模式，在标准实践中，发出一系列 DML 语句并将其提交或一起回滚。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
要使用'''多语句事务'''：&lt;br /&gt;
* 请使用 SQL 语句“SET autocommit = 0”关闭自动提交，并在适当时以“COMMIT”或“ROLLBACK”结束每个事务。&lt;br /&gt;
* 要保留自动提交功能，请以“START TRANSACTION”开始每个事务，并以“COMMIT”或“ROLLBACK”结束它。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：显示了两个事务。第一个被提交；第二个被回滚。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
shell&amp;gt; mysql test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; CREATE TABLE customer (a INT, b CHAR (20), INDEX (a));&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; -- Do a transaction with autocommit turned on.&lt;br /&gt;
mysql&amp;gt; START TRANSACTION;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; INSERT INTO customer VALUES (10, 'Heikki');&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; COMMIT;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; -- Do another transaction with autocommit turned off.&lt;br /&gt;
mysql&amp;gt; SET autocommit=0;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; INSERT INTO customer VALUES (15, 'John');&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; INSERT INTO customer VALUES (20, 'Paul');&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; DELETE FROM customer WHERE b = 'Heikki';&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; -- Now we undo those last 2 inserts and the delete.&lt;br /&gt;
mysql&amp;gt; ROLLBACK;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; SELECT * FROM customer;&lt;br /&gt;
+------+--------+&lt;br /&gt;
| a    | b      |&lt;br /&gt;
+------+--------+&lt;br /&gt;
|   10 | Heikki |&lt;br /&gt;
+------+--------+&lt;br /&gt;
1 row in set (0.00 sec)&lt;br /&gt;
mysql&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Client 端语言的事务 ===&lt;br /&gt;
在诸如 PHP，Perl DBI，JDBC，ODBC 或 MySQL 的标准 C 调用接口之类的 API 中，您可以像其他任何 SQL 语句（如“SELECT”或“INSERT”）一样，将事务控制语句（如“COMMIT”）作为字符串发送到 MySQL 服务器。&lt;br /&gt;
* 一些 API 还提供了单独的特殊事务提交和回滚功能或方法。&lt;br /&gt;
&lt;br /&gt;
== 一致的'''非锁定读取''' ==&lt;br /&gt;
consistent read（一致性读取）表示 InnoDB 使用'''多版本控制'''在某个时间点向查询呈现数据库'''快照'''：&lt;br /&gt;
&lt;br /&gt;
: '''该查询将看到在该时间点之前提交的事务所做的更改，而看不到以后或未提交的事务所做的更改'''。【该规则的例外是查询可以看到同一事务中较早的语句所做的更改。】&lt;br /&gt;
&lt;br /&gt;
此异常导致以下异常：如果更新表中的某些行，则“SELECT”将看到已更新行的最新版本，但也可能会看到任何行的旧版本。如果其他会话同时更新同一张表，则异常意味着您可能会以数据库中不存在的状态查看该表。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''隔离级别与一致性读取：'''&lt;br /&gt;
# 如果事务隔离级别为“'''REPEATABLE READ'''”（默认级别），则'''同一事务中的所有一致读取将读取由该事务中的第一个此类读取构建的快照'''。&lt;br /&gt;
#* 您可以通过提交当前事务并在此之后发出新查询来获取查询的更新快照。&lt;br /&gt;
# 使用“'''READ COMMITTED'''”隔离级别，则'''事务中的每个一致读取都会设置并读取其自己的新快照'''。&lt;br /&gt;
一致读取是 InnoDB 处理“READ COMMITTED”和“REPEATABLE READ”隔离级别的“SELECT”语句的默认模式。一致读取'''不会在它访问的表上设置任何锁'''，因此其他会话可以自由地在对表执行一致读取的同时修改这些表。&lt;br /&gt;
: 假设您以默认的“REPEATABLE READ”隔离级别运行。当您发出一致的读取（即普通的“SELECT”语句）时，InnoDB 为您的事务提供一个时间点，根据该时间点您的查询可以看到数据库。如果另一个事务删除了一行并在分配了时间点后提交，则看不到该行已被删除。插入和更新的处理方式相似。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''NOTE：'''&amp;lt;/big&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
数据库状态的快照适用于事务中的“SELECT”条语句，而'''不必适用于 DML 语句'''。如果您插入或修改某些行，然后提交该事务，则从另一个并发“REPEATABLE READ”事务发出的“DELETE”或“UPDATE”语句可能会影响那些刚刚提交的行，即使会话无法查询它们。如果某个事务确实更新或删除了另一个事务提交的行，则这些更改对于当前事务而言确实可见。&lt;br /&gt;
: 例如，您可能会遇到以下情况：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz';&lt;br /&gt;
-- Returns 0: no rows match.&lt;br /&gt;
DELETE FROM t1 WHERE c1 = 'xyz';&lt;br /&gt;
-- Deletes several rows recently committed by other transaction.&lt;br /&gt;
&lt;br /&gt;
SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc';&lt;br /&gt;
-- Returns 0: no rows match.&lt;br /&gt;
UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc';&lt;br /&gt;
-- Affects 10 rows: another txn just committed 10 rows with 'abc' values.&lt;br /&gt;
SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba';&lt;br /&gt;
-- Returns 10: this txn can now see the rows it just updated.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
您可以通过提交事务，然后执行另一个“SELECT”或使用一致的快照开始事务（“START TRANSACTION WITH CONSISTENT SNAPSHOT”，即使用“START TRANSACTION”等语句开始新事务）来推进时间。这称为&amp;lt;big&amp;gt;'''多版本并发控制'''&amp;lt;/big&amp;gt;。【？？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&amp;lt;br/&amp;gt;&lt;br /&gt;
会话 A 仅在“ B 提交了插入，并且 A 也提交了”时，才看到 B 插入的行，因此时间点比 B 的提交提前了。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
           Session A              Session B&lt;br /&gt;
&lt;br /&gt;
           SET autocommit=0;      SET autocommit=0;&lt;br /&gt;
time&lt;br /&gt;
|          SELECT * FROM t;&lt;br /&gt;
|          empty set&lt;br /&gt;
|                           INSERT INTO t VALUES (1, 2);&lt;br /&gt;
|&lt;br /&gt;
v          SELECT * FROM t;&lt;br /&gt;
           empty set&lt;br /&gt;
                                COMMIT;&lt;br /&gt;
&lt;br /&gt;
          SELECT * FROM t;&lt;br /&gt;
           empty set&lt;br /&gt;
&lt;br /&gt;
           COMMIT;&lt;br /&gt;
&lt;br /&gt;
          SELECT * FROM t;&lt;br /&gt;
          ---------------------&lt;br /&gt;
          |    1    |    2    |&lt;br /&gt;
          ---------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果要'''查看数据库的“最新鲜”状态'''，请使用“'''READ COMMITTED'''”隔离级别或 locking read（&amp;lt;big&amp;gt;'''锁定读取'''&amp;lt;/big&amp;gt;）：&lt;br /&gt;
'''&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t FOR SHARE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
# 使用“READ COMMITTED”隔离级别，事务中的每个一致读取都会设置并读取其自己的新快照。&lt;br /&gt;
# 使用“LOCK IN SHARE MODE”时，将发生锁定读取：“SELECT”阻塞，直到包含最新行的事务结束。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''一致读取不适用于某些 DDL 语句'''：&lt;br /&gt;
* 一致读取无法在“DROP TABLE”上进行，因为 MySQL 无法使用已删除的表，而 InnoDB 会破坏该表。&lt;br /&gt;
* 一致读取在“ALTER TABLE”上不起作用，因为该语句将创建原始表的临时副本，并在构建该临时副本时删除该原始表。当您在事务内重新发出一致的读取时，新表中的行不可见，因为在获取事务快照时这些行不存在。在这种情况下，事务返回错误：“ER_TABLE_DEF_CHANGED”（“table 定义已更改，请重试事务”）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于未指定“FOR UPDATE”或“LOCK IN SHARE MODE”的“INSERT INTO ... SELECT”、“UPDATE ... (SELECT)”和“CREATE TABLE ... SELECT”之类的“select”子句，读取的类型有所不同：&lt;br /&gt;
* 默认情况下，InnoDB 使用更强的锁定，而 SELECT 部分的作用类似于“READ COMMITTED”，即使在同一事务中，每个一致的读取也会设置并读取自己的新快照。&lt;br /&gt;
* 要在这种情况下使用一致的读取，请启用“innodb_locks_unsafe_for_binlog”选项，并将事务的隔离级别设置为“READ UNCOMMITTED”，“READ COMMITTED”或“REPEATABLE READ”（即“SERIALIZABLE”以外的任何值）。在这种情况下，'''不会对从所选表读取的行设置锁定'''。&lt;br /&gt;
&lt;br /&gt;
== '''锁定读取''' ==&lt;br /&gt;
如果查询数据，然后在同一事务中插入或更新相关数据，则常规“SELECT”语句不能提供足够的保护。其他事务可以更新或删除刚查询的相同行。 &lt;br /&gt;
&lt;br /&gt;
InnoDB 支持两种提供额外安全性的locking reads（锁定读取）：&lt;br /&gt;
# “'''SELECT ... LOCK IN SHARE MODE'''”【！！！】&lt;br /&gt;
#: 在读取的任何行上设置'''共享模式锁定'''。'''其他会话可以读取行，但是在事务提交之前不能修改它们'''。如果这些行中的任何一个被尚未提交的另一个事务更改，则查询将 await 直到该事务结束，然后使用最新值。&lt;br /&gt;
# “'''SELECT ... FOR UPDATE'''”【！！！这个我常用】&lt;br /&gt;
#: 对于索引记录，搜索遇到的情况，'''锁定行和任何关联的索引条目'''，就像您为这些行发出“UPDATE”语句一样。&lt;br /&gt;
#* &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
禁止其他事务更新这些行，执行“SELECT ... LOCK IN SHARE MODE”或读取某些事务隔离级别的数据。一致的读取将忽略读取视图中存在的记录上设置的任何锁定。（记录的旧版本无法锁定；可以通过在记录的内存副本上应用undo logs来重构它们。）【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE：&lt;br /&gt;
* 提交或回滚事务时，将释放由“LOCK IN SHARE MODE”和“FOR UPDATE”查询设置的所有锁。&lt;br /&gt;
* '''只有在禁用自动提交时'''（通过以“START TRANSACTION”开始事务或将“autocommit”设置为 0），'''才可以进行锁定读取'''。&lt;br /&gt;
* 除非在子查询中也指定了锁定读取子句，否则'''外部语句中的锁定读取子句不会锁定嵌套子查询中表的行'''。&lt;br /&gt;
*: 例如，以下语句不会锁定表 t2 中的行：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2) FOR UPDATE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: 要锁定表 t2 中的行，请向子查询添加一个锁定 read 子句：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2 FOR UPDATE) FOR UPDATE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 锁定读：'''“行锁”与“表锁”''' ===&lt;br /&gt;
InnoDB 行锁是通过给索引上的索引项加锁来实现的，'''只有通过索引条件检索数据，InnoDB 才使用行级锁，否则，InnoDB 将使用表锁'''。【！！！】&lt;br /&gt;
* 即便在条件中使用了索引字段，但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的，如果 MySQL 认为全表扫描效率更高（比如对一些很小的表）就不会使用索引，这种情况下 InnoDB 将使用表锁，而不是行锁。&lt;br /&gt;
*: 因此，在分析锁冲突时，别忘了检查 SQL 的执行计划，以确认是否真正使用了索引。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
锁定读的所情况总结：&lt;br /&gt;
# “无锁”：根据“主键”、“非主键索引”、“主键 + 非主键索引”、“主键 + 非索引”进行查询，但未查询到数据时。&lt;br /&gt;
# “行锁”：根据“主键”、“非主键索引”、“主键 + 非主键索引”进行查询，并查询到数据时。&lt;br /&gt;
# “'''表锁'''”：&lt;br /&gt;
## 只根据“非索引”字段进行查询时（无论是否查询到数据）；【'''未使用索引'''】&lt;br /&gt;
## 只根据“主键”进行查询，条件为“&amp;lt;&amp;gt;”、“like”时（无论是否查询到数据）；【'''结果集为范围'''】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 根据“主键 + 非索引”进行查询，并且查询到数据时：【？？？】&lt;br /&gt;
*# 如果其他线程按“主键”字段进行查询，则“主键”字段产生行锁；&lt;br /&gt;
*# 如果其他线程按“非主键索引”字段进行查询，则“非主键索引”字段产生行锁；&lt;br /&gt;
*# 如果其他线程按“非索引”字段进行查询，则“非索引”字段产生表锁；&lt;br /&gt;
*# 如果索引值是枚举类型，mysql 也会进行表锁。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* InnoDB 中，使用“非主键索引”（辅助索引）一定会用到“主键索引”（聚簇索引）【“'''回表'''”】&lt;br /&gt;
&lt;br /&gt;
=== 读锁示例 ===&lt;br /&gt;
假设您要在表 child 中插入新行，并确保子行在表 parent 中具有父行。您的应用程序代码可以确保整个操作序列的引用完整性。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
首先，使用一致的读取来查询表 parent 并验证父行是否存在。您可以安全地将子行插入表 child 吗？&lt;br /&gt;
: 不可以，因为某些其他会话可能会在“SELECT”和“INSERT”之间的瞬间删除父行，而不会引起您注意。&lt;br /&gt;
&lt;br /&gt;
为避免此潜在问题，请使用“LOCK IN SHARE MODE”执行“SELECT”：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
“LOCK IN SHARE MODE”查询返回父级 'Jones' 后，您可以安全地将子记录添加到 CHILD 表中并提交事务。任何尝试获取 PARENT 表中适用行中的排他锁的事务都将等到您完成操作（即所有表中的数据处于一致状态）后再进行。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于另一个示例，请考虑表 CHILD_CODES 中的整数计数器字段，该字段用于向添加到表 CHILD 的每个子项分配唯一标识符。不要使用一致读取或共享模式读取来读取计数器的当前值，因为数据库的两个用户可能会看到该计数器的相同值，并且如果两个事务尝试使用以下方式添加行，则会发生重复键错误： CHILD 表具有相同的标识符。&lt;br /&gt;
: 在这里，“LOCK IN SHARE MODE”不是一个好的解决方案，因为如果两个用户同时读取计数器，则其中至少有一个在尝试更新计数器时会陷入死锁状态。&lt;br /&gt;
&lt;br /&gt;
要实现读取和递增计数器，请首先使用“FOR UPDATE”对计数器执行锁定读取，然后递增计数器。例如：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT counter_field FROM child_codes FOR UPDATE;&lt;br /&gt;
UPDATE child_codes SET counter_field = counter_field + 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
“SELECT ... FOR UPDATE”读取最新的可用数据，并在读取的每一行上设置排他锁。因此，它设置了与“对搜索到的 SQL 进行更新”所将在行上设置的相同的锁。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
前面的描述仅是“SELECT ... FOR UPDATE”工作方式的示例。在 MySQL 中，生成唯一标识符的特定任务实际上可以仅通过单次访问表来完成：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);&lt;br /&gt;
SELECT LAST_INSERT_ID();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
“SELECT”语句仅检索标识符信息（特定于当前连接）。它不访问任何表。&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=InnoDB%EF%BC%9AInnoDB_%E4%BA%8B%E5%8A%A1%E6%A8%A1%E5%9E%8B&amp;diff=6667</id>
		<title>InnoDB：InnoDB 事务模型</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=InnoDB%EF%BC%9AInnoDB_%E4%BA%8B%E5%8A%A1%E6%A8%A1%E5%9E%8B&amp;diff=6667"/>
		<updated>2024-01-18T14:19:41Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* “READ COMMITTED” */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:MySQL文档]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
在 InnoDB 事务模型中，目标是将 multi-versioning 数据库的最佳属性与传统的两阶段锁定【？】相结合。 InnoDB在行级别上执行锁定，并且默认情况下以 Oracle 风格将查询作为非锁定 consistent reads 运行。 InnoDB 中的锁信息以节省空间的方式存储，因此不需要锁升级。通常，允许几个用户锁定 InnoDB 表中的每一行或该行的任何随机子集，而不会导致 InnoDB 内存耗尽。&lt;br /&gt;
&lt;br /&gt;
== '''事务隔离级别''' ==&lt;br /&gt;
事务隔离是数据库处理的基础之一。隔离是缩写“ACID”中的“I”；隔离级别是一种设置，用于在多个事务同时进行更改和执行查询时微调性能与结果的可靠性，一致性和可重复性之间的平衡。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
InnoDB提供了 SQL：1992 标准描述的所有四个事务隔离级别：“'''READ UNCOMMITTED'''”，“'''READ COMMITTED'''”，“'''REPEATABLE READ'''”和“'''SERIALIZABLE'''”。 &lt;br /&gt;
* InnoDB 的默认隔离级别是“REPEATABLE READ”。&lt;br /&gt;
* 用户可以使用“'''SET TRANSACTION'''”语句更改单个会话或所有后续连接的隔离级别。要为所有连接设置服务器的默认隔离级别，请在命令行或选项文件中使用“'''--transaction-isolation'''”选项。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
InnoDB 使用不同的锁定策略支持此处描述的每个事务隔离级别。&lt;br /&gt;
: 您可以对“ACID”合规性很重要的关键数据进行操作，与默认“REPEATABLE READ”级别保持高度一致性。&lt;br /&gt;
: 或者，您可以使用“READ COMMITTED”甚至是“READ UNCOMMITTED”放宽一致性规则，例如在批量报告中，精确的一致性和可重复的结果不如最小化锁定开销重要。 &lt;br /&gt;
: “SERIALIZABLE”强制执行比“REPEATABLE READ”更为严格的规则，并且主要用于特殊情况下，例如 XA 事务以及对并发和死锁进行故障排除。&lt;br /&gt;
&lt;br /&gt;
=== “REPEATABLE READ” ===&lt;br /&gt;
这是 InnoDB 的默认隔离级别。'''同一事务中的 Consistent reads（一致性读）读取由第一次读取构建的 snapshot（快照）'''。&lt;br /&gt;
# 【非锁定读】这意味着，如果您在同一事务中发出几个简单的（非锁定）SELECT语句，则这些 SELECT 语句彼此之间也是一致的。&lt;br /&gt;
# 【锁定读、更新】对于锁定读取（带有“FOR UPDATE”或“LOCK IN SHARE MODE”的SELECT），“UPDATE”和“DELETE”语句，锁定取决于该语句是使用具有唯一搜索条件的唯一索引还是范围类型搜索条件。【？？】&lt;br /&gt;
## 对于具有唯一搜索条件的唯一索引，InnoDB 仅锁定找到的索引记录，而不锁定之前的间隙。&lt;br /&gt;
## 对于其他搜索条件，InnoDB 锁定扫描的索引范围，使用“gap locks”（间隙锁）或“next-key locks”（下一键锁）阻止其他会话插入该范围所覆盖的间隙。&lt;br /&gt;
&lt;br /&gt;
=== “READ COMMITTED” ===&lt;br /&gt;
'''即使在同一事务中，每个一致的读取都将设置并读取其自己的新快照'''。&lt;br /&gt;
# 【锁定读、更新】对于锁定读取（带有“FOR UPDATE”或“LOCK IN SHARE MODE”的SELECT），“UPDATE”和“DELETE”语句，InnoDB 仅锁定索引记录，而不锁定它们之间的间隙，因此允许在锁定记录旁边自由插入新记录。间隙锁定仅用于外键约束检查和重复键检查。&lt;br /&gt;
#* 由于禁用了间隙锁定，因此可能会产生幻影问题，因为其他会话可以在间隙中插入新行。&lt;br /&gt;
# “READ COMMITTED”隔离级别仅支持基于行的二进制日志记录。如果将“READ COMMITTED”与“binlog_format=MIXED”一起使用，则服务器将自动使用基于行的日志记录。【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用“READ COMMITTED”具有其他效果：&lt;br /&gt;
# 对于“UPDATE”和“DELETE”语句，InnoDB 仅对其更新或删除的行保持锁定。 MySQL 评估“WHERE”条件后，将释放不匹配行的记录锁。（这大大降低了死锁的可能性，但是仍然可以发生。）&lt;br /&gt;
# 对于“UPDATE”语句，如果某行已被锁定，则 InnoDB 执行“半一致”读取，将最新的提交版本返回给 MySQL，以便 MySQL 可以确定该行是否与“UPDATE”的“WHERE”条件匹配。如果该行匹配（必须更新），则 MySQL 再次读取该行，这一次 InnoDB 要么锁定它，要么 await 对其进行锁定。【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例 1：【？】&amp;lt;br/&amp;gt;&lt;br /&gt;
有如下表，'''表没有索引'''，因此搜索和索引扫描'''将隐藏的聚集索引用于记录锁定，而不是使用索引列'''。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;&lt;br /&gt;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);&lt;br /&gt;
COMMIT;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
假设一个会话使用以下语句执行“UPDATE”：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
# Session A&lt;br /&gt;
START TRANSACTION;&lt;br /&gt;
UPDATE t SET b = 5 WHERE b = 3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
还假设第二个会话通过在第一个会话的语句之后执行以下语句来执行“UPDATE”：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
# Session B&lt;br /&gt;
UPDATE t SET b = 4 WHERE b = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
当 InnoDB 执行每个“UPDATE”时，它首先为其读取的每一行获取一个排他锁，然后确定是否对其进行修改。如果 InnoDB 不修改该行，它将释放锁定。否则，InnoDB 保留锁，直到事务结束。这会影响事务处理，如下所示。&lt;br /&gt;
&lt;br /&gt;
# 使用默认的“REPEATABLE READ”隔离级别时：&lt;br /&gt;
#: 第一个“UPDATE”会在其读取的每一行上获得一个 x 锁，并且不会释放其中的任何一个：【！&amp;lt;span style=&amp;quot;color:Chocolate; font-weight:bold;&amp;quot;&amp;gt;因为没有使用索引，所以导致全表扫面，而又因为 RR 使用“临键锁”，所以实际导致“全表锁定”&amp;lt;span&amp;gt;】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); retain x-lock&lt;br /&gt;
x-lock(2,3); update(2,3) to (2,5); retain x-lock&lt;br /&gt;
x-lock(3,2); retain x-lock&lt;br /&gt;
x-lock(4,3); update(4,3) to (4,5); retain x-lock&lt;br /&gt;
x-lock(5,2); retain x-lock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 第二个“UPDATE”会在尝试获取任何锁时立即阻止（因为第一次更新已在所有行上保留了锁），并且直到第一个“UPDATE”提交或回滚后才继续进行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); block and wait for first UPDATE to commit or roll back&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 如果改为使用“READ COMMITTED”：&lt;br /&gt;
#: 则第一个“UPDATE”会在其读取的每一行上获取一个 x 锁，并释放其未修改的行的 x 锁：【！&amp;lt;span style=&amp;quot;color:Chocolate; font-weight:bold;&amp;quot;&amp;gt;因为没有使用索引，所以导致全表扫面，而又 RC 不使用“临键锁”（间隙锁），所以只会锁定有对应值的记录&amp;lt;span&amp;gt;】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); unlock(1,2)&lt;br /&gt;
x-lock(2,3); update(2,3) to (2,5); retain x-lock&lt;br /&gt;
x-lock(3,2); unlock(3,2)&lt;br /&gt;
x-lock(4,3); update(4,3) to (4,5); retain x-lock&lt;br /&gt;
x-lock(5,2); unlock(5,2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 对于第二个“UPDATE”，InnoDB 进行“半一致”读取，将它读取的每一行的最新提交版本返回给 MySQL，以便 MySQL 可以确定该行是否与“UPDATE”的“WHERE”条件匹配：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
x-lock(1,2); update(1,2) to (1,4); retain x-lock&lt;br /&gt;
x-lock(2,3); unlock(2,3)&lt;br /&gt;
x-lock(3,2); update(3,2) to (3,4); retain x-lock&lt;br /&gt;
x-lock(4,3); unlock(4,3)&lt;br /&gt;
x-lock(5,2); update(5,2) to (5,4); retain x-lock&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例 2：【？】&amp;lt;br/&amp;gt;&lt;br /&gt;
但是，如果“WHERE”条件'''包含索引列'''，并且 InnoDB 使用索引，则在获取和保留记录锁时'''仅考虑索引列'''。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t (a INT NOT NULL, b INT, c INT, INDEX (b)) ENGINE = InnoDB;&lt;br /&gt;
INSERT INTO t VALUES (1,2,3),(2,2,4);&lt;br /&gt;
COMMIT;&lt;br /&gt;
&lt;br /&gt;
# Session A&lt;br /&gt;
START TRANSACTION;&lt;br /&gt;
UPDATE t SET b = 3 WHERE b = 2 AND c = 3;&lt;br /&gt;
&lt;br /&gt;
# Session B&lt;br /&gt;
UPDATE t SET b = 4 WHERE b = 2 AND c = 4;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
在上面的示例中，第一个“UPDATE”在 b = 2 的每一行上获取并保留一个 x 锁。第二个“UPDATE”尝试获取同一记录上的 x 锁时将阻塞，因为它也使用在 b 列上定义的索引。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用“READ COMMITTED”隔离级别的效果与启用已弃用的“innodb_locks_unsafe_for_binlog”配置选项相同，但以下情况除外：&lt;br /&gt;
* 启用“innodb_locks_unsafe_for_binlog”是全局设置，会影响所有会话，而隔离级别可以针对所有会话全局设置，也可以针对每个会话单独设置。&lt;br /&gt;
* “innodb_locks_unsafe_for_binlog”只能在服务器启动时设置，而隔离级别可以在启动时设置或在运行时更改。&lt;br /&gt;
因此“READ COMMITTED”比“innodb_locks_unsafe_for_binlog”提供了更好，更灵活的控制。&lt;br /&gt;
&lt;br /&gt;
=== “READ UNCOMMITTED” ===&lt;br /&gt;
SELECT 语句以'''非锁定'''方式执行，但是可能会使用'''行的早期版本'''。因此，使用此隔离级别，此类读取不一致。这也称为 '''dirty read（脏读）'''。否则，此隔离级别的作用类似于“READ COMMITTED”。&lt;br /&gt;
&lt;br /&gt;
=== “SERIALIZABLE” ===&lt;br /&gt;
此级别类似于“REPEATABLE READ”，但是&lt;br /&gt;
# InnoDB 如果禁用了autocommit，则将所有普通 SELECT 语句隐式转换为“'''SELECT ... LOCK IN SHARE MODE'''”。&lt;br /&gt;
# 如果启用了autocommit，则 SELECT 是其自身的事务。&lt;br /&gt;
因此，它被认为是'''只读的'''，并且如果以一致的（非锁定）读取方式执行并且不需要阻塞其他事务就可以序列化。&lt;br /&gt;
*（如果其他事务已修改所选行，则要强制普通 SELECT 阻止，请禁用autocommit。）&lt;br /&gt;
&lt;br /&gt;
== 自动提交，提交和回滚 ==&lt;br /&gt;
在 InnoDB 中，所有用户活动都发生在事务内部。如果启用了 autocommit 模式，则'''每个 SQL 语句将自己形成一个事务'''。默认情况下，MySQL 为启用了 autocommit 的每个新连接启动会话，因此，如果每个 SQL 语句未返回错误，则 MySQL 都会在该 SQL 语句之后进行提交。如果一条语句返回错误，则提交或回滚行为取决于该错误。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# 启用了 autocommit 的会话可以通过以显式“START TRANSACTION”或“BEGIN”语句开始，并以“COMMIT”或“ROLLBACK”语句结束来执行'''多语句事务'''。【！】&lt;br /&gt;
# 如果在具有“SET autocommit = 0”的会话中禁用了 autocommit 模式，则该会话'''始终具有打开的事务'''。“COMMIT”或“ROLLBACK”语句结束当前事务，然后开始新的事务。【！】&lt;br /&gt;
#* 如果禁用了 autocommit 的会话在没有显式提交最终事务的情况下结束，则 MySQL 将回滚该事务。【！】&lt;br /&gt;
# 某些语句隐式结束事务，就像您在执行该语句之前已经完成“COMMIT”一样。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
“COMMIT”表示在当前事务中所做的更改将成为永久性的，并在其他会话中可见。另一方面，“ROLLBACK”语句会取消当前事务所做的所有修改。'''“COMMIT”和“ROLLBACK”都释放在当前事务期间设置的所有 InnoDB 锁'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 将 DML 操作与事务分组 ===&lt;br /&gt;
默认情况下，与 MySQL 服务器的连接从启用 autocommit 模式开始，此模式会在您执行时自动提交每个 SQL 语句。如果您有其他数据库系统的经验，则可能不熟悉这种操作模式，在标准实践中，发出一系列 DML 语句并将其提交或一起回滚。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
要使用'''多语句事务'''：&lt;br /&gt;
* 请使用 SQL 语句“SET autocommit = 0”关闭自动提交，并在适当时以“COMMIT”或“ROLLBACK”结束每个事务。&lt;br /&gt;
* 要保留自动提交功能，请以“START TRANSACTION”开始每个事务，并以“COMMIT”或“ROLLBACK”结束它。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：显示了两个事务。第一个被提交；第二个被回滚。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
shell&amp;gt; mysql test&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; CREATE TABLE customer (a INT, b CHAR (20), INDEX (a));&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; -- Do a transaction with autocommit turned on.&lt;br /&gt;
mysql&amp;gt; START TRANSACTION;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; INSERT INTO customer VALUES (10, 'Heikki');&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; COMMIT;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; -- Do another transaction with autocommit turned off.&lt;br /&gt;
mysql&amp;gt; SET autocommit=0;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; INSERT INTO customer VALUES (15, 'John');&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; INSERT INTO customer VALUES (20, 'Paul');&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; DELETE FROM customer WHERE b = 'Heikki';&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; -- Now we undo those last 2 inserts and the delete.&lt;br /&gt;
mysql&amp;gt; ROLLBACK;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
mysql&amp;gt; SELECT * FROM customer;&lt;br /&gt;
+------+--------+&lt;br /&gt;
| a    | b      |&lt;br /&gt;
+------+--------+&lt;br /&gt;
|   10 | Heikki |&lt;br /&gt;
+------+--------+&lt;br /&gt;
1 row in set (0.00 sec)&lt;br /&gt;
mysql&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Client 端语言的事务 ===&lt;br /&gt;
在诸如 PHP，Perl DBI，JDBC，ODBC 或 MySQL 的标准 C 调用接口之类的 API 中，您可以像其他任何 SQL 语句（如“SELECT”或“INSERT”）一样，将事务控制语句（如“COMMIT”）作为字符串发送到 MySQL 服务器。&lt;br /&gt;
* 一些 API 还提供了单独的特殊事务提交和回滚功能或方法。&lt;br /&gt;
&lt;br /&gt;
== 一致的'''非锁定读取''' ==&lt;br /&gt;
consistent read（一致性读取）表示 InnoDB 使用'''多版本控制'''在某个时间点向查询呈现数据库'''快照'''：&lt;br /&gt;
&lt;br /&gt;
: '''该查询将看到在该时间点之前提交的事务所做的更改，而看不到以后或未提交的事务所做的更改'''。【该规则的例外是查询可以看到同一事务中较早的语句所做的更改。】&lt;br /&gt;
&lt;br /&gt;
此异常导致以下异常：如果更新表中的某些行，则“SELECT”将看到已更新行的最新版本，但也可能会看到任何行的旧版本。如果其他会话同时更新同一张表，则异常意味着您可能会以数据库中不存在的状态查看该表。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''隔离级别与一致性读取：'''&lt;br /&gt;
# 如果事务隔离级别为“'''REPEATABLE READ'''”（默认级别），则'''同一事务中的所有一致读取将读取由该事务中的第一个此类读取构建的快照'''。&lt;br /&gt;
#* 您可以通过提交当前事务并在此之后发出新查询来获取查询的更新快照。&lt;br /&gt;
# 使用“'''READ COMMITTED'''”隔离级别，则'''事务中的每个一致读取都会设置并读取其自己的新快照'''。&lt;br /&gt;
一致读取是 InnoDB 处理“READ COMMITTED”和“REPEATABLE READ”隔离级别的“SELECT”语句的默认模式。一致读取'''不会在它访问的表上设置任何锁'''，因此其他会话可以自由地在对表执行一致读取的同时修改这些表。&lt;br /&gt;
: 假设您以默认的“REPEATABLE READ”隔离级别运行。当您发出一致的读取（即普通的“SELECT”语句）时，InnoDB 为您的事务提供一个时间点，根据该时间点您的查询可以看到数据库。如果另一个事务删除了一行并在分配了时间点后提交，则看不到该行已被删除。插入和更新的处理方式相似。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''NOTE：'''&amp;lt;/big&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
数据库状态的快照适用于事务中的“SELECT”条语句，而'''不必适用于 DML 语句'''。如果您插入或修改某些行，然后提交该事务，则从另一个并发“REPEATABLE READ”事务发出的“DELETE”或“UPDATE”语句可能会影响那些刚刚提交的行，即使会话无法查询它们。如果某个事务确实更新或删除了另一个事务提交的行，则这些更改对于当前事务而言确实可见。&lt;br /&gt;
: 例如，您可能会遇到以下情况：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz';&lt;br /&gt;
-- Returns 0: no rows match.&lt;br /&gt;
DELETE FROM t1 WHERE c1 = 'xyz';&lt;br /&gt;
-- Deletes several rows recently committed by other transaction.&lt;br /&gt;
&lt;br /&gt;
SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc';&lt;br /&gt;
-- Returns 0: no rows match.&lt;br /&gt;
UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc';&lt;br /&gt;
-- Affects 10 rows: another txn just committed 10 rows with 'abc' values.&lt;br /&gt;
SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba';&lt;br /&gt;
-- Returns 10: this txn can now see the rows it just updated.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
您可以通过提交事务，然后执行另一个“SELECT”或使用一致的快照开始事务（“START TRANSACTION WITH CONSISTENT SNAPSHOT”，即使用“START TRANSACTION”等语句开始新事务）来推进时间。这称为&amp;lt;big&amp;gt;'''多版本并发控制'''&amp;lt;/big&amp;gt;。【？？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&amp;lt;br/&amp;gt;&lt;br /&gt;
会话 A 仅在“ B 提交了插入，并且 A 也提交了”时，才看到 B 插入的行，因此时间点比 B 的提交提前了。&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
           Session A              Session B&lt;br /&gt;
&lt;br /&gt;
           SET autocommit=0;      SET autocommit=0;&lt;br /&gt;
time&lt;br /&gt;
|          SELECT * FROM t;&lt;br /&gt;
|          empty set&lt;br /&gt;
|                           INSERT INTO t VALUES (1, 2);&lt;br /&gt;
|&lt;br /&gt;
v          SELECT * FROM t;&lt;br /&gt;
           empty set&lt;br /&gt;
                                COMMIT;&lt;br /&gt;
&lt;br /&gt;
          SELECT * FROM t;&lt;br /&gt;
           empty set&lt;br /&gt;
&lt;br /&gt;
           COMMIT;&lt;br /&gt;
&lt;br /&gt;
          SELECT * FROM t;&lt;br /&gt;
          ---------------------&lt;br /&gt;
          |    1    |    2    |&lt;br /&gt;
          ---------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果要'''查看数据库的“最新鲜”状态'''，请使用“'''READ COMMITTED'''”隔离级别或 locking read（&amp;lt;big&amp;gt;'''锁定读取'''&amp;lt;/big&amp;gt;）：&lt;br /&gt;
'''&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t FOR SHARE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
# 使用“READ COMMITTED”隔离级别，事务中的每个一致读取都会设置并读取其自己的新快照。&lt;br /&gt;
# 使用“LOCK IN SHARE MODE”时，将发生锁定读取：“SELECT”阻塞，直到包含最新行的事务结束。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''一致读取不适用于某些 DDL 语句'''：&lt;br /&gt;
* 一致读取无法在“DROP TABLE”上进行，因为 MySQL 无法使用已删除的表，而 InnoDB 会破坏该表。&lt;br /&gt;
* 一致读取在“ALTER TABLE”上不起作用，因为该语句将创建原始表的临时副本，并在构建该临时副本时删除该原始表。当您在事务内重新发出一致的读取时，新表中的行不可见，因为在获取事务快照时这些行不存在。在这种情况下，事务返回错误：“ER_TABLE_DEF_CHANGED”（“table 定义已更改，请重试事务”）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于未指定“FOR UPDATE”或“LOCK IN SHARE MODE”的“INSERT INTO ... SELECT”、“UPDATE ... (SELECT)”和“CREATE TABLE ... SELECT”之类的“select”子句，读取的类型有所不同：&lt;br /&gt;
* 默认情况下，InnoDB 使用更强的锁定，而 SELECT 部分的作用类似于“READ COMMITTED”，即使在同一事务中，每个一致的读取也会设置并读取自己的新快照。&lt;br /&gt;
* 要在这种情况下使用一致的读取，请启用“innodb_locks_unsafe_for_binlog”选项，并将事务的隔离级别设置为“READ UNCOMMITTED”，“READ COMMITTED”或“REPEATABLE READ”（即“SERIALIZABLE”以外的任何值）。在这种情况下，'''不会对从所选表读取的行设置锁定'''。&lt;br /&gt;
&lt;br /&gt;
== '''锁定读取''' ==&lt;br /&gt;
如果查询数据，然后在同一事务中插入或更新相关数据，则常规“SELECT”语句不能提供足够的保护。其他事务可以更新或删除刚查询的相同行。 &lt;br /&gt;
&lt;br /&gt;
InnoDB 支持两种提供额外安全性的locking reads（锁定读取）：&lt;br /&gt;
# “'''SELECT ... LOCK IN SHARE MODE'''”【！！！】&lt;br /&gt;
#: 在读取的任何行上设置'''共享模式锁定'''。'''其他会话可以读取行，但是在事务提交之前不能修改它们'''。如果这些行中的任何一个被尚未提交的另一个事务更改，则查询将 await 直到该事务结束，然后使用最新值。&lt;br /&gt;
# “'''SELECT ... FOR UPDATE'''”【！！！这个我常用】&lt;br /&gt;
#: 对于索引记录，搜索遇到的情况，'''锁定行和任何关联的索引条目'''，就像您为这些行发出“UPDATE”语句一样。&lt;br /&gt;
#* &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
禁止其他事务更新这些行，执行“SELECT ... LOCK IN SHARE MODE”或读取某些事务隔离级别的数据。一致的读取将忽略读取视图中存在的记录上设置的任何锁定。（记录的旧版本无法锁定；可以通过在记录的内存副本上应用undo logs来重构它们。）【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE：&lt;br /&gt;
* 提交或回滚事务时，将释放由“LOCK IN SHARE MODE”和“FOR UPDATE”查询设置的所有锁。&lt;br /&gt;
* '''只有在禁用自动提交时'''（通过以“START TRANSACTION”开始事务或将“autocommit”设置为 0），'''才可以进行锁定读取'''。&lt;br /&gt;
* 除非在子查询中也指定了锁定读取子句，否则'''外部语句中的锁定读取子句不会锁定嵌套子查询中表的行'''。&lt;br /&gt;
*: 例如，以下语句不会锁定表 t2 中的行：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2) FOR UPDATE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: 要锁定表 t2 中的行，请向子查询添加一个锁定 read 子句：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2 FOR UPDATE) FOR UPDATE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 锁定读：'''“行锁”与“表锁”''' ===&lt;br /&gt;
InnoDB 行锁是通过给索引上的索引项加锁来实现的，'''只有通过索引条件检索数据，InnoDB 才使用行级锁，否则，InnoDB 将使用表锁'''。【！！！】&lt;br /&gt;
* 即便在条件中使用了索引字段，但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的，如果 MySQL 认为全表扫描效率更高（比如对一些很小的表）就不会使用索引，这种情况下 InnoDB 将使用表锁，而不是行锁。&lt;br /&gt;
*: 因此，在分析锁冲突时，别忘了检查 SQL 的执行计划，以确认是否真正使用了索引。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
锁定读的所情况总结：&lt;br /&gt;
# “无锁”：根据“主键”、“非主键索引”、“主键 + 非主键索引”、“主键 + 非索引”进行查询，但未查询到数据时。&lt;br /&gt;
# “行锁”：根据“主键”、“非主键索引”、“主键 + 非主键索引”进行查询，并查询到数据时。&lt;br /&gt;
# “'''表锁'''”：&lt;br /&gt;
## 只根据“非索引”字段进行查询时（无论是否查询到数据）；【'''未使用索引'''】&lt;br /&gt;
## 只根据“主键”进行查询，条件为“&amp;lt;&amp;gt;”、“like”时（无论是否查询到数据）；【'''结果集为范围'''】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 根据“主键 + 非索引”进行查询，并且查询到数据时：【？？？】&lt;br /&gt;
*# 如果其他线程按“主键”字段进行查询，则“主键”字段产生行锁；&lt;br /&gt;
*# 如果其他线程按“非主键索引”字段进行查询，则“非主键索引”字段产生行锁；&lt;br /&gt;
*# 如果其他线程按“非索引”字段进行查询，则“非索引”字段产生表锁；&lt;br /&gt;
*# 如果索引值是枚举类型，mysql 也会进行表锁。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* InnoDB 中，使用“非主键索引”（辅助索引）一定会用到“主键索引”（聚簇索引）【“'''回表'''”】&lt;br /&gt;
&lt;br /&gt;
=== 读锁示例 ===&lt;br /&gt;
假设您要在表 child 中插入新行，并确保子行在表 parent 中具有父行。您的应用程序代码可以确保整个操作序列的引用完整性。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
首先，使用一致的读取来查询表 parent 并验证父行是否存在。您可以安全地将子行插入表 child 吗？&lt;br /&gt;
: 不可以，因为某些其他会话可能会在“SELECT”和“INSERT”之间的瞬间删除父行，而不会引起您注意。&lt;br /&gt;
&lt;br /&gt;
为避免此潜在问题，请使用“LOCK IN SHARE MODE”执行“SELECT”：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
“LOCK IN SHARE MODE”查询返回父级 'Jones' 后，您可以安全地将子记录添加到 CHILD 表中并提交事务。任何尝试获取 PARENT 表中适用行中的排他锁的事务都将等到您完成操作（即所有表中的数据处于一致状态）后再进行。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于另一个示例，请考虑表 CHILD_CODES 中的整数计数器字段，该字段用于向添加到表 CHILD 的每个子项分配唯一标识符。不要使用一致读取或共享模式读取来读取计数器的当前值，因为数据库的两个用户可能会看到该计数器的相同值，并且如果两个事务尝试使用以下方式添加行，则会发生重复键错误： CHILD 表具有相同的标识符。&lt;br /&gt;
: 在这里，“LOCK IN SHARE MODE”不是一个好的解决方案，因为如果两个用户同时读取计数器，则其中至少有一个在尝试更新计数器时会陷入死锁状态。&lt;br /&gt;
&lt;br /&gt;
要实现读取和递增计数器，请首先使用“FOR UPDATE”对计数器执行锁定读取，然后递增计数器。例如：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT counter_field FROM child_codes FOR UPDATE;&lt;br /&gt;
UPDATE child_codes SET counter_field = counter_field + 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
“SELECT ... FOR UPDATE”读取最新的可用数据，并在读取的每一行上设置排他锁。因此，它设置了与“对搜索到的 SQL 进行更新”所将在行上设置的相同的锁。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
前面的描述仅是“SELECT ... FOR UPDATE”工作方式的示例。在 MySQL 中，生成唯一标识符的特定任务实际上可以仅通过单次访问表来完成：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);&lt;br /&gt;
SELECT LAST_INSERT_ID();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
“SELECT”语句仅检索标识符信息（特定于当前连接）。它不访问任何表。&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6666</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6666"/>
		<updated>2024-01-14T17:06:11Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 解除 UWP 应用的本地回环限制 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行 —— 实际上是 MicrosoftStore 被限制使用“回环地址”，所以不能通过代理访问，见：[[#解除 UWP 应用的本地回环限制]]&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是是系统可识别的一个文件，作用是存储'''用户对文件夹的个性设置'''（用户更换文件夹图标等等都会生成 desktop.ini）。&lt;br /&gt;
 &lt;br /&gt;
 在一些系统文件夹（如，桌面、文档、下载、图片、音乐、视频等）中广泛存在。&lt;br /&gt;
&lt;br /&gt;
在移动这些系统文件夹位置的时候，可能会丢失“desktop.ini”文件，就会造成某些配置的丢失 —— 如，移动或重新制定“下载”文件夹路径后，显示为“Downloads”（而非随系统语言而显示如“下载”等），且默认图标等也会发生变化。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
修复“desktop.ini”文件，步骤：&lt;br /&gt;
# 创建“desktop.ini”文件（从其他电脑/用户路径中拷贝也行）&lt;br /&gt;
#* 桌面：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21769&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 文档：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21770&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-112&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-235&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 下载：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-184&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 图片：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-113&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 音乐：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-108&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-237&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 视频：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21791&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12690&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-189&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-238&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 修改“desktop.ini”文件的'''属性'''：&lt;br /&gt;
#: 在文件所在位置打开 Terminal（&amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; + 右键），并运行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
# 增加“只读文件”、“系统文件”、“隐藏文件”属性&lt;br /&gt;
attrib +R +S +H &amp;quot;desktop.ini&amp;quot; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 重启 explorer。&lt;br /&gt;
&lt;br /&gt;
== 解除 UWP 应用的本地回环限制 ==&lt;br /&gt;
 UWP 应用在默认的情况下（称为 '''AppContainer''' 的'''虚拟沙箱环境'''中），无法使用“'''本地回环地址（Loopback）'''”，如：localhost。&lt;br /&gt;
 &lt;br /&gt;
 在开发调试、正向代理等情况下，就必须解除该限制。&lt;br /&gt;
&lt;br /&gt;
三种方式：&lt;br /&gt;
# '''官方限制解除工具'''：CheckNetIsolation.exe&amp;lt;ref&amp;gt;参考：[https://learn.microsoft.com/en-us/previous-versions/windows/apps/hh780593(v=win.10)?redirectedfrom=MSDN How to enable loopback and troubleshoot network isolation (Windows Runtime apps)]&amp;lt;/ref&amp;gt;&lt;br /&gt;
#: 位置：&amp;lt;code&amp;gt;C:/Windows/System32/CheckNetIsolation.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
#: 用法：&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot; inline&amp;gt;&lt;br /&gt;
CheckNetIsolation.exe LoopbackExempt [operation] [-n=] [-p=]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: [[File:Loopback 限制解除工具“CheckNetIsolation”.png|600px]]&lt;br /&gt;
# 通过 '''Fiddler''' 的 '''WinConfig''' 设置解除回环限制。&lt;br /&gt;
#* 也可以使用其独立工具：'''[https://telerik-fiddler.s3.amazonaws.com/fiddler/addons/enableloopbackutility.exe 下载 enableloopbackutility.exe]'''&lt;br /&gt;
# 通过开源项目 '''Loopback Exemption Manager（网络回环管理器）'''：和 enableloopbackutility 作用一样&lt;br /&gt;
## '''[https://github.com/tiagonmas/Windows-Loopback-Exemption-Manager?tab=readme-ov-file tiagonmas/Windows-Loopback-Exemption-Manager]'''&lt;br /&gt;
## '''[https://github.com/Richasy/LoopbackManager.Desktop?tab=readme-ov-file Richasy/LoopbackManager.Desktop]'''：（Windows-Loopback-Exemption-Manager 的 Windows 11 版本）&lt;br /&gt;
##* 可以通过链接 &amp;lt;code&amp;gt;ms-windows-store://pdp/?productid=9NTJ6CX698CL&amp;lt;/code&amp;gt;（浏览器打开）从 Microsoft Store 获取。&lt;br /&gt;
&lt;br /&gt;
 要在使用代理的情况下使用“Microsoft Store”、“Windows 聚焦”等内容，就解除“Microsoft Store”（Microsoft.WindowsStore_8wekyb3d8bbwe）、“Microsoft 内容”（Microsoft.WindowsContentDeliveryManager_cw5n1h2txyewy）两项。&amp;lt;ref&amp;gt;参考：[https://github.com/2dust/v2rayN/issues/1083 开启http代理或配置pac后导致win10 MICROSOFT STORE无法联网]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6665</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6665"/>
		<updated>2024-01-14T17:01:42Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 解除 UWP 应用的本地回环限制 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行 —— 实际上是 MicrosoftStore 被限制使用“回环地址”，所以不能通过代理访问，见：[[#解除 UWP 应用的本地回环限制]]&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是是系统可识别的一个文件，作用是存储'''用户对文件夹的个性设置'''（用户更换文件夹图标等等都会生成 desktop.ini）。&lt;br /&gt;
 &lt;br /&gt;
 在一些系统文件夹（如，桌面、文档、下载、图片、音乐、视频等）中广泛存在。&lt;br /&gt;
&lt;br /&gt;
在移动这些系统文件夹位置的时候，可能会丢失“desktop.ini”文件，就会造成某些配置的丢失 —— 如，移动或重新制定“下载”文件夹路径后，显示为“Downloads”（而非随系统语言而显示如“下载”等），且默认图标等也会发生变化。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
修复“desktop.ini”文件，步骤：&lt;br /&gt;
# 创建“desktop.ini”文件（从其他电脑/用户路径中拷贝也行）&lt;br /&gt;
#* 桌面：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21769&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 文档：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21770&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-112&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-235&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 下载：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-184&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 图片：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-113&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 音乐：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-108&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-237&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 视频：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21791&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12690&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-189&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-238&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 修改“desktop.ini”文件的'''属性'''：&lt;br /&gt;
#: 在文件所在位置打开 Terminal（&amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; + 右键），并运行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
# 增加“只读文件”、“系统文件”、“隐藏文件”属性&lt;br /&gt;
attrib +R +S +H &amp;quot;desktop.ini&amp;quot; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 重启 explorer。&lt;br /&gt;
&lt;br /&gt;
== 解除 UWP 应用的本地回环限制 ==&lt;br /&gt;
 UWP 应用在默认的情况下（称为 '''AppContainer''' 的'''虚拟沙箱环境'''中），无法使用“'''本地回环地址（Loopback）'''”，如：localhost。&lt;br /&gt;
 &lt;br /&gt;
 在开发调试、正向代理等情况下，就必须解除该限制。&lt;br /&gt;
&lt;br /&gt;
三种方式：&lt;br /&gt;
# '''官方限制解除工具'''：CheckNetIsolation.exe&amp;lt;ref&amp;gt;参考：[https://learn.microsoft.com/en-us/previous-versions/windows/apps/hh780593(v=win.10)?redirectedfrom=MSDN How to enable loopback and troubleshoot network isolation (Windows Runtime apps)]&amp;lt;/ref&amp;gt;&lt;br /&gt;
#: 位置：&amp;lt;code&amp;gt;C:/Windows/System32/CheckNetIsolation.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
#: 用法：&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot; inline&amp;gt;&lt;br /&gt;
CheckNetIsolation.exe LoopbackExempt [operation] [-n=] [-p=]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: [[File:Loopback 限制解除工具“CheckNetIsolation”.png|600px]]&lt;br /&gt;
# 通过 '''Fiddler''' 的 '''WinConfig''' 设置解除回环限制。&lt;br /&gt;
#* 也可以使用其独立工具：'''[https://telerik-fiddler.s3.amazonaws.com/fiddler/addons/enableloopbackutility.exe 下载 enableloopbackutility.exe]'''&lt;br /&gt;
# 通过开源项目 '''Loopback Exemption Manager（网络回环管理器）'''：和 enableloopbackutility 作用一样&lt;br /&gt;
## '''[https://github.com/tiagonmas/Windows-Loopback-Exemption-Manager?tab=readme-ov-file tiagonmas/Windows-Loopback-Exemption-Manager]'''&lt;br /&gt;
## '''[https://github.com/Richasy/LoopbackManager.Desktop?tab=readme-ov-file Richasy/LoopbackManager.Desktop]'''：（Windows-Loopback-Exemption-Manager 的 Windows 11 版本）&lt;br /&gt;
##* 可以通过链接 &amp;lt;code&amp;gt;ms-windows-store://pdp/?productid=9NTJ6CX698CL&amp;lt;/code&amp;gt;（浏览器打开）从 Microsoft Store 获取。&lt;br /&gt;
&lt;br /&gt;
 要在使用代理的情况下使用“Microsoft Store”、“Windows 聚焦”等内容，就解除“Microsoft Store”（Microsoft.WindowsStore_8wekyb3d8bbwe）、“Microsoft 内容”（Microsoft.WindowsContentDeliveryManager_cw5n1h2txyewy）两项。&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Loopback_%E9%99%90%E5%88%B6%E8%A7%A3%E9%99%A4%E5%B7%A5%E5%85%B7%E2%80%9CCheckNetIsolation%E2%80%9D.png&amp;diff=6664</id>
		<title>文件:Loopback 限制解除工具“CheckNetIsolation”.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Loopback_%E9%99%90%E5%88%B6%E8%A7%A3%E9%99%A4%E5%B7%A5%E5%85%B7%E2%80%9CCheckNetIsolation%E2%80%9D.png&amp;diff=6664"/>
		<updated>2024-01-14T16:27:27Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6663</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6663"/>
		<updated>2024-01-14T16:11:41Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* MicrosoftStore下载很慢 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行 —— 实际上是 MicrosoftStore 被限制使用“回环地址”，所以不能通过代理访问，见：[[#解除 UWP 应用的本地回环限制]]&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是是系统可识别的一个文件，作用是存储'''用户对文件夹的个性设置'''（用户更换文件夹图标等等都会生成 desktop.ini）。&lt;br /&gt;
 &lt;br /&gt;
 在一些系统文件夹（如，桌面、文档、下载、图片、音乐、视频等）中广泛存在。&lt;br /&gt;
&lt;br /&gt;
在移动这些系统文件夹位置的时候，可能会丢失“desktop.ini”文件，就会造成某些配置的丢失 —— 如，移动或重新制定“下载”文件夹路径后，显示为“Downloads”（而非随系统语言而显示如“下载”等），且默认图标等也会发生变化。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
修复“desktop.ini”文件，步骤：&lt;br /&gt;
# 创建“desktop.ini”文件（从其他电脑/用户路径中拷贝也行）&lt;br /&gt;
#* 桌面：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21769&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 文档：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21770&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-112&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-235&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 下载：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-184&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 图片：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-113&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 音乐：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-108&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-237&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 视频：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21791&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12690&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-189&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-238&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 修改“desktop.ini”文件的'''属性'''：&lt;br /&gt;
#: 在文件所在位置打开 Terminal（&amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; + 右键），并运行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
# 增加“只读文件”、“系统文件”、“隐藏文件”属性&lt;br /&gt;
attrib +R +S +H &amp;quot;desktop.ini&amp;quot; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 重启 explorer。&lt;br /&gt;
&lt;br /&gt;
== 解除 UWP 应用的本地回环限制 ==&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6662</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6662"/>
		<updated>2024-01-14T16:09:34Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 关于“desktop.ini”文件 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是是系统可识别的一个文件，作用是存储'''用户对文件夹的个性设置'''（用户更换文件夹图标等等都会生成 desktop.ini）。&lt;br /&gt;
 &lt;br /&gt;
 在一些系统文件夹（如，桌面、文档、下载、图片、音乐、视频等）中广泛存在。&lt;br /&gt;
&lt;br /&gt;
在移动这些系统文件夹位置的时候，可能会丢失“desktop.ini”文件，就会造成某些配置的丢失 —— 如，移动或重新制定“下载”文件夹路径后，显示为“Downloads”（而非随系统语言而显示如“下载”等），且默认图标等也会发生变化。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
修复“desktop.ini”文件，步骤：&lt;br /&gt;
# 创建“desktop.ini”文件（从其他电脑/用户路径中拷贝也行）&lt;br /&gt;
#* 桌面：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21769&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 文档：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21770&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-112&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-235&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 下载：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-184&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 图片：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-113&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 音乐：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-108&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-237&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 视频：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21791&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12690&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-189&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-238&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 修改“desktop.ini”文件的'''属性'''：&lt;br /&gt;
#: 在文件所在位置打开 Terminal（&amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; + 右键），并运行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
# 增加“只读文件”、“系统文件”、“隐藏文件”属性&lt;br /&gt;
attrib +R +S +H &amp;quot;desktop.ini&amp;quot; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 重启 explorer。&lt;br /&gt;
&lt;br /&gt;
== 解除 UWP 应用的本地回环限制 ==&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6661</id>
		<title>FAQ:Software</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6661"/>
		<updated>2023-12-28T17:20:41Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* OneDrive使用 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Software]]&lt;br /&gt;
&lt;br /&gt;
== office官方卸载工具 ==&lt;br /&gt;
卸载office官方工具：[https://support.microsoft.com/en-us/office/uninstall-office-from-a-pc-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8 Uninstall Microsoft Office]&lt;br /&gt;
&lt;br /&gt;
== 卸载Visio密钥 ==&lt;br /&gt;
安装Visio之后，填入了密钥之后无法激活，想要修改密钥但发现界面没有修改框，所以只有向其他办法：&lt;br /&gt;
# regedit：开始以为使用的key都保存在注册表中，找了一圈并没有找到&lt;br /&gt;
# ？命令行修改，类似于之前查看Windows激活信息的命令&lt;br /&gt;
&lt;br /&gt;
=== 查看许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /dstatus&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
PRODUCT ID: 00341-31872-32451-AA593&lt;br /&gt;
SKU ID: 2dfe2075-2d04-4e43-816a-eb60bbb77574&lt;br /&gt;
LICENSE NAME: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
LICENSE DESCRIPTION: Office 16, RETAIL channel&lt;br /&gt;
BETA EXPIRATION: 1601/1/1&lt;br /&gt;
LICENSE STATUS:  ---OOB_GRACE---&lt;br /&gt;
ERROR CODE: 0x4004F00C&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the application is running within the valid grace period.&lt;br /&gt;
REMAINING GRACE: 29 days  (43147 minute(s) before expiring)&lt;br /&gt;
Last 5 characters of installed product key: DPFJH&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 安装的产品密钥： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /inpkey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 刷新许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /rearm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 卸载已安装的产品密钥： ===&lt;br /&gt;
* “unpkey”后的内容为密钥的最后5位数&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
&amp;lt;Product key uninstall successful&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 找不到对应的unpkey时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:AA593&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
&amp;lt;Product key not found&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# cmd未使用管理员权限时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
ERROR CODE: 0xC004F025&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the action requires administrator privilege.&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== notepad++ 自动保存位置 ==&lt;br /&gt;
notepad++ 会自动定期保存文件，所以没有手动保存为文件的内容也能够在关闭notepad++的下一次自动显示；&lt;br /&gt;
&lt;br /&gt;
如果关闭notepad++重新打开之后，上次没有手动保存的内容没有显示也不用慌，可以在'''&amp;quot;C:\Users\eijux\AppData\Roaming\Notepad++\backup&amp;quot;'''下自动定期保存的文件中找到。&lt;br /&gt;
&lt;br /&gt;
== 删除多余 Hyper-V Virtual Ethernet Adapter ==&lt;br /&gt;
在使用VBox的过程中，每次遇到更新、重装，都会导致多出虚拟网卡适配器：&lt;br /&gt;
:[[File:多余的虚拟网卡适配器.png|600px]]&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;s&amp;gt;方法一：&lt;br /&gt;
#: 在系统设置网络连接部分又不能直接删除，所以找到了一个从注册表删除的方法：&amp;lt;br/&amp;gt;&lt;br /&gt;
#: 在“'''计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ROOT\VMS_MP'''”中找到多余的项删除即可：&lt;br /&gt;
#: [[File:删除多余虚拟网卡适配器.png|600px]]&lt;br /&gt;
#: 【好像不求好使，以前是在注册表删除的，好像不是这】&amp;lt;/s&amp;gt;&lt;br /&gt;
# 方法二：&lt;br /&gt;
#: 在适配器列表（控制面板-&amp;gt;网络和共享中心-&amp;gt;更改适配器设置），右键“属性”，选择“配置”，到“驱动程序”页，选择“卸载设备”即可。&lt;br /&gt;
&lt;br /&gt;
== 安装“Twomon SE”后托盘区图标间隙变大 ==&lt;br /&gt;
由于想把 iPad 当作 Windows 的拓展屏幕使用，比较多个软件之后，购买了 Twomon SE，但在安装 PC 端之后，突然发现托盘区的图标间隙变得很大很大：&lt;br /&gt;
: [[File:Windows托盘区图标间隙.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
强迫症不能忍，能够确定是 Twomon SE 安装后的问题，查了一些资料，确定如下：&lt;br /&gt;
# 托盘区图标间隙变大，是因为系统认定当前在使用触摸式键盘。&lt;br /&gt;
#* “在触摸模式下，Windows 会在系统托盘（和其他UI）上留出空间，以便减少误点击图标的情况。”&lt;br /&gt;
# 系统托盘图标的间距，不受任何注册表项控制，它内置于程序中，不能更改。&lt;br /&gt;
#*“由explorer.exe应用程序中的编码控制。它是内部编码的，不依赖也不参考任何外部设置、控制或数据值来确定间距。改变它的唯一方法是反编译explorer.exe程序并重新编程文件。考虑到它是一个二进制文件，如果不访问源代码，这将是非常困难或不可能做到的。”&lt;br /&gt;
# 触摸屏设备，是“设备管理器 -&amp;gt; 人体学输入设备 -&amp;gt; 符合 HID 标准的触摸屏”（带 Touch Screen 或者触摸字样的设备）。&lt;br /&gt;
#* 通过禁用该设备可以使托盘区图标间隙恢复，但是，触摸设备也不能使用。（此处用的 iPad 就只能用作“显示屏”而不能用作“触摸屏”）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通过测试，可以把上述设备理器中的项“先禁用在启用”，使托盘区图标间隙恢复，且触摸正常使用，重启也没出现问题（可能使快速启动，没完全重启），算是曲线救国了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''参考：'''&lt;br /&gt;
# [https://answers.microsoft.com/zh-hans/windows/forum/all/%E4%BB%BB%E5%8A%A1%E6%A0%8F%E9%80%9A%E7%9F%A5/a4645ec6-343d-47c1-86cd-732a7536dac4 Microsoft Community：任务栏通知区域（托盘）图标间距变大]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/all/system-tray-icon-spacing-in-windows-10/6ab6e0dd-fe13-48e7-8eeb-c0d12abee6f3 Microsoft Community：System tray icon spacing in WIndows 10]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/tray-icons-reduce-spacing/93991e6b-5c53-4df5-af4e-3bdf3fde17fe Microsoft Community：Tray icons reduce spacing]&lt;br /&gt;
&lt;br /&gt;
== OpenVPN 问题 ==&lt;br /&gt;
 OpenVPN GUI 下载地址： '''https://openvpn.net/community-downloads/'''&lt;br /&gt;
&lt;br /&gt;
=== 设置密码自动填充 ===&lt;br /&gt;
使用 OpenVPN 连接时，每个连接第一次使用都需要输入用户名密码：&lt;br /&gt;
# 在配置文件“xxx.ovpn”的同级目录，添加“auth.txt”文件：第一行为用户，第二行为密码。&lt;br /&gt;
# 在配置文件“xxx.ovpn”中编辑：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
auth-user-pass auth.txt&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如此，不再需要手动填充用户密码信息。&lt;br /&gt;
&lt;br /&gt;
=== 未启动“OpenVPNServiceInteractive” ===&lt;br /&gt;
启动 OpenVPN GUI 时，出现如下提示：&lt;br /&gt;
: [[File:OpenVPN：未启动OpenVPNServiceInteractive.png|400px]]&lt;br /&gt;
&lt;br /&gt;
在 Windows 服务中，启动“'''OpenVPN Interactive Service'''”服务即可。&lt;br /&gt;
&lt;br /&gt;
== Vultr 验证页面 ==&lt;br /&gt;
打开 Vultr 登录页面，总是遇到如下页面，并不能成功跳转：&lt;br /&gt;
: [[File:Vultr：验证页面.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*【2021/11/24 19:23:13】试试不用代理打开，好像能成功。&lt;br /&gt;
&lt;br /&gt;
== Windows更新iTunes、iCloud失败 ==&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows更新iTunes、iCloud失败.png|400px]]&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 卸载该软件（iTunes/iCloud）；&lt;br /&gt;
# 卸载Apple相关的安装内容；&lt;br /&gt;
#* 包括：“Apple Mobile Device Surpport”、“Apple Software Update”、“Apple 应用程序支持(64位)”、“Apple 应用程序支持(32位)”、“Bonjour”；&lt;br /&gt;
# 重新执行安装程序；&lt;br /&gt;
&lt;br /&gt;
=== 安装iCloud时提示“您的电脑缺少媒体功能。请从Microsoft网站下载Media Feature Pack/Windows并安装，然后再试一次。” ===&lt;br /&gt;
解决：&lt;br /&gt;
: &amp;lt;s&amp;gt;“控制面板”-&amp;gt;“软件和功能”-&amp;gt;“启用或关闭Windows功能”：展开“媒体功能”-&amp;gt;勾选“windows media player”。&amp;lt;/s&amp;gt;&lt;br /&gt;
: “设置”-&amp;gt;“应用”-&amp;gt;“应用和功能”-&amp;gt;“管理可选功能”-&amp;gt;“添加功能”-&amp;gt;找到“Windows Media Player”并安装。&lt;br /&gt;
:* 安装完成，可以卸载“Windows Media Player”。&lt;br /&gt;
&lt;br /&gt;
== Steam ==&lt;br /&gt;
 在国内使用 Steam，登录、商店等内容是可以正常访问的（'''steampower.com'''），社区、个人资料等内容需要加速（'''steamcommunity.com'''）。&lt;br /&gt;
&lt;br /&gt;
=== 登录失败、商店错误代码:-324 ===&lt;br /&gt;
 如何开启了加速软件，但线路不通的时候，可能出现。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：'''取消网络代理'''&lt;br /&gt;
 &lt;br /&gt;
 （下面两个设置，其实是同一个东西）&lt;br /&gt;
&lt;br /&gt;
* 通过 IE 设置取消网络代理：&lt;br /&gt;
*# 打开IE -&amp;gt; “设置”-&amp;gt;“Internet选项”，在“连接”页找到“局域网设置”；&lt;br /&gt;
*#:（运行“inetcpl.cpl”可直接打开“Internet选项”页）&lt;br /&gt;
*# 取消勾选“'''自动配置'''”及“'''代理服务器'''”下的选项。&lt;br /&gt;
*: [[File:取消 IE 代理.png|400px]]&lt;br /&gt;
* 通过 Windows10 设置，取消“网络代理”：&lt;br /&gt;
*# 打开“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”；&lt;br /&gt;
*# 取消勾选“'''自动代理设置'''”及“'''手动设置代理'''”下的选项；&lt;br /&gt;
*: [[File:Windows设置：代理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 使用 Steam++ 加速 ===&lt;br /&gt;
 对于出现“'''错误代码：-118'''”等情况，很可能是服务地址被禁。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：通过 [https://steampp.net/ '''Steam++'''（Watt Toolkit）] 为 Steam 的单独、或所有服务加速。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Steam++：为Steam加速.png|600px]]&lt;br /&gt;
* 实测：加速模式中，“'''Hosts 代理模式'''”可正常使用，“DNS 驱动拦截”、“PAC 代理模式”时灵时不灵，“系统代理模式”没得用。&lt;br /&gt;
&lt;br /&gt;
 '''Steam++ 还可以为其他软件和服务加速。'''&lt;br /&gt;
 &lt;br /&gt;
 其代理加速具体设置信息可在“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”（如上节）中看到，可能无法和其他代理软件同时使用。&lt;br /&gt;
&lt;br /&gt;
== NVIDIA GeForce Experience 打不开 ==&lt;br /&gt;
 显卡更新频繁，但是 NVIDIA GeForce Experience 这***东西总是打不开（很多很多次），试过了：退出重启、杀进程、管理员启动、服务重启……不好使。&lt;br /&gt;
&lt;br /&gt;
直接去官网下载 NVIDIA GeForce Experience 覆盖安装吧。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
破****，***，**！&lt;br /&gt;
&lt;br /&gt;
 或者是有使用 GPU 的进程？？？下次试试把 WallpaperEngine 之类的软件关闭看看。&lt;br /&gt;
&lt;br /&gt;
== Duet不能连接 ==&lt;br /&gt;
 Windows 和 iPad 都打开了 duet 并连接，但是没反应。&lt;br /&gt;
 &lt;br /&gt;
 【先在 Windows 端关闭 Duet，在断开连接线，就不会出现该问题】&lt;br /&gt;
&amp;lt;s&amp;gt;在 Windows 设备管理器 -&amp;gt; 便携设备 -&amp;gt; Apple iPad ：禁用再启用，稍后就连接了。&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OneDrive使用 ==&lt;br /&gt;
 OneDrive 不同于其他的网盘同步软件：&lt;br /&gt;
 1、默认只能同步 Windows 提供的几个文件夹。&lt;br /&gt;
 2、同步的文件夹都会被强制移动到 OneDrive 文件夹中（默认：“C:\Users\XXX\OneDrive”） —— 原位置只留下链接（快捷方式）。&lt;br /&gt;
&lt;br /&gt;
要监听同步不同位置的文件夹，可以使用 '''&amp;lt;code&amp;gt;mklink&amp;lt;/code&amp;gt;''' 命令（&amp;lt;code&amp;gt;CMD&amp;lt;/code&amp;gt;命令，而非&amp;lt;code&amp;gt;PowerShell&amp;lt;/code&amp;gt;）创建“'''符号链接'''”&amp;lt;ref&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
关于“'''软连接'''”与“'''硬链接'''”：&lt;br /&gt;
# “符号链接（symbolic link）”：即“软连接”。（类似但[[#为什么使用“mklink”：与“快捷方式”区别|不同于“快捷方式”]]）&lt;br /&gt;
#* 与源文件的 inode 节点号不同；&lt;br /&gt;
#* 删除“源文件”即删除了“文件实体”，“软连接”仍存在但不可用；&lt;br /&gt;
#* 可以用于“文件”和“目录”；&lt;br /&gt;
# “硬链接”：“文件实体”的另一个入口。&lt;br /&gt;
#* 与源文件的 inode 节点号相同；&lt;br /&gt;
#* 只有删除了“源文件”和所有“硬链接”（即所有的“文件入口”）后，“文件实体”才会被删除；&lt;br /&gt;
#* 只能用于“文件”，不能用于“目录”；&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;的方式：&lt;br /&gt;
: [[File:mklink命令.png|600px]]&lt;br /&gt;
“目录链接”与“符号链接”：&lt;br /&gt;
*“目录链接”将引用原文件/目录的“绝对路径”，&lt;br /&gt;
* “符号链接”允许引用原文件/目录的“相对路径”。&lt;br /&gt;
* 两者都可以跨文件系统建立，但 Windows 中链接限于 NTFS 文件系统。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: [[File:mklink命令：示例.png|600px]]&lt;br /&gt;
* 文件夹依旧位于 Target 中，不会被强制移动。&lt;br /&gt;
* OneDrive 只留有 Link，不会有原文件占用大小 —— 仍会同步到云。&lt;br /&gt;
&lt;br /&gt;
=== 为什么使用“mklink”：与“快捷方式”区别 ===&lt;br /&gt;
 简单来说：'''“快捷方式”是一个文件（“.lnk”文件），而“mklink”的链接是一个“文件系统对象”'''。&lt;br /&gt;
&lt;br /&gt;
通过对比就可以清楚地看出不同：&lt;br /&gt;
: [[File:mklink：“链接”与“快捷方式”.png|600px]]&lt;br /&gt;
* “ls”在 Windows 中是“'''Get-ChildItem'''”的别名&amp;lt;ref&amp;gt;参考：[https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.4 Microsoft PowerShell 文档：参考#Get-ChildItem]&amp;lt;/ref&amp;gt;。&lt;br /&gt;
* 其中的“Mode”：&lt;br /&gt;
*# “'''l'''”：表示“'''链接'''”；&lt;br /&gt;
*# “'''d'''”：表示“'''目录'''”；&lt;br /&gt;
*# “'''a'''”：表示“'''存档'''”&amp;lt;ref&amp;gt;&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Windows 文件的“'''archive'''”属性：&lt;br /&gt;
    用于标识“文件/文件夹”是否'''被“修改”的标记'''（新增也是一种“修改”）  ——  对于文件/文件夹的备份相当有用：在进行“'''增量备份'''”时，只需要备份被改标记标识的内容。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://www.cnblogs.com/ini_always/archive/2011/11/23/2260699.html Windows文件的archive属性]&lt;br /&gt;
::# [https://blog.51cto.com/xxjiangsir/386557 存档属性是做什么用的？！]&lt;br /&gt;
&amp;lt;/ref&amp;gt;；&lt;br /&gt;
*# “r”：表示“只读”；&lt;br /&gt;
*# “h”：表示“隐藏”；&lt;br /&gt;
*# “s”：表示“系统”；&lt;br /&gt;
&lt;br /&gt;
=== 重置 OneDrive ===&lt;br /&gt;
 有时候 OneDrive 可能一直在“查找更改”，甚至托盘区右键也没反应，还可能连带着 Explorer 无响应。&lt;br /&gt;
&lt;br /&gt;
这种时候结束任务也无济于事，可以考虑“重置 OneDrive”&amp;lt;ref&amp;gt;参考：[https://support.microsoft.com/zh-cn/office/%E9%87%8D%E7%BD%AE-onedrive-34701e00-bf7b-42db-b960-84905399050c Microsoft支持：重置 OneDrive]&amp;lt;/ref&amp;gt;：&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; inline&amp;gt;wsreset.exe&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：清除 Microsoft Store 的临时文件、缓存和设置。（会打开 Microsoft Store 窗口，稍后关闭即可）&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 以下命令，取决于 onedrive.exe 位置&lt;br /&gt;
&lt;br /&gt;
%localappdata%\Microsoft\OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files (x86)\Microsoft OneDrive\onedrive.exe/reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：重置 OneDrive。（执行时无任何窗口，执行完成后会有提示，稍候即可）&lt;br /&gt;
&lt;br /&gt;
 “同步挂起”：可能是由于某些“隐藏项目”导致，可以排查一下。&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6660</id>
		<title>FAQ:Software</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6660"/>
		<updated>2023-12-28T17:18:51Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* OneDrive使用 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Software]]&lt;br /&gt;
&lt;br /&gt;
== office官方卸载工具 ==&lt;br /&gt;
卸载office官方工具：[https://support.microsoft.com/en-us/office/uninstall-office-from-a-pc-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8 Uninstall Microsoft Office]&lt;br /&gt;
&lt;br /&gt;
== 卸载Visio密钥 ==&lt;br /&gt;
安装Visio之后，填入了密钥之后无法激活，想要修改密钥但发现界面没有修改框，所以只有向其他办法：&lt;br /&gt;
# regedit：开始以为使用的key都保存在注册表中，找了一圈并没有找到&lt;br /&gt;
# ？命令行修改，类似于之前查看Windows激活信息的命令&lt;br /&gt;
&lt;br /&gt;
=== 查看许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /dstatus&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
PRODUCT ID: 00341-31872-32451-AA593&lt;br /&gt;
SKU ID: 2dfe2075-2d04-4e43-816a-eb60bbb77574&lt;br /&gt;
LICENSE NAME: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
LICENSE DESCRIPTION: Office 16, RETAIL channel&lt;br /&gt;
BETA EXPIRATION: 1601/1/1&lt;br /&gt;
LICENSE STATUS:  ---OOB_GRACE---&lt;br /&gt;
ERROR CODE: 0x4004F00C&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the application is running within the valid grace period.&lt;br /&gt;
REMAINING GRACE: 29 days  (43147 minute(s) before expiring)&lt;br /&gt;
Last 5 characters of installed product key: DPFJH&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 安装的产品密钥： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /inpkey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 刷新许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /rearm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 卸载已安装的产品密钥： ===&lt;br /&gt;
* “unpkey”后的内容为密钥的最后5位数&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
&amp;lt;Product key uninstall successful&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 找不到对应的unpkey时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:AA593&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
&amp;lt;Product key not found&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# cmd未使用管理员权限时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
ERROR CODE: 0xC004F025&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the action requires administrator privilege.&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== notepad++ 自动保存位置 ==&lt;br /&gt;
notepad++ 会自动定期保存文件，所以没有手动保存为文件的内容也能够在关闭notepad++的下一次自动显示；&lt;br /&gt;
&lt;br /&gt;
如果关闭notepad++重新打开之后，上次没有手动保存的内容没有显示也不用慌，可以在'''&amp;quot;C:\Users\eijux\AppData\Roaming\Notepad++\backup&amp;quot;'''下自动定期保存的文件中找到。&lt;br /&gt;
&lt;br /&gt;
== 删除多余 Hyper-V Virtual Ethernet Adapter ==&lt;br /&gt;
在使用VBox的过程中，每次遇到更新、重装，都会导致多出虚拟网卡适配器：&lt;br /&gt;
:[[File:多余的虚拟网卡适配器.png|600px]]&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;s&amp;gt;方法一：&lt;br /&gt;
#: 在系统设置网络连接部分又不能直接删除，所以找到了一个从注册表删除的方法：&amp;lt;br/&amp;gt;&lt;br /&gt;
#: 在“'''计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ROOT\VMS_MP'''”中找到多余的项删除即可：&lt;br /&gt;
#: [[File:删除多余虚拟网卡适配器.png|600px]]&lt;br /&gt;
#: 【好像不求好使，以前是在注册表删除的，好像不是这】&amp;lt;/s&amp;gt;&lt;br /&gt;
# 方法二：&lt;br /&gt;
#: 在适配器列表（控制面板-&amp;gt;网络和共享中心-&amp;gt;更改适配器设置），右键“属性”，选择“配置”，到“驱动程序”页，选择“卸载设备”即可。&lt;br /&gt;
&lt;br /&gt;
== 安装“Twomon SE”后托盘区图标间隙变大 ==&lt;br /&gt;
由于想把 iPad 当作 Windows 的拓展屏幕使用，比较多个软件之后，购买了 Twomon SE，但在安装 PC 端之后，突然发现托盘区的图标间隙变得很大很大：&lt;br /&gt;
: [[File:Windows托盘区图标间隙.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
强迫症不能忍，能够确定是 Twomon SE 安装后的问题，查了一些资料，确定如下：&lt;br /&gt;
# 托盘区图标间隙变大，是因为系统认定当前在使用触摸式键盘。&lt;br /&gt;
#* “在触摸模式下，Windows 会在系统托盘（和其他UI）上留出空间，以便减少误点击图标的情况。”&lt;br /&gt;
# 系统托盘图标的间距，不受任何注册表项控制，它内置于程序中，不能更改。&lt;br /&gt;
#*“由explorer.exe应用程序中的编码控制。它是内部编码的，不依赖也不参考任何外部设置、控制或数据值来确定间距。改变它的唯一方法是反编译explorer.exe程序并重新编程文件。考虑到它是一个二进制文件，如果不访问源代码，这将是非常困难或不可能做到的。”&lt;br /&gt;
# 触摸屏设备，是“设备管理器 -&amp;gt; 人体学输入设备 -&amp;gt; 符合 HID 标准的触摸屏”（带 Touch Screen 或者触摸字样的设备）。&lt;br /&gt;
#* 通过禁用该设备可以使托盘区图标间隙恢复，但是，触摸设备也不能使用。（此处用的 iPad 就只能用作“显示屏”而不能用作“触摸屏”）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通过测试，可以把上述设备理器中的项“先禁用在启用”，使托盘区图标间隙恢复，且触摸正常使用，重启也没出现问题（可能使快速启动，没完全重启），算是曲线救国了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''参考：'''&lt;br /&gt;
# [https://answers.microsoft.com/zh-hans/windows/forum/all/%E4%BB%BB%E5%8A%A1%E6%A0%8F%E9%80%9A%E7%9F%A5/a4645ec6-343d-47c1-86cd-732a7536dac4 Microsoft Community：任务栏通知区域（托盘）图标间距变大]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/all/system-tray-icon-spacing-in-windows-10/6ab6e0dd-fe13-48e7-8eeb-c0d12abee6f3 Microsoft Community：System tray icon spacing in WIndows 10]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/tray-icons-reduce-spacing/93991e6b-5c53-4df5-af4e-3bdf3fde17fe Microsoft Community：Tray icons reduce spacing]&lt;br /&gt;
&lt;br /&gt;
== OpenVPN 问题 ==&lt;br /&gt;
 OpenVPN GUI 下载地址： '''https://openvpn.net/community-downloads/'''&lt;br /&gt;
&lt;br /&gt;
=== 设置密码自动填充 ===&lt;br /&gt;
使用 OpenVPN 连接时，每个连接第一次使用都需要输入用户名密码：&lt;br /&gt;
# 在配置文件“xxx.ovpn”的同级目录，添加“auth.txt”文件：第一行为用户，第二行为密码。&lt;br /&gt;
# 在配置文件“xxx.ovpn”中编辑：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
auth-user-pass auth.txt&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如此，不再需要手动填充用户密码信息。&lt;br /&gt;
&lt;br /&gt;
=== 未启动“OpenVPNServiceInteractive” ===&lt;br /&gt;
启动 OpenVPN GUI 时，出现如下提示：&lt;br /&gt;
: [[File:OpenVPN：未启动OpenVPNServiceInteractive.png|400px]]&lt;br /&gt;
&lt;br /&gt;
在 Windows 服务中，启动“'''OpenVPN Interactive Service'''”服务即可。&lt;br /&gt;
&lt;br /&gt;
== Vultr 验证页面 ==&lt;br /&gt;
打开 Vultr 登录页面，总是遇到如下页面，并不能成功跳转：&lt;br /&gt;
: [[File:Vultr：验证页面.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*【2021/11/24 19:23:13】试试不用代理打开，好像能成功。&lt;br /&gt;
&lt;br /&gt;
== Windows更新iTunes、iCloud失败 ==&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows更新iTunes、iCloud失败.png|400px]]&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 卸载该软件（iTunes/iCloud）；&lt;br /&gt;
# 卸载Apple相关的安装内容；&lt;br /&gt;
#* 包括：“Apple Mobile Device Surpport”、“Apple Software Update”、“Apple 应用程序支持(64位)”、“Apple 应用程序支持(32位)”、“Bonjour”；&lt;br /&gt;
# 重新执行安装程序；&lt;br /&gt;
&lt;br /&gt;
=== 安装iCloud时提示“您的电脑缺少媒体功能。请从Microsoft网站下载Media Feature Pack/Windows并安装，然后再试一次。” ===&lt;br /&gt;
解决：&lt;br /&gt;
: &amp;lt;s&amp;gt;“控制面板”-&amp;gt;“软件和功能”-&amp;gt;“启用或关闭Windows功能”：展开“媒体功能”-&amp;gt;勾选“windows media player”。&amp;lt;/s&amp;gt;&lt;br /&gt;
: “设置”-&amp;gt;“应用”-&amp;gt;“应用和功能”-&amp;gt;“管理可选功能”-&amp;gt;“添加功能”-&amp;gt;找到“Windows Media Player”并安装。&lt;br /&gt;
:* 安装完成，可以卸载“Windows Media Player”。&lt;br /&gt;
&lt;br /&gt;
== Steam ==&lt;br /&gt;
 在国内使用 Steam，登录、商店等内容是可以正常访问的（'''steampower.com'''），社区、个人资料等内容需要加速（'''steamcommunity.com'''）。&lt;br /&gt;
&lt;br /&gt;
=== 登录失败、商店错误代码:-324 ===&lt;br /&gt;
 如何开启了加速软件，但线路不通的时候，可能出现。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：'''取消网络代理'''&lt;br /&gt;
 &lt;br /&gt;
 （下面两个设置，其实是同一个东西）&lt;br /&gt;
&lt;br /&gt;
* 通过 IE 设置取消网络代理：&lt;br /&gt;
*# 打开IE -&amp;gt; “设置”-&amp;gt;“Internet选项”，在“连接”页找到“局域网设置”；&lt;br /&gt;
*#:（运行“inetcpl.cpl”可直接打开“Internet选项”页）&lt;br /&gt;
*# 取消勾选“'''自动配置'''”及“'''代理服务器'''”下的选项。&lt;br /&gt;
*: [[File:取消 IE 代理.png|400px]]&lt;br /&gt;
* 通过 Windows10 设置，取消“网络代理”：&lt;br /&gt;
*# 打开“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”；&lt;br /&gt;
*# 取消勾选“'''自动代理设置'''”及“'''手动设置代理'''”下的选项；&lt;br /&gt;
*: [[File:Windows设置：代理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 使用 Steam++ 加速 ===&lt;br /&gt;
 对于出现“'''错误代码：-118'''”等情况，很可能是服务地址被禁。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：通过 [https://steampp.net/ '''Steam++'''（Watt Toolkit）] 为 Steam 的单独、或所有服务加速。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Steam++：为Steam加速.png|600px]]&lt;br /&gt;
* 实测：加速模式中，“'''Hosts 代理模式'''”可正常使用，“DNS 驱动拦截”、“PAC 代理模式”时灵时不灵，“系统代理模式”没得用。&lt;br /&gt;
&lt;br /&gt;
 '''Steam++ 还可以为其他软件和服务加速。'''&lt;br /&gt;
 &lt;br /&gt;
 其代理加速具体设置信息可在“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”（如上节）中看到，可能无法和其他代理软件同时使用。&lt;br /&gt;
&lt;br /&gt;
== NVIDIA GeForce Experience 打不开 ==&lt;br /&gt;
 显卡更新频繁，但是 NVIDIA GeForce Experience 这***东西总是打不开（很多很多次），试过了：退出重启、杀进程、管理员启动、服务重启……不好使。&lt;br /&gt;
&lt;br /&gt;
直接去官网下载 NVIDIA GeForce Experience 覆盖安装吧。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
破****，***，**！&lt;br /&gt;
&lt;br /&gt;
 或者是有使用 GPU 的进程？？？下次试试把 WallpaperEngine 之类的软件关闭看看。&lt;br /&gt;
&lt;br /&gt;
== Duet不能连接 ==&lt;br /&gt;
 Windows 和 iPad 都打开了 duet 并连接，但是没反应。&lt;br /&gt;
 &lt;br /&gt;
 【先在 Windows 端关闭 Duet，在断开连接线，就不会出现该问题】&lt;br /&gt;
&amp;lt;s&amp;gt;在 Windows 设备管理器 -&amp;gt; 便携设备 -&amp;gt; Apple iPad ：禁用再启用，稍后就连接了。&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OneDrive使用 ==&lt;br /&gt;
 OneDrive 不同于其他的网盘同步软件：&lt;br /&gt;
 1、默认只能同步 Windows 提供的几个文件夹。&lt;br /&gt;
 2、同步的文件夹都会被强制移动到 OneDrive 文件夹中（默认：“C:\Users\XXX\OneDrive”） —— 原位置只留下链接（快捷方式）。&lt;br /&gt;
&lt;br /&gt;
要监听同步不同位置的文件夹，可以使用 '''&amp;lt;code&amp;gt;mklink&amp;lt;/code&amp;gt;''' 命令创建“'''符号链接'''”&amp;lt;ref&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
关于“'''软连接'''”与“'''硬链接'''”：&lt;br /&gt;
# “符号链接（symbolic link）”：即“软连接”。（类似但[[#为什么使用“mklink”：与“快捷方式”区别|不同于“快捷方式”]]）&lt;br /&gt;
#* 与源文件的 inode 节点号不同；&lt;br /&gt;
#* 删除“源文件”即删除了“文件实体”，“软连接”仍存在但不可用；&lt;br /&gt;
#* 可以用于“文件”和“目录”；&lt;br /&gt;
# “硬链接”：“文件实体”的另一个入口。&lt;br /&gt;
#* 与源文件的 inode 节点号相同；&lt;br /&gt;
#* 只有删除了“源文件”和所有“硬链接”（即所有的“文件入口”）后，“文件实体”才会被删除；&lt;br /&gt;
#* 只能用于“文件”，不能用于“目录”；&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;的方式：&lt;br /&gt;
: [[File:mklink命令.png|600px]]&lt;br /&gt;
“目录链接”与“符号链接”：&lt;br /&gt;
*“目录链接”将引用原文件/目录的“绝对路径”，&lt;br /&gt;
* “符号链接”允许引用原文件/目录的“相对路径”。&lt;br /&gt;
* 两者都可以跨文件系统建立，但 Windows 中链接限于 NTFS 文件系统。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: [[File:mklink命令：示例.png|600px]]&lt;br /&gt;
* 文件夹依旧位于 Target 中，不会被强制移动。&lt;br /&gt;
* OneDrive 只留有 Link，不会有原文件占用大小 —— 仍会同步到云。&lt;br /&gt;
&lt;br /&gt;
=== 为什么使用“mklink”：与“快捷方式”区别 ===&lt;br /&gt;
 简单来说：'''“快捷方式”是一个文件（“.lnk”文件），而“mklink”的链接是一个“文件系统对象”'''。&lt;br /&gt;
&lt;br /&gt;
通过对比就可以清楚地看出不同：&lt;br /&gt;
: [[File:mklink：“链接”与“快捷方式”.png|600px]]&lt;br /&gt;
* “ls”在 Windows 中是“'''Get-ChildItem'''”的别名&amp;lt;ref&amp;gt;参考：[https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.4 Microsoft PowerShell 文档：参考#Get-ChildItem]&amp;lt;/ref&amp;gt;。&lt;br /&gt;
* 其中的“Mode”：&lt;br /&gt;
*# “'''l'''”：表示“'''链接'''”；&lt;br /&gt;
*# “'''d'''”：表示“'''目录'''”；&lt;br /&gt;
*# “'''a'''”：表示“'''存档'''”&amp;lt;ref&amp;gt;&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Windows 文件的“'''archive'''”属性：&lt;br /&gt;
    用于标识“文件/文件夹”是否'''被“修改”的标记'''（新增也是一种“修改”）  ——  对于文件/文件夹的备份相当有用：在进行“'''增量备份'''”时，只需要备份被改标记标识的内容。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://www.cnblogs.com/ini_always/archive/2011/11/23/2260699.html Windows文件的archive属性]&lt;br /&gt;
::# [https://blog.51cto.com/xxjiangsir/386557 存档属性是做什么用的？！]&lt;br /&gt;
&amp;lt;/ref&amp;gt;；&lt;br /&gt;
*# “r”：表示“只读”；&lt;br /&gt;
*# “h”：表示“隐藏”；&lt;br /&gt;
*# “s”：表示“系统”；&lt;br /&gt;
&lt;br /&gt;
=== 重置 OneDrive ===&lt;br /&gt;
 有时候 OneDrive 可能一直在“查找更改”，甚至托盘区右键也没反应，还可能连带着 Explorer 无响应。&lt;br /&gt;
&lt;br /&gt;
这种时候结束任务也无济于事，可以考虑“重置 OneDrive”&amp;lt;ref&amp;gt;参考：[https://support.microsoft.com/zh-cn/office/%E9%87%8D%E7%BD%AE-onedrive-34701e00-bf7b-42db-b960-84905399050c Microsoft支持：重置 OneDrive]&amp;lt;/ref&amp;gt;：&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; inline&amp;gt;wsreset.exe&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：清除 Microsoft Store 的临时文件、缓存和设置。（会打开 Microsoft Store 窗口，稍后关闭即可）&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 以下命令，取决于 onedrive.exe 位置&lt;br /&gt;
&lt;br /&gt;
%localappdata%\Microsoft\OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files (x86)\Microsoft OneDrive\onedrive.exe/reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：重置 OneDrive。（执行时无任何窗口，执行完成后会有提示，稍候即可）&lt;br /&gt;
&lt;br /&gt;
 “同步挂起”：可能是由于某些“隐藏项目”导致，可以排查一下。&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6659</id>
		<title>FAQ:Software</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6659"/>
		<updated>2023-12-28T16:52:55Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Software]]&lt;br /&gt;
&lt;br /&gt;
== office官方卸载工具 ==&lt;br /&gt;
卸载office官方工具：[https://support.microsoft.com/en-us/office/uninstall-office-from-a-pc-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8 Uninstall Microsoft Office]&lt;br /&gt;
&lt;br /&gt;
== 卸载Visio密钥 ==&lt;br /&gt;
安装Visio之后，填入了密钥之后无法激活，想要修改密钥但发现界面没有修改框，所以只有向其他办法：&lt;br /&gt;
# regedit：开始以为使用的key都保存在注册表中，找了一圈并没有找到&lt;br /&gt;
# ？命令行修改，类似于之前查看Windows激活信息的命令&lt;br /&gt;
&lt;br /&gt;
=== 查看许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /dstatus&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
PRODUCT ID: 00341-31872-32451-AA593&lt;br /&gt;
SKU ID: 2dfe2075-2d04-4e43-816a-eb60bbb77574&lt;br /&gt;
LICENSE NAME: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
LICENSE DESCRIPTION: Office 16, RETAIL channel&lt;br /&gt;
BETA EXPIRATION: 1601/1/1&lt;br /&gt;
LICENSE STATUS:  ---OOB_GRACE---&lt;br /&gt;
ERROR CODE: 0x4004F00C&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the application is running within the valid grace period.&lt;br /&gt;
REMAINING GRACE: 29 days  (43147 minute(s) before expiring)&lt;br /&gt;
Last 5 characters of installed product key: DPFJH&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 安装的产品密钥： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /inpkey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 刷新许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /rearm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 卸载已安装的产品密钥： ===&lt;br /&gt;
* “unpkey”后的内容为密钥的最后5位数&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
&amp;lt;Product key uninstall successful&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 找不到对应的unpkey时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:AA593&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
&amp;lt;Product key not found&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# cmd未使用管理员权限时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
ERROR CODE: 0xC004F025&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the action requires administrator privilege.&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== notepad++ 自动保存位置 ==&lt;br /&gt;
notepad++ 会自动定期保存文件，所以没有手动保存为文件的内容也能够在关闭notepad++的下一次自动显示；&lt;br /&gt;
&lt;br /&gt;
如果关闭notepad++重新打开之后，上次没有手动保存的内容没有显示也不用慌，可以在'''&amp;quot;C:\Users\eijux\AppData\Roaming\Notepad++\backup&amp;quot;'''下自动定期保存的文件中找到。&lt;br /&gt;
&lt;br /&gt;
== 删除多余 Hyper-V Virtual Ethernet Adapter ==&lt;br /&gt;
在使用VBox的过程中，每次遇到更新、重装，都会导致多出虚拟网卡适配器：&lt;br /&gt;
:[[File:多余的虚拟网卡适配器.png|600px]]&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;s&amp;gt;方法一：&lt;br /&gt;
#: 在系统设置网络连接部分又不能直接删除，所以找到了一个从注册表删除的方法：&amp;lt;br/&amp;gt;&lt;br /&gt;
#: 在“'''计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ROOT\VMS_MP'''”中找到多余的项删除即可：&lt;br /&gt;
#: [[File:删除多余虚拟网卡适配器.png|600px]]&lt;br /&gt;
#: 【好像不求好使，以前是在注册表删除的，好像不是这】&amp;lt;/s&amp;gt;&lt;br /&gt;
# 方法二：&lt;br /&gt;
#: 在适配器列表（控制面板-&amp;gt;网络和共享中心-&amp;gt;更改适配器设置），右键“属性”，选择“配置”，到“驱动程序”页，选择“卸载设备”即可。&lt;br /&gt;
&lt;br /&gt;
== 安装“Twomon SE”后托盘区图标间隙变大 ==&lt;br /&gt;
由于想把 iPad 当作 Windows 的拓展屏幕使用，比较多个软件之后，购买了 Twomon SE，但在安装 PC 端之后，突然发现托盘区的图标间隙变得很大很大：&lt;br /&gt;
: [[File:Windows托盘区图标间隙.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
强迫症不能忍，能够确定是 Twomon SE 安装后的问题，查了一些资料，确定如下：&lt;br /&gt;
# 托盘区图标间隙变大，是因为系统认定当前在使用触摸式键盘。&lt;br /&gt;
#* “在触摸模式下，Windows 会在系统托盘（和其他UI）上留出空间，以便减少误点击图标的情况。”&lt;br /&gt;
# 系统托盘图标的间距，不受任何注册表项控制，它内置于程序中，不能更改。&lt;br /&gt;
#*“由explorer.exe应用程序中的编码控制。它是内部编码的，不依赖也不参考任何外部设置、控制或数据值来确定间距。改变它的唯一方法是反编译explorer.exe程序并重新编程文件。考虑到它是一个二进制文件，如果不访问源代码，这将是非常困难或不可能做到的。”&lt;br /&gt;
# 触摸屏设备，是“设备管理器 -&amp;gt; 人体学输入设备 -&amp;gt; 符合 HID 标准的触摸屏”（带 Touch Screen 或者触摸字样的设备）。&lt;br /&gt;
#* 通过禁用该设备可以使托盘区图标间隙恢复，但是，触摸设备也不能使用。（此处用的 iPad 就只能用作“显示屏”而不能用作“触摸屏”）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通过测试，可以把上述设备理器中的项“先禁用在启用”，使托盘区图标间隙恢复，且触摸正常使用，重启也没出现问题（可能使快速启动，没完全重启），算是曲线救国了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''参考：'''&lt;br /&gt;
# [https://answers.microsoft.com/zh-hans/windows/forum/all/%E4%BB%BB%E5%8A%A1%E6%A0%8F%E9%80%9A%E7%9F%A5/a4645ec6-343d-47c1-86cd-732a7536dac4 Microsoft Community：任务栏通知区域（托盘）图标间距变大]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/all/system-tray-icon-spacing-in-windows-10/6ab6e0dd-fe13-48e7-8eeb-c0d12abee6f3 Microsoft Community：System tray icon spacing in WIndows 10]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/tray-icons-reduce-spacing/93991e6b-5c53-4df5-af4e-3bdf3fde17fe Microsoft Community：Tray icons reduce spacing]&lt;br /&gt;
&lt;br /&gt;
== OpenVPN 问题 ==&lt;br /&gt;
 OpenVPN GUI 下载地址： '''https://openvpn.net/community-downloads/'''&lt;br /&gt;
&lt;br /&gt;
=== 设置密码自动填充 ===&lt;br /&gt;
使用 OpenVPN 连接时，每个连接第一次使用都需要输入用户名密码：&lt;br /&gt;
# 在配置文件“xxx.ovpn”的同级目录，添加“auth.txt”文件：第一行为用户，第二行为密码。&lt;br /&gt;
# 在配置文件“xxx.ovpn”中编辑：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
auth-user-pass auth.txt&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如此，不再需要手动填充用户密码信息。&lt;br /&gt;
&lt;br /&gt;
=== 未启动“OpenVPNServiceInteractive” ===&lt;br /&gt;
启动 OpenVPN GUI 时，出现如下提示：&lt;br /&gt;
: [[File:OpenVPN：未启动OpenVPNServiceInteractive.png|400px]]&lt;br /&gt;
&lt;br /&gt;
在 Windows 服务中，启动“'''OpenVPN Interactive Service'''”服务即可。&lt;br /&gt;
&lt;br /&gt;
== Vultr 验证页面 ==&lt;br /&gt;
打开 Vultr 登录页面，总是遇到如下页面，并不能成功跳转：&lt;br /&gt;
: [[File:Vultr：验证页面.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*【2021/11/24 19:23:13】试试不用代理打开，好像能成功。&lt;br /&gt;
&lt;br /&gt;
== Windows更新iTunes、iCloud失败 ==&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows更新iTunes、iCloud失败.png|400px]]&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 卸载该软件（iTunes/iCloud）；&lt;br /&gt;
# 卸载Apple相关的安装内容；&lt;br /&gt;
#* 包括：“Apple Mobile Device Surpport”、“Apple Software Update”、“Apple 应用程序支持(64位)”、“Apple 应用程序支持(32位)”、“Bonjour”；&lt;br /&gt;
# 重新执行安装程序；&lt;br /&gt;
&lt;br /&gt;
=== 安装iCloud时提示“您的电脑缺少媒体功能。请从Microsoft网站下载Media Feature Pack/Windows并安装，然后再试一次。” ===&lt;br /&gt;
解决：&lt;br /&gt;
: &amp;lt;s&amp;gt;“控制面板”-&amp;gt;“软件和功能”-&amp;gt;“启用或关闭Windows功能”：展开“媒体功能”-&amp;gt;勾选“windows media player”。&amp;lt;/s&amp;gt;&lt;br /&gt;
: “设置”-&amp;gt;“应用”-&amp;gt;“应用和功能”-&amp;gt;“管理可选功能”-&amp;gt;“添加功能”-&amp;gt;找到“Windows Media Player”并安装。&lt;br /&gt;
:* 安装完成，可以卸载“Windows Media Player”。&lt;br /&gt;
&lt;br /&gt;
== Steam ==&lt;br /&gt;
 在国内使用 Steam，登录、商店等内容是可以正常访问的（'''steampower.com'''），社区、个人资料等内容需要加速（'''steamcommunity.com'''）。&lt;br /&gt;
&lt;br /&gt;
=== 登录失败、商店错误代码:-324 ===&lt;br /&gt;
 如何开启了加速软件，但线路不通的时候，可能出现。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：'''取消网络代理'''&lt;br /&gt;
 &lt;br /&gt;
 （下面两个设置，其实是同一个东西）&lt;br /&gt;
&lt;br /&gt;
* 通过 IE 设置取消网络代理：&lt;br /&gt;
*# 打开IE -&amp;gt; “设置”-&amp;gt;“Internet选项”，在“连接”页找到“局域网设置”；&lt;br /&gt;
*#:（运行“inetcpl.cpl”可直接打开“Internet选项”页）&lt;br /&gt;
*# 取消勾选“'''自动配置'''”及“'''代理服务器'''”下的选项。&lt;br /&gt;
*: [[File:取消 IE 代理.png|400px]]&lt;br /&gt;
* 通过 Windows10 设置，取消“网络代理”：&lt;br /&gt;
*# 打开“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”；&lt;br /&gt;
*# 取消勾选“'''自动代理设置'''”及“'''手动设置代理'''”下的选项；&lt;br /&gt;
*: [[File:Windows设置：代理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 使用 Steam++ 加速 ===&lt;br /&gt;
 对于出现“'''错误代码：-118'''”等情况，很可能是服务地址被禁。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：通过 [https://steampp.net/ '''Steam++'''（Watt Toolkit）] 为 Steam 的单独、或所有服务加速。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Steam++：为Steam加速.png|600px]]&lt;br /&gt;
* 实测：加速模式中，“'''Hosts 代理模式'''”可正常使用，“DNS 驱动拦截”、“PAC 代理模式”时灵时不灵，“系统代理模式”没得用。&lt;br /&gt;
&lt;br /&gt;
 '''Steam++ 还可以为其他软件和服务加速。'''&lt;br /&gt;
 &lt;br /&gt;
 其代理加速具体设置信息可在“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”（如上节）中看到，可能无法和其他代理软件同时使用。&lt;br /&gt;
&lt;br /&gt;
== NVIDIA GeForce Experience 打不开 ==&lt;br /&gt;
 显卡更新频繁，但是 NVIDIA GeForce Experience 这***东西总是打不开（很多很多次），试过了：退出重启、杀进程、管理员启动、服务重启……不好使。&lt;br /&gt;
&lt;br /&gt;
直接去官网下载 NVIDIA GeForce Experience 覆盖安装吧。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
破****，***，**！&lt;br /&gt;
&lt;br /&gt;
 或者是有使用 GPU 的进程？？？下次试试把 WallpaperEngine 之类的软件关闭看看。&lt;br /&gt;
&lt;br /&gt;
== Duet不能连接 ==&lt;br /&gt;
 Windows 和 iPad 都打开了 duet 并连接，但是没反应。&lt;br /&gt;
 &lt;br /&gt;
 【先在 Windows 端关闭 Duet，在断开连接线，就不会出现该问题】&lt;br /&gt;
&amp;lt;s&amp;gt;在 Windows 设备管理器 -&amp;gt; 便携设备 -&amp;gt; Apple iPad ：禁用再启用，稍后就连接了。&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OneDrive使用 ==&lt;br /&gt;
 OneDrive 不同于其他的网盘同步软件：&lt;br /&gt;
 1、默认只能同步 Windows 提供的几个文件夹。&lt;br /&gt;
 2、同步的文件夹都会被强制移动到 OneDrive 文件夹中（默认：“C:\Users\XXX\OneDrive”） —— 原位置只留下链接（快捷方式）。&lt;br /&gt;
&lt;br /&gt;
要监听同步不同位置的文件夹，可以使用 '''&amp;lt;code&amp;gt;mklink&amp;lt;/code&amp;gt;''' 命令创建“'''符号链接'''”的方式：&lt;br /&gt;
: [[File:mklink命令.png|600px]]&lt;br /&gt;
# &amp;lt;code&amp;gt;/D&amp;lt;/code&amp;gt;：创建“符号链接（symbolic link）”，即“软连接”。&lt;br /&gt;
#: 类似于快捷方式（但不同，见[[#为什么使用“mklink”：与“快捷方式”区别|下一节]]），&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: [[File:mklink命令：示例.png|600px]]&lt;br /&gt;
* 文件夹依旧位于 Target 中，不会被强制移动。&lt;br /&gt;
* OneDrive 只留有 Link，不会有原文件占用大小 —— 仍会同步到云。&lt;br /&gt;
&lt;br /&gt;
=== 为什么使用“mklink”：与“快捷方式”区别 ===&lt;br /&gt;
 简单来说：'''“快捷方式”是一个文件（“.lnk”文件），而“mklink”的链接是一个“文件系统对象”'''。&lt;br /&gt;
&lt;br /&gt;
通过对比就可以清楚地看出不同：&lt;br /&gt;
: [[File:mklink：“链接”与“快捷方式”.png|600px]]&lt;br /&gt;
* “ls”在 Windows 中是“Get-ChildItem”的别名&amp;lt;ref&amp;gt;关于：&amp;lt;/ref&amp;gt;。&lt;br /&gt;
* 其中的“Mode”：&lt;br /&gt;
*# “'''l'''”：表示“'''链接'''”；&lt;br /&gt;
*# “'''d'''”：表示“'''目录'''”；&lt;br /&gt;
*# “'''a'''”：表示“'''存档'''”&amp;lt;ref&amp;gt;&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Windows 文件的“'''archive'''”属性：&lt;br /&gt;
    用于标识“文件/文件夹”是否'''被“修改”的标记'''（新增也是一种“修改”）  ——  对于文件/文件夹的备份相当有用：在进行“'''增量备份'''”时，只需要备份被改标记标识的内容。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://www.cnblogs.com/ini_always/archive/2011/11/23/2260699.html Windows文件的archive属性]&lt;br /&gt;
::# [https://blog.51cto.com/xxjiangsir/386557 存档属性是做什么用的？！]&lt;br /&gt;
&amp;lt;/ref&amp;gt;；&lt;br /&gt;
*# “r”：表示“只读”；&lt;br /&gt;
*# “h”：表示“隐藏”；&lt;br /&gt;
*# “s”：表示“系统”；&lt;br /&gt;
&lt;br /&gt;
=== 重置 OneDrive ===&lt;br /&gt;
 有时候 OneDrive 可能一直在“查找更改”，甚至托盘区右键也没反应，还可能连带着 Explorer 无响应。&lt;br /&gt;
&lt;br /&gt;
这种时候结束任务也无济于事，可以考虑“重置 OneDrive”&amp;lt;ref&amp;gt;参考：[https://support.microsoft.com/zh-cn/office/%E9%87%8D%E7%BD%AE-onedrive-34701e00-bf7b-42db-b960-84905399050c Microsoft支持：重置 OneDrive]&amp;lt;/ref&amp;gt;：&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; inline&amp;gt;wsreset.exe&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：清除 Microsoft Store 的临时文件、缓存和设置。（会打开 Microsoft Store 窗口，稍后关闭即可）&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 以下命令，取决于 onedrive.exe 位置&lt;br /&gt;
&lt;br /&gt;
%localappdata%\Microsoft\OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files (x86)\Microsoft OneDrive\onedrive.exe/reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：重置 OneDrive。（执行时无任何窗口，执行完成后会有提示，稍候即可）&lt;br /&gt;
&lt;br /&gt;
 “同步挂起”：可能是由于某些“隐藏项目”导致，可以排查一下。&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%EF%BC%9A%E2%80%9C%E9%93%BE%E6%8E%A5%E2%80%9D%E4%B8%8E%E2%80%9C%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F%E2%80%9D.png&amp;diff=6658</id>
		<title>文件:Mklink：“链接”与“快捷方式”.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%EF%BC%9A%E2%80%9C%E9%93%BE%E6%8E%A5%E2%80%9D%E4%B8%8E%E2%80%9C%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F%E2%80%9D.png&amp;diff=6658"/>
		<updated>2023-12-28T16:03:55Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6657</id>
		<title>FAQ:Software</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6657"/>
		<updated>2023-12-28T15:23:34Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* OneDrive使用 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Software]]&lt;br /&gt;
&lt;br /&gt;
== office官方卸载工具 ==&lt;br /&gt;
卸载office官方工具：[https://support.microsoft.com/en-us/office/uninstall-office-from-a-pc-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8 Uninstall Microsoft Office]&lt;br /&gt;
&lt;br /&gt;
== 卸载Visio密钥 ==&lt;br /&gt;
安装Visio之后，填入了密钥之后无法激活，想要修改密钥但发现界面没有修改框，所以只有向其他办法：&lt;br /&gt;
# regedit：开始以为使用的key都保存在注册表中，找了一圈并没有找到&lt;br /&gt;
# ？命令行修改，类似于之前查看Windows激活信息的命令&lt;br /&gt;
&lt;br /&gt;
=== 查看许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /dstatus&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
PRODUCT ID: 00341-31872-32451-AA593&lt;br /&gt;
SKU ID: 2dfe2075-2d04-4e43-816a-eb60bbb77574&lt;br /&gt;
LICENSE NAME: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
LICENSE DESCRIPTION: Office 16, RETAIL channel&lt;br /&gt;
BETA EXPIRATION: 1601/1/1&lt;br /&gt;
LICENSE STATUS:  ---OOB_GRACE---&lt;br /&gt;
ERROR CODE: 0x4004F00C&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the application is running within the valid grace period.&lt;br /&gt;
REMAINING GRACE: 29 days  (43147 minute(s) before expiring)&lt;br /&gt;
Last 5 characters of installed product key: DPFJH&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 安装的产品密钥： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /inpkey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 刷新许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /rearm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 卸载已安装的产品密钥： ===&lt;br /&gt;
* “unpkey”后的内容为密钥的最后5位数&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
&amp;lt;Product key uninstall successful&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 找不到对应的unpkey时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:AA593&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
&amp;lt;Product key not found&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# cmd未使用管理员权限时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
ERROR CODE: 0xC004F025&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the action requires administrator privilege.&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== notepad++ 自动保存位置 ==&lt;br /&gt;
notepad++ 会自动定期保存文件，所以没有手动保存为文件的内容也能够在关闭notepad++的下一次自动显示；&lt;br /&gt;
&lt;br /&gt;
如果关闭notepad++重新打开之后，上次没有手动保存的内容没有显示也不用慌，可以在'''&amp;quot;C:\Users\eijux\AppData\Roaming\Notepad++\backup&amp;quot;'''下自动定期保存的文件中找到。&lt;br /&gt;
&lt;br /&gt;
== 删除多余 Hyper-V Virtual Ethernet Adapter ==&lt;br /&gt;
在使用VBox的过程中，每次遇到更新、重装，都会导致多出虚拟网卡适配器：&lt;br /&gt;
:[[File:多余的虚拟网卡适配器.png|600px]]&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;s&amp;gt;方法一：&lt;br /&gt;
#: 在系统设置网络连接部分又不能直接删除，所以找到了一个从注册表删除的方法：&amp;lt;br/&amp;gt;&lt;br /&gt;
#: 在“'''计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ROOT\VMS_MP'''”中找到多余的项删除即可：&lt;br /&gt;
#: [[File:删除多余虚拟网卡适配器.png|600px]]&lt;br /&gt;
#: 【好像不求好使，以前是在注册表删除的，好像不是这】&amp;lt;/s&amp;gt;&lt;br /&gt;
# 方法二：&lt;br /&gt;
#: 在适配器列表（控制面板-&amp;gt;网络和共享中心-&amp;gt;更改适配器设置），右键“属性”，选择“配置”，到“驱动程序”页，选择“卸载设备”即可。&lt;br /&gt;
&lt;br /&gt;
== 安装“Twomon SE”后托盘区图标间隙变大 ==&lt;br /&gt;
由于想把 iPad 当作 Windows 的拓展屏幕使用，比较多个软件之后，购买了 Twomon SE，但在安装 PC 端之后，突然发现托盘区的图标间隙变得很大很大：&lt;br /&gt;
: [[File:Windows托盘区图标间隙.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
强迫症不能忍，能够确定是 Twomon SE 安装后的问题，查了一些资料，确定如下：&lt;br /&gt;
# 托盘区图标间隙变大，是因为系统认定当前在使用触摸式键盘。&lt;br /&gt;
#* “在触摸模式下，Windows 会在系统托盘（和其他UI）上留出空间，以便减少误点击图标的情况。”&lt;br /&gt;
# 系统托盘图标的间距，不受任何注册表项控制，它内置于程序中，不能更改。&lt;br /&gt;
#*“由explorer.exe应用程序中的编码控制。它是内部编码的，不依赖也不参考任何外部设置、控制或数据值来确定间距。改变它的唯一方法是反编译explorer.exe程序并重新编程文件。考虑到它是一个二进制文件，如果不访问源代码，这将是非常困难或不可能做到的。”&lt;br /&gt;
# 触摸屏设备，是“设备管理器 -&amp;gt; 人体学输入设备 -&amp;gt; 符合 HID 标准的触摸屏”（带 Touch Screen 或者触摸字样的设备）。&lt;br /&gt;
#* 通过禁用该设备可以使托盘区图标间隙恢复，但是，触摸设备也不能使用。（此处用的 iPad 就只能用作“显示屏”而不能用作“触摸屏”）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通过测试，可以把上述设备理器中的项“先禁用在启用”，使托盘区图标间隙恢复，且触摸正常使用，重启也没出现问题（可能使快速启动，没完全重启），算是曲线救国了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''参考：'''&lt;br /&gt;
# [https://answers.microsoft.com/zh-hans/windows/forum/all/%E4%BB%BB%E5%8A%A1%E6%A0%8F%E9%80%9A%E7%9F%A5/a4645ec6-343d-47c1-86cd-732a7536dac4 Microsoft Community：任务栏通知区域（托盘）图标间距变大]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/all/system-tray-icon-spacing-in-windows-10/6ab6e0dd-fe13-48e7-8eeb-c0d12abee6f3 Microsoft Community：System tray icon spacing in WIndows 10]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/tray-icons-reduce-spacing/93991e6b-5c53-4df5-af4e-3bdf3fde17fe Microsoft Community：Tray icons reduce spacing]&lt;br /&gt;
&lt;br /&gt;
== OpenVPN 问题 ==&lt;br /&gt;
 OpenVPN GUI 下载地址： '''https://openvpn.net/community-downloads/'''&lt;br /&gt;
&lt;br /&gt;
=== 设置密码自动填充 ===&lt;br /&gt;
使用 OpenVPN 连接时，每个连接第一次使用都需要输入用户名密码：&lt;br /&gt;
# 在配置文件“xxx.ovpn”的同级目录，添加“auth.txt”文件：第一行为用户，第二行为密码。&lt;br /&gt;
# 在配置文件“xxx.ovpn”中编辑：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
auth-user-pass auth.txt&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如此，不再需要手动填充用户密码信息。&lt;br /&gt;
&lt;br /&gt;
=== 未启动“OpenVPNServiceInteractive” ===&lt;br /&gt;
启动 OpenVPN GUI 时，出现如下提示：&lt;br /&gt;
: [[File:OpenVPN：未启动OpenVPNServiceInteractive.png|400px]]&lt;br /&gt;
&lt;br /&gt;
在 Windows 服务中，启动“'''OpenVPN Interactive Service'''”服务即可。&lt;br /&gt;
&lt;br /&gt;
== Vultr 验证页面 ==&lt;br /&gt;
打开 Vultr 登录页面，总是遇到如下页面，并不能成功跳转：&lt;br /&gt;
: [[File:Vultr：验证页面.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*【2021/11/24 19:23:13】试试不用代理打开，好像能成功。&lt;br /&gt;
&lt;br /&gt;
== Windows更新iTunes、iCloud失败 ==&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows更新iTunes、iCloud失败.png|400px]]&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 卸载该软件（iTunes/iCloud）；&lt;br /&gt;
# 卸载Apple相关的安装内容；&lt;br /&gt;
#* 包括：“Apple Mobile Device Surpport”、“Apple Software Update”、“Apple 应用程序支持(64位)”、“Apple 应用程序支持(32位)”、“Bonjour”；&lt;br /&gt;
# 重新执行安装程序；&lt;br /&gt;
&lt;br /&gt;
=== 安装iCloud时提示“您的电脑缺少媒体功能。请从Microsoft网站下载Media Feature Pack/Windows并安装，然后再试一次。” ===&lt;br /&gt;
解决：&lt;br /&gt;
: &amp;lt;s&amp;gt;“控制面板”-&amp;gt;“软件和功能”-&amp;gt;“启用或关闭Windows功能”：展开“媒体功能”-&amp;gt;勾选“windows media player”。&amp;lt;/s&amp;gt;&lt;br /&gt;
: “设置”-&amp;gt;“应用”-&amp;gt;“应用和功能”-&amp;gt;“管理可选功能”-&amp;gt;“添加功能”-&amp;gt;找到“Windows Media Player”并安装。&lt;br /&gt;
:* 安装完成，可以卸载“Windows Media Player”。&lt;br /&gt;
&lt;br /&gt;
== Steam ==&lt;br /&gt;
 在国内使用 Steam，登录、商店等内容是可以正常访问的（'''steampower.com'''），社区、个人资料等内容需要加速（'''steamcommunity.com'''）。&lt;br /&gt;
&lt;br /&gt;
=== 登录失败、商店错误代码:-324 ===&lt;br /&gt;
 如何开启了加速软件，但线路不通的时候，可能出现。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：'''取消网络代理'''&lt;br /&gt;
 &lt;br /&gt;
 （下面两个设置，其实是同一个东西）&lt;br /&gt;
&lt;br /&gt;
* 通过 IE 设置取消网络代理：&lt;br /&gt;
*# 打开IE -&amp;gt; “设置”-&amp;gt;“Internet选项”，在“连接”页找到“局域网设置”；&lt;br /&gt;
*#:（运行“inetcpl.cpl”可直接打开“Internet选项”页）&lt;br /&gt;
*# 取消勾选“'''自动配置'''”及“'''代理服务器'''”下的选项。&lt;br /&gt;
*: [[File:取消 IE 代理.png|400px]]&lt;br /&gt;
* 通过 Windows10 设置，取消“网络代理”：&lt;br /&gt;
*# 打开“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”；&lt;br /&gt;
*# 取消勾选“'''自动代理设置'''”及“'''手动设置代理'''”下的选项；&lt;br /&gt;
*: [[File:Windows设置：代理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 使用 Steam++ 加速 ===&lt;br /&gt;
 对于出现“'''错误代码：-118'''”等情况，很可能是服务地址被禁。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：通过 [https://steampp.net/ '''Steam++'''（Watt Toolkit）] 为 Steam 的单独、或所有服务加速。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Steam++：为Steam加速.png|600px]]&lt;br /&gt;
* 实测：加速模式中，“'''Hosts 代理模式'''”可正常使用，“DNS 驱动拦截”、“PAC 代理模式”时灵时不灵，“系统代理模式”没得用。&lt;br /&gt;
&lt;br /&gt;
 '''Steam++ 还可以为其他软件和服务加速。'''&lt;br /&gt;
 &lt;br /&gt;
 其代理加速具体设置信息可在“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”（如上节）中看到，可能无法和其他代理软件同时使用。&lt;br /&gt;
&lt;br /&gt;
== NVIDIA GeForce Experience 打不开 ==&lt;br /&gt;
 显卡更新频繁，但是 NVIDIA GeForce Experience 这***东西总是打不开（很多很多次），试过了：退出重启、杀进程、管理员启动、服务重启……不好使。&lt;br /&gt;
&lt;br /&gt;
直接去官网下载 NVIDIA GeForce Experience 覆盖安装吧。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
破****，***，**！&lt;br /&gt;
&lt;br /&gt;
 或者是有使用 GPU 的进程？？？下次试试把 WallpaperEngine 之类的软件关闭看看。&lt;br /&gt;
&lt;br /&gt;
== Duet不能连接 ==&lt;br /&gt;
 Windows 和 iPad 都打开了 duet 并连接，但是没反应。&lt;br /&gt;
 &lt;br /&gt;
 【先在 Windows 端关闭 Duet，在断开连接线，就不会出现该问题】&lt;br /&gt;
&amp;lt;s&amp;gt;在 Windows 设备管理器 -&amp;gt; 便携设备 -&amp;gt; Apple iPad ：禁用再启用，稍后就连接了。&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OneDrive使用 ==&lt;br /&gt;
 OneDrive 不同于其他的网盘同步软件：&lt;br /&gt;
 1、默认只能同步 Windows 提供的几个文件夹。&lt;br /&gt;
 2、同步的文件夹都会被强制移动到 OneDrive 文件夹中（默认：“C:\Users\XXX\OneDrive”） —— 原位置只留下链接（快捷方式）。&lt;br /&gt;
&lt;br /&gt;
要监听同步不同位置的文件夹，可以使用 '''&amp;lt;code&amp;gt;mklink&amp;lt;/code&amp;gt;''' 命令创建“'''符号链接'''”的方式：&lt;br /&gt;
: [[File:mklink命令.png|600px]]&lt;br /&gt;
* 文件夹依旧位于 Target 中，不会被强制移动。&lt;br /&gt;
* OneDrive 只留有 Link，不会有原文件占用大小 —— 仍会同步到云。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: [[File:mklink命令：示例.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 重置 OneDrive ===&lt;br /&gt;
 有时候 OneDrive 可能一直在“查找更改”，甚至托盘区右键也没反应，还可能连带着 Explorer 无响应。&lt;br /&gt;
&lt;br /&gt;
这种时候结束任务也无济于事，可以考虑“重置 OneDrive”&amp;lt;ref&amp;gt;参考：[https://support.microsoft.com/zh-cn/office/%E9%87%8D%E7%BD%AE-onedrive-34701e00-bf7b-42db-b960-84905399050c Microsoft支持：重置 OneDrive]&amp;lt;/ref&amp;gt;：&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; inline&amp;gt;wsreset.exe&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：清除 Microsoft Store 的临时文件、缓存和设置。（会打开 Microsoft Store 窗口，稍后关闭即可）&lt;br /&gt;
# 运行（&amp;lt;code&amp;gt;Windows&amp;lt;/code&amp;gt;+&amp;lt;code&amp;gt;R&amp;lt;/code&amp;gt;）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 以下命令，取决于 onedrive.exe 位置&lt;br /&gt;
&lt;br /&gt;
%localappdata%\Microsoft\OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft OneDrive\onedrive.exe /reset&lt;br /&gt;
&lt;br /&gt;
C:\Program Files (x86)\Microsoft OneDrive\onedrive.exe/reset&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 用于：重置 OneDrive。（执行时无任何窗口，执行完成后会有提示，稍候即可）&lt;br /&gt;
&lt;br /&gt;
 “同步挂起”：可能是由于某些“隐藏项目”导致，可以排查一下。&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E5%88%86%E7%B1%BB:%E7%BD%91%E7%BB%9C%E5%B7%A5%E5%85%B7&amp;diff=6656</id>
		<title>分类:网络工具</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E5%88%86%E7%B1%BB:%E7%BD%91%E7%BB%9C%E5%B7%A5%E5%85%B7&amp;diff=6656"/>
		<updated>2023-12-28T15:00:18Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* SS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Software]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 关于几种不同的工具，搜集了以下，空了看看：&lt;br /&gt;
 &lt;br /&gt;
 [https://wivwiv.com/post/ssr-v2ray-trojan/ 2021年SSR断流，V2ray被墙，Trojan？三大翻墙工具分析+一键脚本搭建安装]&lt;br /&gt;
 [https://freeroad.org/172.html Shadowsocks V2Ray Trojan有什么区别？哪种协议扶墙最靠谱？]&lt;br /&gt;
 [https://www.naplesblue.cc/8kmiao-kai-ce-shi-liao-trojanhe-v2rayde-su-du-zhi-hou-jue-ding-qi-yong/ 8K秒开？测试了Trojan和V2ray的速度之后，决定弃用。。。]&lt;br /&gt;
 [https://blog.awesome-doge.org/breaking-gfw-book/%E7%AA%81%E7%A0%B4%E9%98%B2%E7%81%AB%E5%A2%99%E5%B7%A5%E5%85%B7.html GFW Tool 简介]&lt;br /&gt;
 &lt;br /&gt;
 [https://tlanyan.pp.ua/introduce-v2ray-vless-protocol/ V2ray的VLESS协议介绍和使用教程]&lt;br /&gt;
 [https://v2xtls.org/v2ray%e5%a4%9a%e5%90%88%e4%b8%80%e8%84%9a%e6%9c%ac%ef%bc%8c%e6%94%af%e6%8c%81vmesswebsockettlsnginx%e3%80%81vlesstcpxtls%e3%80%81vlesstcptls%e7%ad%89%e7%bb%84%e5%90%88/ V2ray多合一脚本，支持VMESS+websocket+TLS+Nginx、VLESS+TCP+XTLS、VLESS+TCP+TLS等组合]&lt;br /&gt;
 [https://github.com/v2ray/discussion/issues/513 发现新大陆！！！！ #513]&lt;br /&gt;
 &lt;br /&gt;
 [https://www.lbtlm.com/archives/167 一次搞懂Xray/V2ray/Trojan/Trojan-go/SSR/SS的区别，不再选择困难症]&lt;br /&gt;
 [https://www.lbtlm.com/archives/172 一键安装七合一共存脚本+伪装站点Xray、Trojan-go、V2ray、Trojan科学上网]&lt;br /&gt;
&lt;br /&gt;
== SS ==&lt;br /&gt;
 关于 Docker：&lt;br /&gt;
 1、[https://github.com/Acris/docker-shadowsocks-libev Shadowsocks-libev Dockerfile]（Build a docker image for shadowsocks-libev with v2ray-plugin, based on Alpine Linux.）&lt;br /&gt;
 2、[https://www.aloneray.com/1279.html 【简单稳定】Vultr的购买和SS + v2ray-plugin +BBR的部署教程]&lt;br /&gt;
 3、[https://abcdsxg.cn/post/%E7%BB%99ss%E5%8A%A0%E4%B8%8Av2ray-plugin/ 给ss加上v2ray-Plugin]&lt;br /&gt;
&lt;br /&gt;
# [[SS]]&lt;br /&gt;
# [[SS：服务端]]&lt;br /&gt;
# [[SS：服务端（加速）]]&lt;br /&gt;
# [[SS：服务端（插件）]]&lt;br /&gt;
# [[SS：客户端]]&lt;br /&gt;
# [[FAQ:SS服务端]]&lt;br /&gt;
# [[FAQ:SS客户端]]&lt;br /&gt;
# [[CloudFlare使用]]&lt;br /&gt;
&lt;br /&gt;
== SSR ==&lt;br /&gt;
 参考：&lt;br /&gt;
 1、[https://wmovc.com/758/ Vultr搭建SSR梯子【2021年】新手快速科学上网（带BBR加速）]&lt;br /&gt;
 2、[https://viencoding.com/article/122 如何自己搭建SSR/SS服务端教程]&lt;br /&gt;
&lt;br /&gt;
== v2ray ==&lt;br /&gt;
 参考：&lt;br /&gt;
 1、[https://github.com/v2ray v2ray 项目官网]&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6655</id>
		<title>FAQ:Software</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Software&amp;diff=6655"/>
		<updated>2023-12-28T14:53:26Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* Duet不能连接 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Software]]&lt;br /&gt;
&lt;br /&gt;
== office官方卸载工具 ==&lt;br /&gt;
卸载office官方工具：[https://support.microsoft.com/en-us/office/uninstall-office-from-a-pc-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8 Uninstall Microsoft Office]&lt;br /&gt;
&lt;br /&gt;
== 卸载Visio密钥 ==&lt;br /&gt;
安装Visio之后，填入了密钥之后无法激活，想要修改密钥但发现界面没有修改框，所以只有向其他办法：&lt;br /&gt;
# regedit：开始以为使用的key都保存在注册表中，找了一圈并没有找到&lt;br /&gt;
# ？命令行修改，类似于之前查看Windows激活信息的命令&lt;br /&gt;
&lt;br /&gt;
=== 查看许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /dstatus&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
PRODUCT ID: 00341-31872-32451-AA593&lt;br /&gt;
SKU ID: 2dfe2075-2d04-4e43-816a-eb60bbb77574&lt;br /&gt;
LICENSE NAME: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
LICENSE DESCRIPTION: Office 16, RETAIL channel&lt;br /&gt;
BETA EXPIRATION: 1601/1/1&lt;br /&gt;
LICENSE STATUS:  ---OOB_GRACE---&lt;br /&gt;
ERROR CODE: 0x4004F00C&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the application is running within the valid grace period.&lt;br /&gt;
REMAINING GRACE: 29 days  (43147 minute(s) before expiring)&lt;br /&gt;
Last 5 characters of installed product key: DPFJH&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 安装的产品密钥： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /inpkey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 刷新许可证信息列表： ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /rearm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 卸载已安装的产品密钥： ===&lt;br /&gt;
* “unpkey”后的内容为密钥的最后5位数&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
&amp;lt;Product key uninstall successful&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 找不到对应的unpkey时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:AA593&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
&amp;lt;Product key not found&amp;gt;&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# cmd未使用管理员权限时：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;PowerShell&amp;quot;&amp;gt;&lt;br /&gt;
C:\Program Files (x86)\Microsoft Office\Office16&amp;gt;cscript ospp.vbs /unpkey:DPFJH&lt;br /&gt;
Microsoft (R) Windows Script Host Version 5.812&lt;br /&gt;
版权所有(C) Microsoft Corporation。保留所有权利。&lt;br /&gt;
&lt;br /&gt;
---Processing--------------------------&lt;br /&gt;
---------------------------------------&lt;br /&gt;
Uninstalling product key for: Office 16, Office16VisioProR_Retail edition&lt;br /&gt;
ERROR CODE: 0xC004F025&lt;br /&gt;
ERROR DESCRIPTION: The Software Licensing Service reported that the action requires administrator privilege.&lt;br /&gt;
---------------------------------------&lt;br /&gt;
---Exiting-----------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== notepad++ 自动保存位置 ==&lt;br /&gt;
notepad++ 会自动定期保存文件，所以没有手动保存为文件的内容也能够在关闭notepad++的下一次自动显示；&lt;br /&gt;
&lt;br /&gt;
如果关闭notepad++重新打开之后，上次没有手动保存的内容没有显示也不用慌，可以在'''&amp;quot;C:\Users\eijux\AppData\Roaming\Notepad++\backup&amp;quot;'''下自动定期保存的文件中找到。&lt;br /&gt;
&lt;br /&gt;
== 删除多余 Hyper-V Virtual Ethernet Adapter ==&lt;br /&gt;
在使用VBox的过程中，每次遇到更新、重装，都会导致多出虚拟网卡适配器：&lt;br /&gt;
:[[File:多余的虚拟网卡适配器.png|600px]]&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;s&amp;gt;方法一：&lt;br /&gt;
#: 在系统设置网络连接部分又不能直接删除，所以找到了一个从注册表删除的方法：&amp;lt;br/&amp;gt;&lt;br /&gt;
#: 在“'''计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ROOT\VMS_MP'''”中找到多余的项删除即可：&lt;br /&gt;
#: [[File:删除多余虚拟网卡适配器.png|600px]]&lt;br /&gt;
#: 【好像不求好使，以前是在注册表删除的，好像不是这】&amp;lt;/s&amp;gt;&lt;br /&gt;
# 方法二：&lt;br /&gt;
#: 在适配器列表（控制面板-&amp;gt;网络和共享中心-&amp;gt;更改适配器设置），右键“属性”，选择“配置”，到“驱动程序”页，选择“卸载设备”即可。&lt;br /&gt;
&lt;br /&gt;
== 安装“Twomon SE”后托盘区图标间隙变大 ==&lt;br /&gt;
由于想把 iPad 当作 Windows 的拓展屏幕使用，比较多个软件之后，购买了 Twomon SE，但在安装 PC 端之后，突然发现托盘区的图标间隙变得很大很大：&lt;br /&gt;
: [[File:Windows托盘区图标间隙.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
强迫症不能忍，能够确定是 Twomon SE 安装后的问题，查了一些资料，确定如下：&lt;br /&gt;
# 托盘区图标间隙变大，是因为系统认定当前在使用触摸式键盘。&lt;br /&gt;
#* “在触摸模式下，Windows 会在系统托盘（和其他UI）上留出空间，以便减少误点击图标的情况。”&lt;br /&gt;
# 系统托盘图标的间距，不受任何注册表项控制，它内置于程序中，不能更改。&lt;br /&gt;
#*“由explorer.exe应用程序中的编码控制。它是内部编码的，不依赖也不参考任何外部设置、控制或数据值来确定间距。改变它的唯一方法是反编译explorer.exe程序并重新编程文件。考虑到它是一个二进制文件，如果不访问源代码，这将是非常困难或不可能做到的。”&lt;br /&gt;
# 触摸屏设备，是“设备管理器 -&amp;gt; 人体学输入设备 -&amp;gt; 符合 HID 标准的触摸屏”（带 Touch Screen 或者触摸字样的设备）。&lt;br /&gt;
#* 通过禁用该设备可以使托盘区图标间隙恢复，但是，触摸设备也不能使用。（此处用的 iPad 就只能用作“显示屏”而不能用作“触摸屏”）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通过测试，可以把上述设备理器中的项“先禁用在启用”，使托盘区图标间隙恢复，且触摸正常使用，重启也没出现问题（可能使快速启动，没完全重启），算是曲线救国了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''参考：'''&lt;br /&gt;
# [https://answers.microsoft.com/zh-hans/windows/forum/all/%E4%BB%BB%E5%8A%A1%E6%A0%8F%E9%80%9A%E7%9F%A5/a4645ec6-343d-47c1-86cd-732a7536dac4 Microsoft Community：任务栏通知区域（托盘）图标间距变大]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/all/system-tray-icon-spacing-in-windows-10/6ab6e0dd-fe13-48e7-8eeb-c0d12abee6f3 Microsoft Community：System tray icon spacing in WIndows 10]&lt;br /&gt;
# [https://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/tray-icons-reduce-spacing/93991e6b-5c53-4df5-af4e-3bdf3fde17fe Microsoft Community：Tray icons reduce spacing]&lt;br /&gt;
&lt;br /&gt;
== OpenVPN 问题 ==&lt;br /&gt;
 OpenVPN GUI 下载地址： '''https://openvpn.net/community-downloads/'''&lt;br /&gt;
&lt;br /&gt;
=== 设置密码自动填充 ===&lt;br /&gt;
使用 OpenVPN 连接时，每个连接第一次使用都需要输入用户名密码：&lt;br /&gt;
# 在配置文件“xxx.ovpn”的同级目录，添加“auth.txt”文件：第一行为用户，第二行为密码。&lt;br /&gt;
# 在配置文件“xxx.ovpn”中编辑：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
auth-user-pass auth.txt&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如此，不再需要手动填充用户密码信息。&lt;br /&gt;
&lt;br /&gt;
=== 未启动“OpenVPNServiceInteractive” ===&lt;br /&gt;
启动 OpenVPN GUI 时，出现如下提示：&lt;br /&gt;
: [[File:OpenVPN：未启动OpenVPNServiceInteractive.png|400px]]&lt;br /&gt;
&lt;br /&gt;
在 Windows 服务中，启动“'''OpenVPN Interactive Service'''”服务即可。&lt;br /&gt;
&lt;br /&gt;
== Vultr 验证页面 ==&lt;br /&gt;
打开 Vultr 登录页面，总是遇到如下页面，并不能成功跳转：&lt;br /&gt;
: [[File:Vultr：验证页面.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*【2021/11/24 19:23:13】试试不用代理打开，好像能成功。&lt;br /&gt;
&lt;br /&gt;
== Windows更新iTunes、iCloud失败 ==&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows更新iTunes、iCloud失败.png|400px]]&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 卸载该软件（iTunes/iCloud）；&lt;br /&gt;
# 卸载Apple相关的安装内容；&lt;br /&gt;
#* 包括：“Apple Mobile Device Surpport”、“Apple Software Update”、“Apple 应用程序支持(64位)”、“Apple 应用程序支持(32位)”、“Bonjour”；&lt;br /&gt;
# 重新执行安装程序；&lt;br /&gt;
&lt;br /&gt;
=== 安装iCloud时提示“您的电脑缺少媒体功能。请从Microsoft网站下载Media Feature Pack/Windows并安装，然后再试一次。” ===&lt;br /&gt;
解决：&lt;br /&gt;
: &amp;lt;s&amp;gt;“控制面板”-&amp;gt;“软件和功能”-&amp;gt;“启用或关闭Windows功能”：展开“媒体功能”-&amp;gt;勾选“windows media player”。&amp;lt;/s&amp;gt;&lt;br /&gt;
: “设置”-&amp;gt;“应用”-&amp;gt;“应用和功能”-&amp;gt;“管理可选功能”-&amp;gt;“添加功能”-&amp;gt;找到“Windows Media Player”并安装。&lt;br /&gt;
:* 安装完成，可以卸载“Windows Media Player”。&lt;br /&gt;
&lt;br /&gt;
== Steam ==&lt;br /&gt;
 在国内使用 Steam，登录、商店等内容是可以正常访问的（'''steampower.com'''），社区、个人资料等内容需要加速（'''steamcommunity.com'''）。&lt;br /&gt;
&lt;br /&gt;
=== 登录失败、商店错误代码:-324 ===&lt;br /&gt;
 如何开启了加速软件，但线路不通的时候，可能出现。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：'''取消网络代理'''&lt;br /&gt;
 &lt;br /&gt;
 （下面两个设置，其实是同一个东西）&lt;br /&gt;
&lt;br /&gt;
* 通过 IE 设置取消网络代理：&lt;br /&gt;
*# 打开IE -&amp;gt; “设置”-&amp;gt;“Internet选项”，在“连接”页找到“局域网设置”；&lt;br /&gt;
*#:（运行“inetcpl.cpl”可直接打开“Internet选项”页）&lt;br /&gt;
*# 取消勾选“'''自动配置'''”及“'''代理服务器'''”下的选项。&lt;br /&gt;
*: [[File:取消 IE 代理.png|400px]]&lt;br /&gt;
* 通过 Windows10 设置，取消“网络代理”：&lt;br /&gt;
*# 打开“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”；&lt;br /&gt;
*# 取消勾选“'''自动代理设置'''”及“'''手动设置代理'''”下的选项；&lt;br /&gt;
*: [[File:Windows设置：代理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 使用 Steam++ 加速 ===&lt;br /&gt;
 对于出现“'''错误代码：-118'''”等情况，很可能是服务地址被禁。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 解决：通过 [https://steampp.net/ '''Steam++'''（Watt Toolkit）] 为 Steam 的单独、或所有服务加速。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Steam++：为Steam加速.png|600px]]&lt;br /&gt;
* 实测：加速模式中，“'''Hosts 代理模式'''”可正常使用，“DNS 驱动拦截”、“PAC 代理模式”时灵时不灵，“系统代理模式”没得用。&lt;br /&gt;
&lt;br /&gt;
 '''Steam++ 还可以为其他软件和服务加速。'''&lt;br /&gt;
 &lt;br /&gt;
 其代理加速具体设置信息可在“Windows 设置 -&amp;gt; 网络和Internet -&amp;gt; 代理”（如上节）中看到，可能无法和其他代理软件同时使用。&lt;br /&gt;
&lt;br /&gt;
== NVIDIA GeForce Experience 打不开 ==&lt;br /&gt;
 显卡更新频繁，但是 NVIDIA GeForce Experience 这***东西总是打不开（很多很多次），试过了：退出重启、杀进程、管理员启动、服务重启……不好使。&lt;br /&gt;
&lt;br /&gt;
直接去官网下载 NVIDIA GeForce Experience 覆盖安装吧。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
破****，***，**！&lt;br /&gt;
&lt;br /&gt;
 或者是有使用 GPU 的进程？？？下次试试把 WallpaperEngine 之类的软件关闭看看。&lt;br /&gt;
&lt;br /&gt;
== Duet不能连接 ==&lt;br /&gt;
 Windows 和 iPad 都打开了 duet 并连接，但是没反应。&lt;br /&gt;
 &lt;br /&gt;
 【先在 Windows 端关闭 Duet，在断开连接线，就不会出现该问题】&lt;br /&gt;
&amp;lt;s&amp;gt;在 Windows 设备管理器 -&amp;gt; 便携设备 -&amp;gt; Apple iPad ：禁用再启用，稍后就连接了。&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OneDrive使用 ==&lt;br /&gt;
 OneDrive 不同于其他的网盘同步软件：&lt;br /&gt;
 1、默认只能同步 Windows 提供的几个文件夹。&lt;br /&gt;
 2、同步的文件夹都会被强制移动到 OneDrive 文件夹中（默认：“C:\Users\XXX\OneDrive”） —— 原位置只留下链接（快捷方式）。&lt;br /&gt;
&lt;br /&gt;
要监听同步不同位置的文件夹，可以使用 '''&amp;lt;code&amp;gt;mklink&amp;lt;/code&amp;gt;''' 命令创建“'''符号链接'''”的方式：&lt;br /&gt;
: [[File:mklink命令.png|600px]]&lt;br /&gt;
* 文件夹依旧位于 Target 中，不会被强制移动。&lt;br /&gt;
* OneDrive 只留有 Link，不会有原文件占用大小 —— 仍会同步到云。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: [[File:mklink命令：示例.png|600px]]&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%E5%91%BD%E4%BB%A4%EF%BC%9A%E7%A4%BA%E4%BE%8B.png&amp;diff=6654</id>
		<title>文件:Mklink命令：示例.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%E5%91%BD%E4%BB%A4%EF%BC%9A%E7%A4%BA%E4%BE%8B.png&amp;diff=6654"/>
		<updated>2023-12-28T14:52:23Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%E5%91%BD%E4%BB%A4.png&amp;diff=6653</id>
		<title>文件:Mklink命令.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%E5%91%BD%E4%BB%A4.png&amp;diff=6653"/>
		<updated>2023-12-28T14:47:48Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​Eijux上传文件:Mklink命令.png的新版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%E5%91%BD%E4%BB%A4.png&amp;diff=6652</id>
		<title>文件:Mklink命令.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:Mklink%E5%91%BD%E4%BB%A4.png&amp;diff=6652"/>
		<updated>2023-12-28T14:46:10Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6651</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6651"/>
		<updated>2023-12-25T09:35:41Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 关于“desktop.ini”文件 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是是系统可识别的一个文件，作用是存储'''用户对文件夹的个性设置'''（用户更换文件夹图标等等都会生成 desktop.ini）。&lt;br /&gt;
 &lt;br /&gt;
 在一些系统文件夹（如，桌面、文档、下载、图片、音乐、视频等）中广泛存在。&lt;br /&gt;
&lt;br /&gt;
在移动这些系统文件夹位置的时候，可能会丢失“desktop.ini”文件，就会造成某些配置的丢失 —— 如，移动或重新制定“下载”文件夹路径后，显示为“Downloads”（而非随系统语言而显示如“下载”等），且默认图标等也会发生变化。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
修复“desktop.ini”文件，步骤：&lt;br /&gt;
# 创建“desktop.ini”文件（从其他电脑/用户路径中拷贝也行）&lt;br /&gt;
#* 桌面：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21769&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 文档：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21770&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-112&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-235&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 下载：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-184&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 图片：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-113&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 音乐：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-108&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-237&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 视频：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21791&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12690&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-189&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-238&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 修改“desktop.ini”文件的'''属性'''：&lt;br /&gt;
#: 在文件所在位置打开 Terminal（&amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; + 右键），并运行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
# 增加“只读文件”、“系统文件”、“隐藏文件”属性&lt;br /&gt;
attrib +R +S +H &amp;quot;desktop.ini&amp;quot; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 重启 explorer。&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6650</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6650"/>
		<updated>2023-12-25T09:22:21Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 关于“desktop.ini”文件 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是是系统可识别的一个文件，作用是存储'''用户对文件夹的个性设置'''（用户更换文件夹图标等等都会生成 desktop.ini）。&lt;br /&gt;
 &lt;br /&gt;
 在一些系统文件夹（如，桌面、文档、下载、图片、音乐、视频等）中广泛存在。&lt;br /&gt;
&lt;br /&gt;
在移动这些系统文件夹位置的时候，可能会丢失“desktop.ini”文件，就会造成某些配置的丢失 —— 如，移动或重新制定“下载”文件夹路径后，显示为“Downloads”（而非随系统语言而显示如“下载”等），且默认图标等也会发生变化。&lt;br /&gt;
&lt;br /&gt;
修复“desktop.ini”文件，步骤：&lt;br /&gt;
# 创建“desktop.ini”文件（从其他电脑/用户路径中拷贝也行）&lt;br /&gt;
#* 桌面：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21769&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 文档：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21770&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-112&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-235&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 下载：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21798&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-184&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 图片：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-113&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-236&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 音乐：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21790&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12689&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-108&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-237&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 视频：&lt;br /&gt;
#*: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[.ShellClassInfo]&lt;br /&gt;
LocalizedResourceName=@%SystemRoot%\system32\windows.storage.dll,-21791&lt;br /&gt;
InfoTip=@%SystemRoot%\system32\shell32.dll,-12690&lt;br /&gt;
IconResource=%SystemRoot%\system32\imageres.dll,-189&lt;br /&gt;
IconFile=%SystemRoot%\system32\shell32.dll&lt;br /&gt;
IconIndex=-238&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 修改“desktop.ini”文件的'''属性'''：&lt;br /&gt;
#: 在文件所在位置打开 Terminal（&amp;lt;code&amp;gt;shift&amp;lt;/code&amp;gt; + 右键），并运行：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
# 增加“只读文件”、“系统文件”、“隐藏文件”属性&lt;br /&gt;
attrib +R +S +H &amp;quot;desktop.ini&amp;quot; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 重启 explorer。&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6649</id>
		<title>FAQ:Windows</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=FAQ:Windows&amp;diff=6649"/>
		<updated>2023-12-25T08:29:15Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 查看连接过的 Wifi 密码 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Windows]]&lt;br /&gt;
&lt;br /&gt;
== 系统信息 ==&lt;br /&gt;
查看系统信息，运行：&amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;msinfo32&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 【备份】BIOS 系统信息 ==&lt;br /&gt;
: [[File:BIOS：系统信息.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== 任务管理器中有未知启动项不能删除 ==&lt;br /&gt;
如图：&lt;br /&gt;
:[[File:不能删除的未知启动项.png|600px]]&lt;br /&gt;
* 右键“打开文件所在位置”、“属性”不能打开。&lt;br /&gt;
* 使用“CCleaner”、“Dism++”等，均不能直接删除。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
后来，在使用“Dism++”清理系统时，对照任务管理器，发现该项实际为：&lt;br /&gt;
:[[File:Dism++查看启动项.png|600px]]&lt;br /&gt;
由此，得到该启动项位置：“'''C:\Users\eijux\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\'''”&lt;br /&gt;
*【'''部分启动项的位置'''在此，备忘】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
删除该项即可。&lt;br /&gt;
&lt;br /&gt;
== 文件所有者“'''TrustedInstaller'''” ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，在 Windows 中拥有修改系统文件权限，本身是一个服务，以一个账户组的形式出现。&lt;br /&gt;
&lt;br /&gt;
它的全名是：【NT SERVICE\TrustedInstaller】，从名字中我们不难发现，这其实是 NT 服务，并非一个实际存在的用户组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    自从 Windows Vista 以来，为了提升安全性，微软对于权限的把控越来越紧。为了对抗恶意软件随意修改系统文件，Trustedinstaller 应运而生。TrustedInstaller 是从 Windows Vista 开始出现的一个内置安全主体，它的本体是 “Windows Modules Installer” 服务。在 Windows 中拥有修改系统文件权限，以一个用户组的形式出现。通常情况下，在使用 Windows Update 安装系统更新，开启关闭 Windows 功能时起非常重要的作用。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows 的某些系统文件夹的所有者是“TrustedInstaller”，有时候我们需要获取文件夹或文件的管理员权限，从而修改其“所有者”。&lt;br /&gt;
: [[File:文件(夹)的所有者为“TrustedInstaller”.png|600px]]&lt;br /&gt;
&lt;br /&gt;
但是，如果再想更改为 TrustedInstaller 时，我们会发现“选择用户或组”页面进行“立即查找”后，所给出的“用户或组”的列表中并没有“TrustedInstaller”。（“计算机管理”-&amp;gt;“本地用户和组”中也看不到该组）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这时，只需在“选择用户或组”页面直接输入其全名&amp;lt;big&amp;gt;“'''NT SERVICE\TrustedInstaller'''”&amp;lt;/big&amp;gt;即可。（只输入“TrustedInstaller”无法完成命令）&lt;br /&gt;
: [[File:更改所有者为“TrustedInstaller”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
具体步骤:&lt;br /&gt;
# 打开文件夹“属性”，切换到“安全”标签页，单击“高级”；&lt;br /&gt;
# 在“所有者”项后单击“更改”；&lt;br /&gt;
# 在“选择用户或组”窗口，输入“NT SERVICE\TrustedInstaller”，单击“确定”按钮。&lt;br /&gt;
&lt;br /&gt;
== 不能删除文件 ==&lt;br /&gt;
 Windows 删除某些文件时，会出现各种各样的错误，比如“该项目不在路径中”，或文件权限错误等等。&lt;br /&gt;
&lt;br /&gt;
在删除 mediawiki 的文件夹时也出现了类似问题：&lt;br /&gt;
: （mediawiki的这类“xxx.”的文件都不能删除、移动，直接向服务器上传该文件也失败。）&lt;br /&gt;
: （简而言之就是权限出错，无法操作）&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[File:无法删除的文件.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件2.png|400px]]&lt;br /&gt;
|[[File:无法删除的文件3.png|thumb|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
解决：&lt;br /&gt;
# 建立“强制删除文件夹.bat”（参见[http://wiki.eijux.com/%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4:Windows#DEL_.E4.B8.8E_RD del 与 rd]）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
del /F /S /Q \\?\%1&lt;br /&gt;
rd /S /Q \\?\%1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将不能删除的文件或文件夹直接拖到该bat上，就能强制删除。&lt;br /&gt;
#* 但是对于上图的文件，只能拖动删除文件所在文件夹，不能直接删除文件（？安全信息错误显得特殊？）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 '''另外的思路，用 [http://wiki.eijux.com/Sysinternals#SDelete SDelete] 删除。（未尝试）'''&lt;br /&gt;
&lt;br /&gt;
== “编辑环境变量”以【列表】展示 ==&lt;br /&gt;
如果环境变量的值：&lt;br /&gt;
# 以“'''%'''”或“'''.'''”开头，编辑时就会显示为文本框；&lt;br /&gt;
#: [[File:Windows10环境变量——文本框展示.png|400px]]&lt;br /&gt;
# 以'''盘符'''开始，编辑时就会展示为列表；&lt;br /&gt;
#: [[File:Windows10环境变量——列表展示.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== MicrosoftStore下载很慢==&lt;br /&gt;
 Microsoft Store 下载很慢的时候，禁用（关闭）系统代理就行&lt;br /&gt;
&lt;br /&gt;
== 查看错误日志 ==&lt;br /&gt;
 Windows + X，选择“'''事件查看器'''”：&lt;br /&gt;
     在此处查看系统、应用、服务的日志信息。&lt;br /&gt;
&lt;br /&gt;
== '''查看当前电池使用情况''' ==&lt;br /&gt;
两种方法：&lt;br /&gt;
# 使用 '''AIDA64'''。&lt;br /&gt;
#* 一个运行在 Microsoft Windows 操作系统上的系统信息、诊断和审计程序，用于显示计算机的组件的详细信息。&lt;br /&gt;
# 命令行（管理员权限）：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
powercfg /batteryreport /output &amp;quot;C:\battery_report.html&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:cmd查看电池使用情况.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== '''CPU 使用率飘忽''' ==&lt;br /&gt;
 CPU 的使用率总是莫名其妙地忽高忽低，在待机情况下，没有任务时依旧。&lt;br /&gt;
&lt;br /&gt;
=== X Boost ===&lt;br /&gt;
 '''X Boost'''：&lt;br /&gt;
 USB Boost：支持 USB 存储设备更快的数据传输速率。&lt;br /&gt;
 Storage Boost: 支持更快的存储设备访问速度。&lt;br /&gt;
&lt;br /&gt;
通过网络，建议将 '''MSI Dragon Center''' 的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''X Boost'''&amp;lt;/span&amp;gt; 功能关闭，目前情况有所改善。&lt;br /&gt;
: [[File:MSI_Dragon_Center：系统环境设置.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 优化：设置和服务 ===&lt;br /&gt;
 以下是通过网络查询到的可能的优化方法，另外还可以通过“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''Dism++'''&amp;lt;/span&amp;gt;”（系统优化 -&amp;gt; 服务优化）来进行更多优化。&lt;br /&gt;
&lt;br /&gt;
【'''已经应用'''】：&lt;br /&gt;
# 关闭“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''反馈'''&amp;lt;/span&amp;gt;”功能：&lt;br /&gt;
#: 步骤：“设置 -&amp;gt; 隐私：诊断和反馈”，将“'''反馈频率'''”修改为“'''从不'''”。&lt;br /&gt;
# 禁用“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Connected User Experiences and Telemetry'''（已连接的用户体验和遥测服务）&amp;lt;/span&amp;gt;”服务：&lt;br /&gt;
#: 该服务将根据事件来管理诊断和使用情况信息的收集和传输（用于改进 Windows 平台的体验和质量）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
【'''暂未使用'''】：（貌似不需要）&lt;br /&gt;
# 禁用“'''诊断相关服务'''”：用于支持 Windows 的诊断，涉及“问题检测、疑难解答和解决方案”的相关服务。&lt;br /&gt;
#: 包括：“Diagnostic Execution Service”、“Diagnostic Policy Service”、“Diagnostic Service Host”和“Diagnostic System Host”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 另外：在“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务管理器：应用历史记录&amp;lt;/span&amp;gt;'''”中，将“'''CPU 时间'''”过多的应用（此处显示的都是 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Microsoft APP'''&amp;lt;/span&amp;gt;）限制运行或禁止掉。&lt;br /&gt;
 &lt;br /&gt;
 （已经发现：可能由于“'''反馈中心'''”、“'''Microsoft 照片'''”等的后台运行时间过长，导致 CPU 使用率居高不下）&lt;br /&gt;
&lt;br /&gt;
== CPU 温度过高 ==&lt;br /&gt;
 前情提要：&lt;br /&gt;
 今天装了 WallpaperEngine，在尝试某些“场景”、“视频”、“网页”时，GPU明显受到压力，卡顿严重（尤其是“应用程序”）。&lt;br /&gt;
 由于默认使用的核显，所以直接导致 CPU 温度升高，风扇狂转。&lt;br /&gt;
 改为使用独显之后，仍然 CPU 温度居高不下。&lt;br /&gt;
 （清灰之后依旧）&lt;br /&gt;
&lt;br /&gt;
 突然注意到 CPU 的频率是要高于基准频率的，不用说，自动睿频了，但是疑惑的是此时 CPU 压力并不高（30-40%？）&lt;br /&gt;
 不知道是什么原因导致睿频，还是之前任务睿频后没有降频？&lt;br /&gt;
 &lt;br /&gt;
 （之前频率为 3.4，温度在 70-90 左右）&lt;br /&gt;
通过 MSI Dragon Center 将 ECO 模式改为 Sport 模式，过几分钟再改回 ECO 模式，才使频率将为 1.39 （如图），温度在 40-60 左右。&lt;br /&gt;
: [[File:CPU频率.png|400px]]&lt;br /&gt;
&lt;br /&gt;
 由于是轻薄本，所以散热格外不好，风扇格外吵，只能想想能不能限制 CPU 频率了：&lt;br /&gt;
 1、通过高级电源设置限制 CPU 频率，并不好使！&lt;br /&gt;
 2、MSI 禁止睿频，好像是在 BIOS 中？？？&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;s&amp;gt;高级电源设置：限制 CPU 最高频率&amp;lt;/s&amp;gt; ===&lt;br /&gt;
 很多伙伴建议，日常办公生活使用，可以将最大处理器状态设置为'''99'''。&lt;br /&gt;
 &lt;br /&gt;
 '''100'''：代表处理器自动超频（非睿频）；&lt;br /&gt;
 '''99'''：代表默认处理器正常使用。&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;s&amp;gt;[[File:电源管理：CPU最大状态.png|400px]]&amp;lt;/s&amp;gt;&lt;br /&gt;
&amp;lt;s&amp;gt;将电源管理中，“最大处理器状态”改为 99（网络上看到有效降温，性能降低不明显）&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;【亲测，不好使】&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 '''现象：'''最小CPU状态设置失效，无论是99还是0，均不能控制CPU频率，CPU一直以最高频率运行。或者重启之后，方案失效，CPU一直高功率运行。&lt;br /&gt;
 &lt;br /&gt;
 '''原因：'''频繁修改电源方案失效、未知选项控制电源方案、可视化设置失效。如果到了这一步，还是无法解决，非系统爱好者、PC从业者，可以选择重装系统解决，爱好者可以详细了解 '''POWERCFG''' 命令，在 power shell 中，利用“'''&amp;lt;code&amp;gt;powercfg /?&amp;lt;/code&amp;gt;'''”来详细了解每一项可能解决的设置。&lt;br /&gt;
 &lt;br /&gt;
 '''解决：'''利用“'''POWERCFG -IMPORT'''”（“&amp;lt;code&amp;gt;powercfg -import “Full path of .pow file&amp;lt;/code&amp;gt;”）来替换自己系统内，电源方案文件。&lt;br /&gt;
&lt;br /&gt;
=== MSI Dragon Center 的“Shift”变档模式 ===&lt;br /&gt;
 机器：MSI GS63 7RE-010CN&lt;br /&gt;
 CPU：i7-7700HQ&lt;br /&gt;
 显卡：GeForce1050TI&lt;br /&gt;
&lt;br /&gt;
# “'''Turbo'''”：自定义超频；&lt;br /&gt;
#* CPU 如果后缀带 K（不锁倍频）才可以超频，否则仅提供 GPU 超频；&lt;br /&gt;
# “'''Sport'''”：全面释放 CPU、GPU 性能；【高性能】&lt;br /&gt;
#* CUP 占用率会固定显示 100%。&lt;br /&gt;
#* 对于不可超频的CPU，默认为该模式。&lt;br /&gt;
# “'''Comfort'''”：平衡模式；【默认】&lt;br /&gt;
#* CPU 会自动睿频，一般在 3.4 左右。&lt;br /&gt;
# “'''ECO'''”：节能模式；【低功耗】&lt;br /&gt;
#* CPU 频率固定在 1.39。&lt;br /&gt;
# “'''Power Options'''”：根据电源管理调节；&lt;br /&gt;
* Turbo Mode/ Sport Mode/ Comfort Mode 三种选项只有在插上 AC 电源时方能选用；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 一直“ECO”模式（高级设置，风扇可以不用转），在开机的时候 CPU 频率在基准频率 2.8 左右，一会儿（打开 Dragon Center）就固定在了 1.39 左右。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;s&amp;gt;暂时不清楚，是因为 Dragon Center 启动了会固定 ECO 的 1.39，还是 ECO 也会在高压力时短暂提升频率。&amp;lt;/s&amp;gt;&lt;br /&gt;
 【其频率还是会随 CPU 使用率变动，并不是固定在一个数值】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;'''&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;如果 CPU 压力小但频率一直太高，尝试在 Dragon Center 中，将“Shift”切换到其他模式，再切换回“ECO”。&amp;lt;/span&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MSI 启用 '''TPM2.0''' ==&lt;br /&gt;
=== 什么是 TPM ===&lt;br /&gt;
 TPM（可信赖平台模块）是关于安全处理的通用标准，是一种专用微控制器，可通过集成的加密密钥保护硬件。目前，TPM的新版本是2.0。&lt;br /&gt;
 TPM作为硬件安全密钥具有广泛的作用，例如设备识别、身份验证、加密和完整性验证。&lt;br /&gt;
 &lt;br /&gt;
 简而言之，TPM主要做两件事：&lt;br /&gt;
 &lt;br /&gt;
 1、密钥计算：也就是说，使用其内置的加密算法在计算机中生成或验证密码。这些密码可以是硬盘的加密锁、操作系统用来验证其完整性的特征代码（检查程序是否被篡改），或者是专用软件的激活码。&lt;br /&gt;
 2、密钥存储：TPM本身也是计算机中的一块加密存储单元，不只可以计算密钥，还可以存储密钥。并且由于TPM采用了专用的电路，整个计算和存储过程无需经过内存，在硬盘中不留痕迹，因此密钥生成、验证和存储的安全性非常高。&lt;br /&gt;
&lt;br /&gt;
=== 验证是否支持 TPM2.0 ===&lt;br /&gt;
 运行：&amp;lt;big&amp;gt;'''tpm.msc'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 不支持（未启用）：&lt;br /&gt;
*:[[File:TPM2.0（未启用）.png|500px]]&lt;br /&gt;
* 支持（已启用）：&lt;br /&gt;
*:[[File:TPM2.0（已启用）.png|500px]]&lt;br /&gt;
&lt;br /&gt;
=== MSI BIOS 开启 TPM 支持（隐藏选项） ===&lt;br /&gt;
 在 Intel 八代 U 之后都内置了 TPM。 ——一直以为老的电脑上没有 TPM 芯片，今天在网上查了资料后尝试了下，成功开启了 TPM（默认关闭）。&lt;br /&gt;
&lt;br /&gt;
# 进入 BIOS 后，按照“'''右ctrl''' + '''右shift''' + '''左alt''' + '''F2'''”显示隐藏选项，才能看到该内容。&lt;br /&gt;
#* 未显示隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（未显示隐藏选项）.jpg|400px]] [[File:BIOS：安全性（未显示隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
#* 显示了隐藏选项：&lt;br /&gt;
#*: [[File:BIOS：高级选项（显示了隐藏选项）.jpg|400px]] [[File:BIOS：安全性（显示了隐藏选项）.jpg.jpg|400px]]&lt;br /&gt;
# 在 tab 页“安全性”下，进入“'''Trusted Commputing'''”菜单，将“'''Security Device Support'''”设置为“Enable”，保存并重启。&lt;br /&gt;
#* 重启后再次该菜单，即可看到已开启的相关内容，确保“TPM2.0 UEFI Spec Version”为“TCG_2”即可。&lt;br /&gt;
#*: [[File:BIOS：已启用TPM2.0.jpg|400px]] [[File:BIOS：TPM2.0选项.jpg|500px]]&lt;br /&gt;
&lt;br /&gt;
== Windows：检测、修复系统源文件 ==&lt;br /&gt;
 在管理员命令提示符下键入以下命令。&lt;br /&gt;
# 这条命令将扫描全部系统文件并和官方系统文件对比，扫描计算机中的不一致情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /ScanHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令必须在前一条命令执行完以后，发现系统文件有损坏时使用：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Dism /Online /Cleanup-Image /CheckHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 这条命令是把那些不同的系统文件还原成官方系统源文件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
DISM /Online /Cleanup-image /RestoreHealth&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 论以上命令运行结果如何，运行完成后重启，再键入以下命令：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
sfc /SCANNOW&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 启用 OpenSSH ==&lt;br /&gt;
 Windows 10 从某个版本（1809）开始已经对 OpenSSH 提供了支持，但是默认并未启用。&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 设置 -&amp;gt; 应用 -&amp;gt; 可选功能；&lt;br /&gt;
#: [[File:Windows10：可选功能.png|400px]]&lt;br /&gt;
# 点击“添加功能”，勾选“OpenSSH 服务器”、“OpenSSH 客户端”并安装：&lt;br /&gt;
#: [[File:Windows10：添加“可选功能”.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== 共享文件夹管理 ==&lt;br /&gt;
 管理所有共享的文件夹，通过“计算机管理”-&amp;gt;“系统工具”-&amp;gt;“共享文件夹”可以看到。&lt;br /&gt;
&lt;br /&gt;
如图：&lt;br /&gt;
: [[File:Windows：共享文件夹管理.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 禁用“Microsoft Compatibility Telemetry” ==&lt;br /&gt;
 在启动/从休眠中恢复 Windows 时，总能在任务管理器看到“Microsoft Compatibility Telemetry”的进程，而且 CPU 占用时不时飙升。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 Microsoft Compatibility Telemetry 是微软下的一个监测数据收集服务，如果加入microsoft 客户反馈改善计划，该服务就会在监测系统异常并收集反馈到微软。&lt;br /&gt;
&lt;br /&gt;
禁用“Microsoft Compatibility Telemetry”步骤：&lt;br /&gt;
# 控制面板：所有控制面板项 -&amp;gt; 管理工具 -&amp;gt; 任务计划程序；&lt;br /&gt;
# 定位到：Microsoft -&amp;gt; Windows -&amp;gt; Application Experience 栏目下；&lt;br /&gt;
# 找到“Microsoft Compatibility Appraiser”计划任务，禁用。&lt;br /&gt;
#: [[File:Windows：禁用“Microsoft Compatibility Appraiser”.png|600px]]&lt;br /&gt;
#* “Microsoft Compatibility Appraiser”等同于“Microsoft Compatibility Telemetry”。&lt;br /&gt;
&lt;br /&gt;
== 关于“蓝牙”使用中的问题 ==&lt;br /&gt;
 情景一：游戏时（蓝牙同时连接：音箱、键盘、耳机、手柄），在键盘睡眠重新连接后，再使用手柄操作总是会卡顿。&lt;br /&gt;
 &lt;br /&gt;
 情景二：音乐时（蓝牙同时连接：音箱、键盘、耳机），在键盘睡眠重新连接后，耳机（WH-1000XM4）总是会提示“蓝牙已连接”。&lt;br /&gt;
&lt;br /&gt;
以上问题都是由于“'''蓝牙带宽不够'''”导致的，&amp;lt;s&amp;gt;考虑不要同时连接、使用过多设备，关闭、断开（应该不用删除设备）部分设备就会好转&amp;lt;/s&amp;gt; —— '''必须删除某些已配对的设备，和当前连接的设备数量无关'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S. 一直以为是信号不好或者系统对蓝牙设备的自动休眠导致，很难意识到是连接设备过多导致的带宽带宽带宽带宽带宽问题。&lt;br /&gt;
&lt;br /&gt;
== 修改 hosts 文件 ==&lt;br /&gt;
 hosts 文件（位置：“C:\Users\&amp;lt;user&amp;gt;\scoop”）打开编辑，但是不能直接保存，只有用文件替换。&lt;br /&gt;
&lt;br /&gt;
使用 '''notepad'''（PowerShell 打开）打开 hosts 并修改，就可以直接保存。&lt;br /&gt;
&lt;br /&gt;
== '''查看连接过的 Wifi 密码''' ==&lt;br /&gt;
 查看当前 Wifi 的密码：（仅当前 Wifi）&lt;br /&gt;
     [[File:Windows：查看当前 Wifi 的密码.png|600px]]&lt;br /&gt;
&lt;br /&gt;
查看连接过的 Wifi 密码：&lt;br /&gt;
# 查看连接过的 Wifi：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profiles&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看连接过的 Wifi.png|600px]]&lt;br /&gt;
# 查看具体的 Wifi 配置：&lt;br /&gt;
#: '''&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;1,5&amp;quot;&amp;gt;&lt;br /&gt;
netsh wlan show profile name=&amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&lt;br /&gt;
或&lt;br /&gt;
&lt;br /&gt;
netsh wlan show profile &amp;quot;&amp;lt;Wifi 名称&amp;gt;&amp;quot; key=clear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
#: [[File:Windows：查看具体过的 Wifi 配置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 关于“desktop.ini”文件 ==&lt;br /&gt;
 “desktop.ini”文件是用于&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Linux%E5%8C%85%E7%AE%A1%E7%90%86%EF%BC%9Adpkg%E4%B8%8Eapt&amp;diff=6648</id>
		<title>Linux包管理：dpkg与apt</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Linux%E5%8C%85%E7%AE%A1%E7%90%86%EF%BC%9Adpkg%E4%B8%8Eapt&amp;diff=6648"/>
		<updated>2023-12-06T15:20:15Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 更新源 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Linux]]&lt;br /&gt;
&lt;br /&gt;
== dpkg ==&lt;br /&gt;
dpkg，即package manager for Debian（debian系统的包管理工具）。“dpkg is a tool to install, build, remove and manage Debian packages”，dpkg是Debian的一个底层包管理工具，主要用于对已下载到本地和已安装的软件包进行管理。&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这个机制最早由Debian Linux社区所开发出来的，通过dpkg的机制，Debian提供的软件就能够简单的安装起来，同时能提供安装后的软件信息。派生于Debian的其它Linux distributions大多使用dpkg这个机制来管理，包括B2D，Ubuntu等。&lt;br /&gt;
&lt;br /&gt;
=== deb软件包名规则 ===&lt;br /&gt;
格式：“Package_Version-Build_Architecture.deb”。&amp;lt;br/&amp;gt;&lt;br /&gt;
如：nano_1.3.10-2_i386.deb&lt;br /&gt;
# 软件包名称(Package Name): nano&lt;br /&gt;
# 版本(Version Number):1.3.10&lt;br /&gt;
# 修订号(Build Number):2&lt;br /&gt;
# 平台(Architecture):i386&lt;br /&gt;
&lt;br /&gt;
=== 相关文件 ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 文件 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| /etc/dpkg/dpkg.cfg&lt;br /&gt;
| dpkg的配置文件&lt;br /&gt;
|-&lt;br /&gt;
| /var/log/dpkg.log&lt;br /&gt;
| dpkg的日志文件&lt;br /&gt;
|-&lt;br /&gt;
| /var/lib/dpkg/available&lt;br /&gt;
| 存放系统所有安装过的软件包信息&lt;br /&gt;
|-&lt;br /&gt;
| /var/lib/dpkg/status&lt;br /&gt;
| 存放系统现在所有安装软件的状态信息&lt;br /&gt;
|-&lt;br /&gt;
| /var/lib/dpkg/info&lt;br /&gt;
| 存放安装软件包控制目录的控制信息文件&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== dpkg数据库 ===&lt;br /&gt;
* dpkg 使用文本文件作为数据库来维护系统中软件，包括文件清单、依赖关系、软件状态等详细的内容；&lt;br /&gt;
相关文本文件通常在“/var/lib/dpkg 目录下，通常在：&lt;br /&gt;
# “status”文件中存储软件状态和控制信息&lt;br /&gt;
# “info/”目录下备份控制文件，并在其下的；&lt;br /&gt;
#: “.list”文件中记录安装文件清单；&lt;br /&gt;
#: “.md5sums”保存文件的 MD5 编码。&lt;br /&gt;
[[File:dpkg数据库文本.png|800px]]&lt;br /&gt;
&lt;br /&gt;
==== 查询dpkg数据库 ====&lt;br /&gt;
显示所有已安装的Deb包“dpkg -l”：&lt;br /&gt;
: [[File:dpkg查看数据库.png|800px]]&lt;br /&gt;
每条记录的前三个字符为软件包的状态标识（Desired|Status|Err），后边依此是软件包名称、版本号、硬件平台和简单描述，其中&lt;br /&gt;
# 第一字符，为期望值（Desired=Unknown/Install/Remove/Purge/Hold），它包括：&lt;br /&gt;
#: u Unknown状态未知，这意味着软件包未安装，并且用户也未发出安装请求.&lt;br /&gt;
#: i Install用户请求安装软件包.&lt;br /&gt;
#: r Remove用户请求卸载软件包.&lt;br /&gt;
#: p Purge用户请求清除软件包.&lt;br /&gt;
#: h Hold用户请求保持软件包版本锁定.&lt;br /&gt;
# 第二列，为软件包的当前状态(Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend)：&lt;br /&gt;
#: n Not软件包未安装.&lt;br /&gt;
#: i Inst软件包安装并完成配置.&lt;br /&gt;
#: c Conf-files软件包以前安装过，现在删除了，但是它的配置文件还留在系统中.&lt;br /&gt;
#: u Unpacked软件包被解包，但还未配置.&lt;br /&gt;
#: f halF-conf试图配置软件包，但是失败了.&lt;br /&gt;
#: h Half-inst软件包安装，但是但是没有成功.&lt;br /&gt;
#: w trig-aWait触发器等待&lt;br /&gt;
#: t Trig-pend触发器未决&lt;br /&gt;
# 第三列标识错误状态，第一种状态标识“(none)”表示没有问题，其它符号则标识相应问题（Err?=(none)/Reinst-required (Status,Err: uppercase=bad)）&lt;br /&gt;
#: h 软件包被强制保持，因为有其它软件包依赖需求，无法升级.&lt;br /&gt;
#: r Reinst-required，软件包被破坏，可能需要重新安装才能正常使用(包括删除).&lt;br /&gt;
#: x 软包件被破坏，并且被强制保持.&lt;br /&gt;
&lt;br /&gt;
=== dpkg 子命令 ===&lt;br /&gt;
为了方便用户使用，dpkg不仅提供了大量的参数选项，同时也提供了许多子命令。比如：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dpkg-deb、dpkg-divert、dpkg-query、dpkg-split、dpkg-statoverride、start-stop-daemon&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== dpkg 使用 ===&lt;br /&gt;
==== 安装 ====&lt;br /&gt;
命令：&lt;br /&gt;
# dpkg -i package-name.deb：安装软件包，必须是deb包的完整名称（软件的安装可被拆分为两个对立的过程“解包”和“配置”）；&lt;br /&gt;
#: dpkg --unpack package-name.deb：解开软件包到系统目录但不配置；（“解包”）&lt;br /&gt;
#: dpkg --configure package-name.deb：配置软件包；（“配置”）&lt;br /&gt;
# dpkg -c package-name.deb：列出 deb 包的内容&lt;br /&gt;
选项：&lt;br /&gt;
# -R,--recursive：递归地处理在指定目录中的指向特定目录中所匹配的所有安装包；&lt;br /&gt;
#: 可以和 -i, -A, --install, --unpack 与--avail一起使用&lt;br /&gt;
&lt;br /&gt;
==== 移除 ====&lt;br /&gt;
# dpkg -r package-name：移除软件包，但保留其配置文件&lt;br /&gt;
# dpkg -P package-name：清除软件包的所有文件&lt;br /&gt;
&lt;br /&gt;
==== 查询 ====&lt;br /&gt;
# dpkg -l package-name-pattern：查看系统中软件包名符合pattern模式的软件包&lt;br /&gt;
# dpkg -L package-name：查看package-name对应的软件包安装的文件及目录&lt;br /&gt;
# dpkg -p package-name：显示包的具体信息&lt;br /&gt;
# dpkg -s package-name：查看package-name（已安装）对应的软件包信息&lt;br /&gt;
# dpkg -S filename-search-pattern：从已经安装的软件包中查找包含filename的软件包名称 &lt;br /&gt;
&lt;br /&gt;
*（也可使用子命令dpkg-query来进行查询操作）&lt;br /&gt;
&lt;br /&gt;
== apt ==&lt;br /&gt;
dpkg时，已经解决掉了软件安装过程中的大量问题，但是当依赖关系不满足时，仍然需要手动解决，而apt这个工具解决了这样的问题。&lt;br /&gt;
&lt;br /&gt;
linux distribution 先将软件放置到对应的服务器中，然后分析软件的依赖关系，并且记录下来，然后当客户端有安装软件需求时，通过清单列表与本地的dpkg以存在的软件数据相比较，就能从网络端获取所有需要的具有依赖属性的软件了。&lt;br /&gt;
&lt;br /&gt;
=== 原理 ===&lt;br /&gt;
dpkg 采用集中式的软件仓库机制，将各式各样的软件包分门别类地存放在软件仓库中，进行有效地组织和管理。然后，将软件仓库置于许许多多的镜像服务器中，并保持基本一致。这样，所有的Ubuntu用户随时都能获得最新版本的安装软件包。因此，对于用户，这些镜像服务器就是他们的软件源。&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然而，由于每位用户所处的网络环境不同，不可能随意地访问各镜像站点。为了能够有选择地访问，在Debian系统中，使用软件源配置文件“/etc/apt/sources.list”列出最合适访问的镜像站点地址。&lt;br /&gt;
&lt;br /&gt;
==== apt-get update的过程 ====&lt;br /&gt;
# 执行“apt-get update”&lt;br /&gt;
# 程序分析“/etc/apt/sources.list”&lt;br /&gt;
# 自动连网寻找list中对应的“Packages/Sources/Release”列表文件，如果有更新则下载之，存入“/var/lib/apt/lists/”目录&lt;br /&gt;
# 然后“apt-get install”相应的包 ，下载并安装&lt;br /&gt;
&lt;br /&gt;
* “apt-get update”命令会扫描每一个软件源服务器，并为该服务器所具有软件包资源建立索引文件，存放在本地的/var/lib/apt/lists/目录中。 &lt;br /&gt;
* 使用apt-get执行安装、更新操作时，都将依据这些索引文件，向软件源服务器申请资源。&lt;br /&gt;
* 因此，在计算机设备空闲时，经常使用“apt-get update”命令刷新软件源，是一个好的习惯。【？服务器呢？也需要？任务？】&lt;br /&gt;
&lt;br /&gt;
==== apt-get install的过程 ====&lt;br /&gt;
[[File:apt-get install原理图.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== apt 相关文件 ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| var/lib/dpkg/available&lt;br /&gt;
| 存放系统所有安装过的软件包信息&lt;br /&gt;
|-&lt;br /&gt;
| /etc/apt/sources.list&lt;br /&gt;
| 记录软件源的地址&lt;br /&gt;
（执行“sudo apt-get install xxx”时，系统就去这些站点下载软件包到本地并执行安装）&lt;br /&gt;
|-&lt;br /&gt;
| /var/cache/apt/archives&lt;br /&gt;
| 已经下载到的软件包&lt;br /&gt;
（用“apt-get install”安装软件时，软件包的临时存放路径）&lt;br /&gt;
|-&lt;br /&gt;
| /var/lib/apt/lists&lt;br /&gt;
| 使用“apt-get update”命令会从“/etc/apt/sources.list”中下载软件列表，并保存到该目录&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 更新源 ===&lt;br /&gt;
apt的源文件由配置文件“/etc/apt/sources.list”指定：&amp;lt;br/&amp;gt;&lt;br /&gt;
[[File:apt源文件的配置.png|800px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
* 在“[http://.../Ubantu/dists/trusty/main/binary-all/ http://.../Ubantu/dists/trusty/main/binary-all/]”的“Packages.gz”中，包含所有所依赖的软件及其版本信息、以及下载地址。&lt;br /&gt;
&lt;br /&gt;
源内容分为四部分，分别为（非上图例）：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;properties&amp;quot;&amp;gt;&lt;br /&gt;
deb    ###   镜像地址                ###  版本代号    ###  限定词&lt;br /&gt;
deb    ###   http://mirrors.163.com/debian/  ###  wheezy     ###  main non-free contrib&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# deb 表示软件的位置，deb-src 代表软件的源代码的位置；&lt;br /&gt;
# 镜像地址，其目录结构如下：&lt;br /&gt;
#: [[File:镜像url的内容.png|800px]]&lt;br /&gt;
#: /dists/：目录包含“发行版”（distributions）；&lt;br /&gt;
#: /pool/：目录为软件包的物理地址；软件包均放进一个巨大的 “池子(pool)”，按照源码包名称分类存放；&lt;br /&gt;
#:: 为了方便管理，pool 目录下按属性再分类(&amp;quot;main&amp;quot;, &amp;quot;contrib&amp;quot; 和 &amp;quot;non-free&amp;quot;)，分类下面再按源码包名称的首字母归档；&lt;br /&gt;
#: /tools/：用于创建启动盘、磁盘分区、压缩/解压文件，启动Linux的DOS下小工具等；&lt;br /&gt;
#: /doc/：基本的 Debian 文档, 如 FAQ, 错误报告系统指导等；&lt;br /&gt;
#: /indices/：维护人员文件和重载文件；&lt;br /&gt;
#: /project/：大部分为开发人员的资源；&lt;br /&gt;
# 版本号&lt;br /&gt;
#: oldstable：以前的稳定发行版&lt;br /&gt;
#: stable：现在的稳定发行版&lt;br /&gt;
#:: 对于每个debian来说，每个稳定发行版都会有一个代号，如debian 6叫做squeeze，debian 7叫做wheezy&lt;br /&gt;
#: testing：处于测试阶段的发行版&lt;br /&gt;
#: unstable：不稳定版本&lt;br /&gt;
# 限定词&lt;br /&gt;
#: main：Debian 里最基本及主要且符合自由软件规范的软件 &lt;br /&gt;
#: contrib：自由软件（相对于non-free）&lt;br /&gt;
#: non-free：不属于自由软件范畴的软件&lt;br /&gt;
&lt;br /&gt;
=== apt使用 ===&lt;br /&gt;
==== apt-get ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apt-get is the command-line tool for handling packages, and may be considered the user's &amp;quot;back-end&amp;quot; to other tools using the APT library. Several &amp;quot;front-end&amp;quot; interfaces exist, such as dselect(?), aptitude(?), synaptic(?) and wajig(?).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
apt-get 是一个下载安装软件包的简单命令行接口。最常用的命令是update(更新)和install(安装)。&amp;lt;br/&amp;gt;&lt;br /&gt;
用法： &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt-get [选项] 命令&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
选项:&lt;br /&gt;
# -h：显示帮助信息；&lt;br /&gt;
# -q：输出到日志，不显示进展；&lt;br /&gt;
# -qq：不输出信息，错误除外；&lt;br /&gt;
# -d：仅下载软件包，不执行安装操作；&lt;br /&gt;
# -P：每一步操作都要求确认；&lt;br /&gt;
# -s：模拟执行命令，不实际安装；&lt;br /&gt;
# -y：所有问题都回答“yes”；&lt;br /&gt;
# -v：显示附加信息；&lt;br /&gt;
# -u：启动时下载新的软件包列表。&lt;br /&gt;
# &lt;br /&gt;
# -c=?：阅读配置文件？；&lt;br /&gt;
# -o=?：设置自定的配置选项，如“-o dir::cache=/tmp”；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
常用命令：&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| apt-get update&lt;br /&gt;
| 更新源&lt;br /&gt;
（“aptitude update”）&lt;br /&gt;
|-&lt;br /&gt;
| apt-get dist-upgrade&lt;br /&gt;
| 升级系统到相应的发行版（根据 source.list 的配置）&lt;br /&gt;
（“aptitude dist-upgrade”）&lt;br /&gt;
|-&lt;br /&gt;
| apt-get upgrade&lt;br /&gt;
| 更新所有已经安装的软件包&lt;br /&gt;
（“aptitude upgrade”）&lt;br /&gt;
|-&lt;br /&gt;
| apt-get install package_name&lt;br /&gt;
| 安装软件包&lt;br /&gt;
（“aptitude install package_name”）&lt;br /&gt;
# 参数“--reinstall”用于重新安装&lt;br /&gt;
# “apt-get install package_name=version”：安装指定版本的软件包&lt;br /&gt;
|-&lt;br /&gt;
| apt-get remove package_name&lt;br /&gt;
| 卸载一个已安装的软件包（保留配置文件）&lt;br /&gt;
（“aptitude remove package_name”）&lt;br /&gt;
|-&lt;br /&gt;
| apt-get purge package_name&lt;br /&gt;
| 移除软件包（删除配置信息）&lt;br /&gt;
（“aptitude purge package_name”）&lt;br /&gt;
# 或“apt-get --purge remove packagename”&lt;br /&gt;
|-&lt;br /&gt;
| apt-get check&lt;br /&gt;
| 检查是否有损坏的依赖&lt;br /&gt;
|-&lt;br /&gt;
| apt-get autoclean&lt;br /&gt;
| 清理已删除软件的.deb文件&lt;br /&gt;
（“aptitude autoclean”）&lt;br /&gt;
* 定期清理，可以释放的磁盘空间&lt;br /&gt;
|-&lt;br /&gt;
| apt-get clean&lt;br /&gt;
| 清理已安装软件的备份（不影响软件使用）&lt;br /&gt;
（“aptitude clean”）&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== apt-cache ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apt-cache performs a variety of operations on APT's package cache. apt-cache does not manipulate the state of the system but does provide operations to search and generate interesting output from the package metadata.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
apt-cache：用于对apt的包缓存执行各种操作：&lt;br /&gt;
# “apt-cache depends packagename”：了解使用依赖&lt;br /&gt;
# “apt-cache rdepends packagename”：是查看该包被哪些包依赖&lt;br /&gt;
# “apt-cache search packagename”：搜索包&lt;br /&gt;
#: 【aptitude search packagename】&lt;br /&gt;
# “apt-cache show packagename”：获取包的相关信息，如说明、大小、版本等&lt;br /&gt;
#: 【aptitude show packagename】&lt;br /&gt;
# “apt-cache showpkg packagename”：显示软件包的大致信息&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Mysql%EF%BC%9A%E5%AE%89%E8%A3%85%EF%BC%88Windows%EF%BC%89&amp;diff=6647</id>
		<title>Mysql：安装（Windows）</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Mysql%EF%BC%9A%E5%AE%89%E8%A3%85%EF%BC%88Windows%EF%BC%89&amp;diff=6647"/>
		<updated>2023-12-06T05:02:16Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 多版本安装 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:MySQL]]&lt;br /&gt;
[[category:安装（Windows）]]&lt;br /&gt;
&lt;br /&gt;
== 下载安装包 ==&lt;br /&gt;
一般选择的是社区版（MySQL Community Server）的GA版本（正式发布版本、生产版本），链接 [https://dev.mysql.com/downloads/mysql/ MySQL:Download MySQL Community Server]。&lt;br /&gt;
: [[File:下载MySQL安装文件.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
安装文件类型：&lt;br /&gt;
# “mysql-xxx-win64.zip”：编译好的 windows 64 位 MySQL，文件解压缩后即可使用（需要手工配置）。&lt;br /&gt;
# “mysql-xxx-win64.msi”：windows 安装包，双击执行根据向导安装即可。&lt;br /&gt;
# “mysql-xxx.zip”：windows源文件，需要编译。&lt;br /&gt;
&lt;br /&gt;
== 安装 MySQL==&lt;br /&gt;
 以 mysql-5.7.33-winx64.zip 为例。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
安装步骤：&lt;br /&gt;
# 解压 MySQL 文件到目的目录；（如“D:\Program Files\mysql-5.7.33-winx64”）&lt;br /&gt;
# 配置环境变量：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
MYSQL_HOME：D:\Program Files\mysql-5.7.33-winx64;&lt;br /&gt;
&lt;br /&gt;
path 添加：%MYSQL_HOME%\bin;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 新建配置文件“'''my.ini'''”：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
[mysql]  &lt;br /&gt;
# 设置 mysql 客户端默认字符集  &lt;br /&gt;
default-character-set=utf8 &lt;br /&gt;
 &lt;br /&gt;
[mysqld]  &lt;br /&gt;
# 设置 3306 端口  &lt;br /&gt;
port = 3306  &lt;br /&gt;
&lt;br /&gt;
# 设置 mysql 的安装目录  &lt;br /&gt;
basedir=D:\Program Files\mysql-5.7.23-winx64&lt;br /&gt;
&lt;br /&gt;
# 设置 mysql 数据库的数据的存放目录  &lt;br /&gt;
datadir=D:\Program Files\mysql-5.7.23-winx64\data &lt;br /&gt;
&lt;br /&gt;
# 允许最大连接数  &lt;br /&gt;
max_connections=200  &lt;br /&gt;
&lt;br /&gt;
# 服务端使用的字符集默认为 8 比特编码的 latin1 字符集  &lt;br /&gt;
character-set-server=utf8  &lt;br /&gt;
&lt;br /&gt;
# 创建新表时将使用的默认存储引擎  &lt;br /&gt;
default-storage-engine=INNODB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 用于配置MySQL的基础设置，如字符集、引擎、端口、安装目录、数据目录等。&lt;br /&gt;
# 初始化数据库：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
# 初始化命令&lt;br /&gt;
mysqld --initialize-insecure --user=mysql&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: MySQL目录中多出一个“data”文件夹，包含了系统的默认数据库；&lt;br /&gt;
#* 如果使用“--initialize”还会生了一个随机的初始 root 密码。&lt;br /&gt;
# 安装服务：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
# 将服务器安装为 Windows 服务，并设置服务为“自动启动”&lt;br /&gt;
mysqld -install [service_name]&lt;br /&gt;
&lt;br /&gt;
# 将服务器安装为 Windows 服务，并设置服务为“手动启动”&lt;br /&gt;
mysqld --install-manual [service_name]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 如果未提供“[service_name]”值，则默认服务名称为“MySQL”。&lt;br /&gt;
#* 第一次安装的话会显示“Service successfully installed.”；否则会显示“The service already exists! ...”&lt;br /&gt;
#*: [[File:安装服务.jpg|600px]]&lt;br /&gt;
# 验证安装：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
# 查看MySQL版本&lt;br /&gt;
mysql --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: [[File:查看MySQL版本.png|600px]]&lt;br /&gt;
&lt;br /&gt;
=== 关于“初始化数据库” ===&lt;br /&gt;
安装 MySQL 之后，初始化数据库，包括 mysql 系统数据库中的表：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
mysqld --initialize --user=mysql [--console]&lt;br /&gt;
&lt;br /&gt;
mysqld --initialize-insecure --user=mysql [--console]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “--user=mysql”：以“mysql”身份运行该命令。&lt;br /&gt;
# “--console”：选项将消息定向到 Windows 控制台；否则将写入其标准错误输出：“错误日志”（data目录中后缀为“.err”的文件）。&lt;br /&gt;
# “--initialize”：进行“默认安全”的初始化，即：包括'''生成随机的初始root密码'''（可在错误日志中找到）。&lt;br /&gt;
#* 以 root 连接到服务器时，“'''&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; inline&amp;gt;mysql -u root -p&amp;lt;/syntaxhighlight&amp;gt;'''”需要生成的临时密码；&lt;br /&gt;
#* 在这种情况下，密码被标记为'''已过期'''，您将需要选择一个新密码；&lt;br /&gt;
# “--initialize-insecure”：执行初始化，但'''不会生成root密码'''。&lt;br /&gt;
#* 以 root 连接到服务器时，不使用密码登录“'''&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; inline&amp;gt;mysql -u root --skip-password&amp;lt;/syntaxhighlight&amp;gt;'''”；&lt;br /&gt;
#* 这是不安全的；假定您在将服务器投入生产使用之前会及时为帐户分配密码；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
对于某些 MySQL 安装方法，数据目录初始化是自动的。（如在 Windows 上通过msi文件的自动化安装过程）&lt;br /&gt;
&lt;br /&gt;
对于其他安装方法，必须手动初始化数据目录。（包括在 Unix 和类似 Unix 的系统上从通用二进制发行版和源代码发行版进行安装，以及在 Windows 上从 ZIP Archive 软件包进行安装）&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
初始化期间的服务器操作：'''服务器检查数据目录是否存在'''：&lt;br /&gt;
# 如果不存在数据目录，则服务器将创建它。&lt;br /&gt;
# 如果数据目录存在但不为空（即它包含文件或子目录），则服务器在生成错误消息后退出：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
[ERROR] --initialize specified but the data directory exists. Aborting.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 在这种情况下，请删除或重命名数据目录，然后重试。&lt;br /&gt;
* 首次安装 MySQL 之后才需要进行数据目录初始化；但，初始化数据目录的命令不会覆盖任何现有的 mysql 数据库表，因此在任何情况下都可以安全运行。&lt;br /&gt;
&lt;br /&gt;
== 多版本安装 ==&lt;br /&gt;
 多版本共存时：&lt;br /&gt;
 1、需要配置不同的环境变量。&lt;br /&gt;
 2、配置文件中：需要指定不同端口“port”避免冲突；&lt;br /&gt;
 3、安装时，安装命令需要指定配置文件。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
步骤：（以 5.7.35、8.0.27 为例）&lt;br /&gt;
# 解压 MySQL 文件到目的目录；&lt;br /&gt;
# 新建配置文件：&lt;br /&gt;
#: 分别在两个 MySQL 目录中新建“my.ini”：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
# 设置端口&lt;br /&gt;
port=3306&lt;br /&gt;
# 设置 mysql 的安装目录&lt;br /&gt;
basedir=D:\Program Files\MySQL\mysql-5.7.35&lt;br /&gt;
# 设置 mysql 数据库的数据的存放目录&lt;br /&gt;
datadir=D:\Program Files\MySQL\mysql-5.7.35\data &lt;br /&gt;
# 允许最大连接数&lt;br /&gt;
max_connections=200&lt;br /&gt;
# 服务端使用的字符集默认为 8 比特编码的 latin1 字符集&lt;br /&gt;
character-set-server=utf8&lt;br /&gt;
# 创建新表时将使用的默认存储引擎&lt;br /&gt;
default-storage-engine=INNODB&lt;br /&gt;
&lt;br /&gt;
[mysql]&lt;br /&gt;
# 设置 mysql 客户端默认字符集&lt;br /&gt;
default-character-set=utf8&lt;br /&gt;
&lt;br /&gt;
[client]&lt;br /&gt;
# 设置mysql客户端连接服务端时默认使用的端口&lt;br /&gt;
port=3306&lt;br /&gt;
default-character-set=utf8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
# 设置端口&lt;br /&gt;
port=3307&lt;br /&gt;
# 设置mysql的安装目录&lt;br /&gt;
basedir=D:\Program Files\MySQL\mysql-8.0.27&lt;br /&gt;
# 设置mysql数据库的数据的存放目录&lt;br /&gt;
datadir=D:\Program Files\MySQL\mysql-8.0.27\data&lt;br /&gt;
# 允许最大连接数&lt;br /&gt;
max_connections=200&lt;br /&gt;
# 允许连接失败的次数&lt;br /&gt;
max_connect_errors=10&lt;br /&gt;
# 服务端使用的字符集默认为UTF8&lt;br /&gt;
character-set-server=utf8mb4&lt;br /&gt;
# 创建新表时将使用的默认存储引擎&lt;br /&gt;
default-storage-engine=INNODB&lt;br /&gt;
# 认证插件：默认使用“caching_sha2_password”，可选“mysql_native_password”&lt;br /&gt;
default_authentication_plugin=caching_sha2_password&lt;br /&gt;
&lt;br /&gt;
[mysql]&lt;br /&gt;
# 设置mysql客户端默认字符集&lt;br /&gt;
default-character-set=utf8mb4&lt;br /&gt;
&lt;br /&gt;
[client]&lt;br /&gt;
# 设置mysql客户端连接服务端时默认使用的端口&lt;br /&gt;
port=3307&lt;br /&gt;
default-character-set=utf8mb4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 需要设置不同的端口！&lt;br /&gt;
#* MYSQL 8+ 字符编码要求使用“utf8mb4”，否则在初始化的时候会报一个警告；&lt;br /&gt;
#* MYSQL 8+ 默认的认证插件为“caching_sha2_password”；MYSQL 5.7 默认使用“mysql_native_password”；&lt;br /&gt;
#* “server-id”用于不同服务器的主从复制，这里不需要；&lt;br /&gt;
# 初始化数据库：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
cd D:\Program Files\MySQL\mysql-5.7.35\bin&lt;br /&gt;
mysqld --initialize --user=mysql --console&lt;br /&gt;
&lt;br /&gt;
cd D:\Program Files\MySQL\mysql-8.0.27\bin&lt;br /&gt;
mysqld --initialize --user=mysql --console &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 完成之后，可以通过“mysqld --version”确认是否成功；&lt;br /&gt;
#* 安装第二个时，可能遇到错误：&amp;lt;big&amp;gt;'''&amp;lt;code&amp;gt;[ERROR]—initialize specified but the data directory has files in it ． Aborting ．&amp;lt;/code&amp;gt;'''&amp;lt;/big&amp;gt;&lt;br /&gt;
#*: [[File:MySQL安装多版本错误：--initialize specified but the data directory has files int it.png|600px]]&lt;br /&gt;
#*: 原因：由于已为第一个 MySQL 配置了环境变量，所以虽然定位到了第二个 bin 目录，但使用的还是第一个 bin（环境变量中先读取的那个）  ——【这他妈是 Windows 的 bug 吧】&lt;br /&gt;
#*: 解决：&amp;lt;big&amp;gt;'''先删除环境变量，待初始化、安装服务之后，再配置环境变量。'''&amp;lt;/big&amp;gt;  ——【由于使用的不是定位的目录，还可能引起许多问题——由于不同版本 MySQL 引起的问题】&lt;br /&gt;
# 安装服务：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
cd D:\Program Files\MySQL\mysql-5.7.35\bin&lt;br /&gt;
mysqld –install MySQL57&lt;br /&gt;
&lt;br /&gt;
cd D:\Program Files\MySQL\mysql-8.0.27\bin&lt;br /&gt;
mysqld –install MySQL80&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 需要设置不同的服务名称！&lt;br /&gt;
# 配置环境变量：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
MYSQL_HOME57：D:\Program Files\MySQL\mysql-5.7.35&lt;br /&gt;
MYSQL_HOME80：D:\Program Files\MySQL\mysql-8.0.27&lt;br /&gt;
&lt;br /&gt;
path 添加：%MYSQL_HOME57%\bin;%MYSQL_HOME80%\bin;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''修改注册表'''：【！！！】&lt;br /&gt;
#: 注册表“计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\”下找到安装的服务，将“'''ImagePath'''”设置为正确的路径，如：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL57&lt;br /&gt;
ImagePath：&amp;quot;D:\Program Files\MySQL\mysql-5.7.35\bin\mysqld&amp;quot; MySQL57&lt;br /&gt;
&lt;br /&gt;
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL57&lt;br /&gt;
ImagePath：&amp;quot;D:\Program Files\MySQL\mysql-8.0.27\bin\mysqld&amp;quot; MySQL80&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 因为安装了两个版本的 MySQL，所以后一个的执行文件被指向了前一个版本目录中的内容，需要修改！！！&lt;br /&gt;
# '''开放端口'''：【！！！】&lt;br /&gt;
#: 在防火墙的“高级设置”中添加“'''入站规则'''”，指定需要的端口。&lt;br /&gt;
#* 规则可能没生效，可能需要重启。【坑】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::: [[File:MySQL多版本安装.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 指定“--defaults-file” ===&lt;br /&gt;
如果安装过程中要指定“--defaults-file”，则必须在前面：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
应该是：&lt;br /&gt;
mysqld --defaults-file=&amp;quot;D:\Program Files\MySQL\mysql-5.7.35\my.ini&amp;quot; --initialize --user=mysql --console&lt;br /&gt;
&lt;br /&gt;
而非：&lt;br /&gt;
mysqld --initialize --user=mysql --console --defaults-file=&amp;quot;D:\Program Files\MySQL\mysql-5.7.35\my.ini&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
cd D:\Program Files\MySQL\mysql-5.7.35\bin&lt;br /&gt;
mysqld --defaults-file=&amp;quot;D:\Program Files\MySQL\mysql-5.7.35\my.ini&amp;quot; --initialize --user=mysql --console&lt;br /&gt;
mysqld –install MySQL57 --defaults-file=&amp;quot;D:\Program Files\MySQL\mysql-5.7.35\my.ini&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cd D:\Program Files\MySQL\mysql-8.0.27\bin&lt;br /&gt;
mysqld --defaults-file=&amp;quot;D:\Program Files\MySQL\mysql-8.0.27\my.ini&amp;quot; --initialize --user=mysql --console &lt;br /&gt;
mysqld –install MySQL80 --defaults-file=&amp;quot;D:\Program Files\MySQL\mysql-8.0.27\my.ini&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 验证安装 ===&lt;br /&gt;
如果服务均能启动，则说明安装成功。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果有服务不能启动：（以下两个作用一样）&lt;br /&gt;
# 在注册表“计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\”下找到安装的服务，在“ImagePath”可以确认是不是正确；&lt;br /&gt;
# 在服务页面找到安装的服务项，右键页面可以看到服务的安装信息是否正确；&lt;br /&gt;
&lt;br /&gt;
=== “本地计算机上的 MySQLXX 服务启动后停止。某些服务在未由其他程序或服务使用时将自动停止” ===&lt;br /&gt;
如上安装了两个MySQL版本之后，发现始终只能启动一个。&lt;br /&gt;
&lt;br /&gt;
: 一开始以为是因为服务的执行文件指向的是同一个目录下的内容，通过注册表项进行了更改，但是问题依旧；&lt;br /&gt;
: 然后发现，其实是只能使用“3306”一个接口，无论哪个版本设置3306都可以启动，但是其他接口就不行，所以在防火墙打开了 3306-3309 的接口，但是问题依旧。&lt;br /&gt;
【解决】：坑比的系统防火墙规则没生效，重启了一遍才生效，一切正常了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
所以步骤是：&lt;br /&gt;
# 修改注册表；&lt;br /&gt;
# 开放端口；&lt;br /&gt;
# 判断端口是否生效，否则重启试试。&lt;br /&gt;
&lt;br /&gt;
== 卸载MySQL ==&lt;br /&gt;
# 移除 MySQL 服务：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
mysqld -remove&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 删除环境变量；&lt;br /&gt;
# 删除 MySQL 目录；&lt;br /&gt;
#* 此外，在“C:\ProgramData”、“C:\Program Files (x86)”、“C:\Program Files”等位置可能还有 MySQL 的文件夹；&lt;br /&gt;
&lt;br /&gt;
== 进入 MySQL ==&lt;br /&gt;
# 启动服务：使用Windows的cmd执行命令，用于手动启动服务：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
net start mysql&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 登录：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
mysql -u root -p&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 设置密码：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
use mysql;&lt;br /&gt;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;!-- msi本机安装时修改密码为“@eijux” --&amp;gt;&lt;br /&gt;
# 操作数据库：如查看存在的数据库等：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
show databases;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 退出和停止：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
quit  // 退出&lt;br /&gt;
net stop mysql // 停止服务&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 附：安装 MySQL（mysql-installer-community-5.7.33.0.msi）==&lt;br /&gt;
使用Windows Installer安装MySQL顺序而行，没有特别需要注意的地方：&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:WindowsInstaller安装MySQL_1.jpg|“License Agreement（用户许可证协议）”&lt;br /&gt;
File:WindowsInstaller安装MySQL_2.jpg|“Choosing a Setup Type（安装类型选择）”&lt;br /&gt;
File:WindowsInstaller安装MySQL_3.jpg|根据所选择的安装类型安装 Windows 系统框架（framework）&lt;br /&gt;
File:WindowsInstaller安装MySQL_4.jpg|弹出安装程序窗口，安装需要的系统框架&lt;br /&gt;
File:WindowsInstaller安装MySQL_5.jpg|框架已经安装完成&lt;br /&gt;
File:WindowsInstaller安装MySQL_6.jpg|所需框架均安装成功后，单击 “Next（下一步）”&lt;br /&gt;
File:WindowsInstaller安装MySQL_7.jpg|安装确认窗口，单击 “Execute（执行）”按钮，开始 MySQL 各个组件的安装&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:MySQL%E5%AE%89%E8%A3%85%E5%A4%9A%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF%EF%BC%9A--initialize_specified_but_the_data_directory_has_files_int_it.png&amp;diff=6646</id>
		<title>文件:MySQL安装多版本错误：--initialize specified but the data directory has files int it.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:MySQL%E5%AE%89%E8%A3%85%E5%A4%9A%E7%89%88%E6%9C%AC%E9%94%99%E8%AF%AF%EF%BC%9A--initialize_specified_but_the_data_directory_has_files_int_it.png&amp;diff=6646"/>
		<updated>2023-12-06T04:53:02Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ASSL%E8%AE%BE%E7%BD%AE.png&amp;diff=6645</id>
		<title>文件:CloudFlare：SSL设置.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ASSL%E8%AE%BE%E7%BD%AE.png&amp;diff=6645"/>
		<updated>2023-08-05T09:37:09Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​Eijux上传文件:CloudFlare：SSL设置.png的新版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ADNS%E8%AE%BE%E7%BD%AE.png&amp;diff=6644</id>
		<title>文件:CloudFlare：DNS设置.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ADNS%E8%AE%BE%E7%BD%AE.png&amp;diff=6644"/>
		<updated>2023-08-05T09:36:15Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​Eijux已恢复文件:CloudFlare：DNS设置.png至旧版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=CloudFlare%E4%BD%BF%E7%94%A8&amp;diff=6643</id>
		<title>CloudFlare使用</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=CloudFlare%E4%BD%BF%E7%94%A8&amp;diff=6643"/>
		<updated>2023-08-05T09:35:08Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* SSL 设置 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:网络工具]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 CloudFlare 一般用于 '''CDN 加速'''（如用于外贸网站）和'''DNS解析'''（'''站点代理'''）&lt;br /&gt;
&lt;br /&gt;
== DNS 设置 ==&lt;br /&gt;
 “代理状态”：&lt;br /&gt;
 1、“仅 DNS”（“DNS 解析”）：仅用于“DNS 解析”，不用于“站点代理”&lt;br /&gt;
 2、“已代理”（“站点代理”）：“DNS 解析”+“站点代理”，该'''域名会被 CloudFlare 提供的 IP 隐藏'''&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 添加站点&lt;br /&gt;
# 修改域名的“'''DNS 解析服务器'''”&lt;br /&gt;
#: 在域名供应商（如，阿里云）处修改域名的 DNS 为 CloudFlare 提供的服务器 —— 域名供应商处的“DNS 记录”不再生效&lt;br /&gt;
# 设置域名的“'''DNS 记录'''”&lt;br /&gt;
#: 与域名供应商处设置的解析记录类同&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：DNS设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== SSL 设置 ==&lt;br /&gt;
 CloudFlare 要求站点必须使用 SSL 证书。&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：SSL设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
 证书可以通过多种渠道获取，此处不提。&lt;br /&gt;
 &lt;br /&gt;
 可以通过【&amp;lt;big&amp;gt;'''[[Acme.sh 使用|acme.sh 脚本]]'''&amp;lt;/big&amp;gt;】申请、自动更新证书。&lt;br /&gt;
&lt;br /&gt;
== 端口转发设置 ==&lt;br /&gt;
 CloudFlare 支持的 '''HTTP''' 端口：80、8080、8880、2052、2082、2086、2095&lt;br /&gt;
 &lt;br /&gt;
 CloudFlare 支持的 '''HTTPS''' 端口：443、2053、2083、2087、2096、8443&lt;br /&gt;
&lt;br /&gt;
除此此外的端口，需要设置“'''回源规则'''（Origin Rules）”仅行转发：&lt;br /&gt;
# 对外提供服务的端口仍为：80 / 443&lt;br /&gt;
# 服务器中服务使用的端口：“目的端口”&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：端口转发设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 附：通过CloudFlare拯救被X的IP ==&lt;br /&gt;
 即：&lt;br /&gt;
 &lt;br /&gt;
 1、通过“'''站点代理'''”来让使用被 X 的 IP —— 由域名是不能获取到真实 IP 的&lt;br /&gt;
 &lt;br /&gt;
 2、SS 客户端一律使用 80 / 443 端口连接 —— SS 服务等可以使用 443 端口，也可以通过“'''回源规则'''”使用其他端口&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=CloudFlare%E4%BD%BF%E7%94%A8&amp;diff=6642</id>
		<title>CloudFlare使用</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=CloudFlare%E4%BD%BF%E7%94%A8&amp;diff=6642"/>
		<updated>2023-08-05T09:34:30Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* SSL 设置 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:网络工具]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 CloudFlare 一般用于 '''CDN 加速'''（如用于外贸网站）和'''DNS解析'''（'''站点代理'''）&lt;br /&gt;
&lt;br /&gt;
== DNS 设置 ==&lt;br /&gt;
 “代理状态”：&lt;br /&gt;
 1、“仅 DNS”（“DNS 解析”）：仅用于“DNS 解析”，不用于“站点代理”&lt;br /&gt;
 2、“已代理”（“站点代理”）：“DNS 解析”+“站点代理”，该'''域名会被 CloudFlare 提供的 IP 隐藏'''&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 添加站点&lt;br /&gt;
# 修改域名的“'''DNS 解析服务器'''”&lt;br /&gt;
#: 在域名供应商（如，阿里云）处修改域名的 DNS 为 CloudFlare 提供的服务器 —— 域名供应商处的“DNS 记录”不再生效&lt;br /&gt;
# 设置域名的“'''DNS 记录'''”&lt;br /&gt;
#: 与域名供应商处设置的解析记录类同&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：DNS设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== SSL 设置 ==&lt;br /&gt;
 CloudFlare 要求站点必须使用 SSL 证书。&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：SSL设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
 证书可以通过多种渠道获取，此处不提。&lt;br /&gt;
 &lt;br /&gt;
 可以通过【[[Acme.sh 使用|acme.sh 脚本]]】申请、自动更新证书。&lt;br /&gt;
&lt;br /&gt;
== 端口转发设置 ==&lt;br /&gt;
 CloudFlare 支持的 '''HTTP''' 端口：80、8080、8880、2052、2082、2086、2095&lt;br /&gt;
 &lt;br /&gt;
 CloudFlare 支持的 '''HTTPS''' 端口：443、2053、2083、2087、2096、8443&lt;br /&gt;
&lt;br /&gt;
除此此外的端口，需要设置“'''回源规则'''（Origin Rules）”仅行转发：&lt;br /&gt;
# 对外提供服务的端口仍为：80 / 443&lt;br /&gt;
# 服务器中服务使用的端口：“目的端口”&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：端口转发设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 附：通过CloudFlare拯救被X的IP ==&lt;br /&gt;
 即：&lt;br /&gt;
 &lt;br /&gt;
 1、通过“'''站点代理'''”来让使用被 X 的 IP —— 由域名是不能获取到真实 IP 的&lt;br /&gt;
 &lt;br /&gt;
 2、SS 客户端一律使用 80 / 443 端口连接 —— SS 服务等可以使用 443 端口，也可以通过“'''回源规则'''”使用其他端口&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=CloudFlare%E4%BD%BF%E7%94%A8&amp;diff=6641</id>
		<title>CloudFlare使用</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=CloudFlare%E4%BD%BF%E7%94%A8&amp;diff=6641"/>
		<updated>2023-08-05T09:33:21Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​创建页面，内容为“category:网络工具  == 关于 ==  CloudFlare 一般用于 '''CDN 加速'''（如用于外贸网站）和'''DNS解析'''（'''站点代理'''）  == DNS 设置 ==  “代理状态”：  1、“仅 DNS”（“DNS 解析”）：仅用于“DNS 解析”，不用于“站点代理”  2、“已代理”（“站点代理”）：“DNS 解析”+“站点代理”，该'''域名会被 CloudFlare 提供的 IP 隐藏'''  步骤： # 添加站点 # 修改…”&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:网络工具]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 CloudFlare 一般用于 '''CDN 加速'''（如用于外贸网站）和'''DNS解析'''（'''站点代理'''）&lt;br /&gt;
&lt;br /&gt;
== DNS 设置 ==&lt;br /&gt;
 “代理状态”：&lt;br /&gt;
 1、“仅 DNS”（“DNS 解析”）：仅用于“DNS 解析”，不用于“站点代理”&lt;br /&gt;
 2、“已代理”（“站点代理”）：“DNS 解析”+“站点代理”，该'''域名会被 CloudFlare 提供的 IP 隐藏'''&lt;br /&gt;
&lt;br /&gt;
步骤：&lt;br /&gt;
# 添加站点&lt;br /&gt;
# 修改域名的“'''DNS 解析服务器'''”&lt;br /&gt;
#: 在域名供应商（如，阿里云）处修改域名的 DNS 为 CloudFlare 提供的服务器 —— 域名供应商处的“DNS 记录”不再生效&lt;br /&gt;
# 设置域名的“'''DNS 记录'''”&lt;br /&gt;
#: 与域名供应商处设置的解析记录类同&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：DNS设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== SSL 设置 ==&lt;br /&gt;
 CloudFlare 要求站点必须使用 SSL 证书。&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：SSL设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
证书可以通过多种渠道获取，此处不提。&lt;br /&gt;
* 证书的设置可以通过 [[Acme.sh 使用|acme.sh 脚本]]，可以申请、自动更新证书&lt;br /&gt;
&lt;br /&gt;
== 端口转发设置 ==&lt;br /&gt;
 CloudFlare 支持的 '''HTTP''' 端口：80、8080、8880、2052、2082、2086、2095&lt;br /&gt;
 &lt;br /&gt;
 CloudFlare 支持的 '''HTTPS''' 端口：443、2053、2083、2087、2096、8443&lt;br /&gt;
&lt;br /&gt;
除此此外的端口，需要设置“'''回源规则'''（Origin Rules）”仅行转发：&lt;br /&gt;
# 对外提供服务的端口仍为：80 / 443&lt;br /&gt;
# 服务器中服务使用的端口：“目的端口”&lt;br /&gt;
&lt;br /&gt;
: [[File:CloudFlare：端口转发设置.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== 附：通过CloudFlare拯救被X的IP ==&lt;br /&gt;
 即：&lt;br /&gt;
 &lt;br /&gt;
 1、通过“'''站点代理'''”来让使用被 X 的 IP —— 由域名是不能获取到真实 IP 的&lt;br /&gt;
 &lt;br /&gt;
 2、SS 客户端一律使用 80 / 443 端口连接 —— SS 服务等可以使用 443 端口，也可以通过“'''回源规则'''”使用其他端口&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9A%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91%E8%AE%BE%E7%BD%AE.png&amp;diff=6640</id>
		<title>文件:CloudFlare：端口转发设置.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9A%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91%E8%AE%BE%E7%BD%AE.png&amp;diff=6640"/>
		<updated>2023-08-05T09:23:36Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ASSL%E8%AE%BE%E7%BD%AE.png&amp;diff=6639</id>
		<title>文件:CloudFlare：SSL设置.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ASSL%E8%AE%BE%E7%BD%AE.png&amp;diff=6639"/>
		<updated>2023-08-05T09:22:03Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ADNS%E8%AE%BE%E7%BD%AE.png&amp;diff=6638</id>
		<title>文件:CloudFlare：DNS设置.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ADNS%E8%AE%BE%E7%BD%AE.png&amp;diff=6638"/>
		<updated>2023-08-05T09:21:40Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​Eijux上传文件:CloudFlare：DNS设置.png的新版本&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ADNS%E8%AE%BE%E7%BD%AE.png&amp;diff=6637</id>
		<title>文件:CloudFlare：DNS设置.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E6%96%87%E4%BB%B6:CloudFlare%EF%BC%9ADNS%E8%AE%BE%E7%BD%AE.png&amp;diff=6637"/>
		<updated>2023-08-05T09:20:53Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​基于MsUpload的文件上传&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;基于MsUpload的文件上传&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=MySQL_%E4%BC%98%E5%8C%96%EF%BC%9A%E4%BC%98%E5%8C%96_SQL_%E8%AF%AD%E5%8F%A5%EF%BC%9A%E4%BC%98%E5%8C%96_SELECT_%E8%AF%AD%E5%8F%A5&amp;diff=6636</id>
		<title>MySQL 优化：优化 SQL 语句：优化 SELECT 语句</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=MySQL_%E4%BC%98%E5%8C%96%EF%BC%9A%E4%BC%98%E5%8C%96_SQL_%E8%AF%AD%E5%8F%A5%EF%BC%9A%E4%BC%98%E5%8C%96_SELECT_%E8%AF%AD%E5%8F%A5&amp;diff=6636"/>
		<updated>2023-04-26T19:34:59Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 条件过滤【？？？】 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:MySQL文档]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
查询以“SELECT”语句的形式执行数据库中的所有查找操作。&lt;br /&gt;
* 除了“SELECT”语句外，查询的调整技术还适用于：“CREATE TABLE...AS SELECT”，“INSERT INTO...SELECT”和“DELETE”语句中的“WHERE”子句。这些语句还有其他性能方面的考虑，因为它们将写操作与面向读取的查询操作结合在一起。&lt;br /&gt;
* NDB Cluster 支持 join 下推优化，将符合条件的 join 整体发送到 NDB Cluster 数据节点，在这些节点之间可以分布并并行执行。【？？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
优化查询的主要注意事项是：&lt;br /&gt;
# 要使慢速“SELECT ... WHERE”查询更快，首先要检查的是是否可以添加'''index'''。在“WHERE”子句中使用的列上设置索引，以加快评估，过滤和最终检索结果的速度。为了避免浪费磁盘空间，请构造一小组索引，以加快应用程序中使用的许多相关查询的速度。&lt;br /&gt;
#: 对于使用“joins”和“foreign keys”之类的功能引用不同表的查询，索引尤为重要。您可以使用“'''EXPLAIN'''”语句来确定 SELECT 使用哪些索引。&lt;br /&gt;
# 隔离并调整查询中花费时间过多的任何部分，例如函数调用。根据查询的结构方式，可以对结果集中的每一行调用一次函数，甚至可以对表中的每一行调用一次函数，从而极大地提高了效率。&lt;br /&gt;
# 最小化查询中的'''全表扫描'''数量，尤其是对于大表。&lt;br /&gt;
# 通过定期使用“'''ANALYZE TABLE'''”语句来使表统计信息保持最新，因此优化器具有构造有效执行计划所需的信息。&lt;br /&gt;
# 了解每个表的'''存储引擎'''特定的调整技术，索引技术和配置参数。InnoDB 和 MyISAM 都有一套准则，用于启用和维持查询的高性能。&lt;br /&gt;
# 避免以难以理解的方式转换查询，尤其是在优化程序自动执行某些相同转换的情况下。【？】&lt;br /&gt;
# 如果使用基本准则之一不能轻松解决性能问题，请通过阅读“EXPLAIN”计划并调整'''索引，WHERE 子句，join 子句'''等来调查特定查询的内部详细信息。&lt;br /&gt;
#* （当您达到一定的专业水平时，阅读 EXPLAIN 计划可能是每个查询的第一步。）【！】&lt;br /&gt;
# 调整 MySQL 用于缓存的内存区域的大小和属性。通过有效地使用'''InnoDB buffer pool（缓冲池），MyISAM 键高速缓存和 MySQL 查询高速缓存'''，重复查询的运行速度更快，因为第二次及以后都从内存中检索结果。&lt;br /&gt;
# 即使对于使用缓存区域快速运行的查询，您也可能会进一步优化，以使它们需要更少的缓存，从而使您的应用程序更具可伸缩性。可伸缩性意味着您的应用程序可以处理更多的并发用户，更大的请求等，而不会导致性能大幅下降。&lt;br /&gt;
# 处理'''锁'''问题，其中其他会话同时访问表可能会影响查询速度。&lt;br /&gt;
&lt;br /&gt;
== WHERE 子句优化【适用于“SELECT”、“DELETE”和“UPDATE”语句中的“WHERE”子句】==&lt;br /&gt;
您可能会试图重写查询以加快算术运算，同时牺牲可读性。&lt;br /&gt;
* 因为'''MySQL会自动进行类似的优化'''，所以通常可以避免这项工作，并以更易于理解和维护的形式保留查询。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
MySQL 执行的一些优化如下：&lt;br /&gt;
# 删除不必要的括号：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
((a AND b) AND c OR (((a AND b) AND (c AND d))))&lt;br /&gt;
-&amp;gt; (a AND b AND c) OR (a AND b AND c AND d)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 常数折叠：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(a&amp;lt;b AND b=c) AND a=5&lt;br /&gt;
-&amp;gt; b&amp;gt;5 AND b=c AND a=5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 常数条件移除：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(b&amp;gt;=5 AND b=5) OR (b=6 AND 5=5) OR (b=7 AND 5=6)&lt;br /&gt;
-&amp;gt; b=5 OR b=6&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 索引使用的常量表达式仅计算一次。&lt;br /&gt;
# '''“COUNT(*)”：在没有“WHERE”单表上，是直接从 MyISAM 和 MEMORY 表的表信息中检索的。'''&lt;br /&gt;
#* 当其仅与一个表一起使用时，对于任何“NOT NULL”表达式也将执行此操作。&lt;br /&gt;
# 早期检测无效常量表达式。MySQL很快检测到一些“SELECT”语句是不可能的，并且不返回任何行。&lt;br /&gt;
# '''如果不使用“GROUP BY”或集合函数（“COUNT()”、“MIN()”等），“HAVING”将与“WHERE”合并'''。&lt;br /&gt;
# 对于联接中的每个表，构造一个'''更简单的“WHERE”'''来快速计算表的“WHERE”，并尽快跳过行。&lt;br /&gt;
# 在查询中的所有其他表之前，首先读取所有'''常量表'''。常量表可以是以下任意一个：【？？？】&lt;br /&gt;
## 空表或具有一行的表。&lt;br /&gt;
## 在“主键”或“唯一索引”上使用“WHERE”子句的表，其中所有索引部分都与常量表达式进行比较，并定义为“NOT NULL”。【？】&lt;br /&gt;
#: 以下所有表均用作常量表：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t WHERE primary_key=1;&lt;br /&gt;
SELECT * FROM t1,t2&lt;br /&gt;
  WHERE t1.primary_key=1 AND t2.primary_key=t1.id;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 通过尝试所有可能的方法，找到用于联接表的最佳联接组合。'''如果“ORDER BY”和“GROUP BY”子句中的所有列都来自同一表，则在联接时优先使用该表。'''&lt;br /&gt;
# 如果有一个“ORDER BY”子句和另一个“GROUP BY”子句，或者“ORDER BY”或“GROUP BY”包含联接队列中第一个表以外的表中的列，则会创建一个临时表。【？？？】&lt;br /&gt;
# 如果使用“'''SQL_SMALL_RESULT'''”修饰符，则 MySQL 使用内存中的临时表。【？？？】&lt;br /&gt;
# 查询每个表索引，并使用'''最佳索引'''，除非优化程序认为使用全表扫描更有效。同时，使用扫描是基于最佳索引是否跨越了表的 30％以上，但是固定百分比不再决定使用索引还是扫描。现在，优化器更加复杂，其评估基于其他因素，例如表大小，行数和 I/O 块大小。&lt;br /&gt;
# 在输出每一行之前，将跳过与“HAVING”子句不匹配的行。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
快速查询示例：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(*) FROM tbl_name;&lt;br /&gt;
&lt;br /&gt;
SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;&lt;br /&gt;
&lt;br /&gt;
SELECT MAX(key_part2) FROM tbl_name&lt;br /&gt;
  WHERE key_part1=constant;&lt;br /&gt;
&lt;br /&gt;
SELECT ... FROM tbl_name&lt;br /&gt;
  ORDER BY key_part1,key_part2,... LIMIT 10;&lt;br /&gt;
&lt;br /&gt;
SELECT ... FROM tbl_name&lt;br /&gt;
  ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
假设索引列是数字，MySQL 仅使用索引树来解析以下查询：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;&lt;br /&gt;
&lt;br /&gt;
SELECT COUNT(*) FROM tbl_name&lt;br /&gt;
  WHERE key_part1=val1 AND key_part2=val2;&lt;br /&gt;
&lt;br /&gt;
SELECT key_part2 FROM tbl_name GROUP BY key_part1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
以下查询使用索引来按排序 Sequences 检索行，而无需单独的排序遍历：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT ... FROM tbl_name&lt;br /&gt;
  ORDER BY key_part1,key_part2,... ;&lt;br /&gt;
&lt;br /&gt;
SELECT ... FROM tbl_name&lt;br /&gt;
  ORDER BY key_part1 DESC, key_part2 DESC, ... ;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 范围优化【？？？？？？】 ==&lt;br /&gt;
range访问方法使用单个索引来检索包含在一个或几个索引值间隔内的表行的子集。它可以用于单部分或多部份索引。&lt;br /&gt;
&lt;br /&gt;
=== 单部分索引的范围访问方法【？？？】 ===&lt;br /&gt;
对于单部分索引，索引值间隔可以方便地由“WHERE”子句中的相应条件表示，表示为范围条件，而不是“间隔”。【？】&lt;br /&gt;
&lt;br /&gt;
单部分索引的范围条件的定义如下：&lt;br /&gt;
# 对于 B树 和 HASH 索引，使用'''='''，'''&amp;lt;=&amp;gt;'''，'''IN()'''，'''IS NULL'''或'''不为空'''运算符时，将关键部分与常量值进行比较是一个范围条件。&lt;br /&gt;
# 此外，对于 B树 索引，使用'''&amp;gt;'''，'''&amp;lt;'''，'''&amp;gt;='''，'''&amp;lt;='''，'''BETWEEN'''，'''!='''或'''&amp;lt;&amp;gt;'''运算符时，将关键部分与常量值进行比较是一个范围条件；&lt;br /&gt;
#* 如果'''LIKE'''的参数为常量字符串，则'''进行 LIKE 比较不能以通配符开头'''。&lt;br /&gt;
# 对于所有索引类型，将多个范围条件与'''OR'''或'''AND'''组合在一起可形成范围条件。&lt;br /&gt;
&lt;br /&gt;
前面的描述中的“常量值”表示以下之一：&lt;br /&gt;
# 查询字符串中的常量；&lt;br /&gt;
# 来自同一联接的常量或system表中的列；&lt;br /&gt;
# 不相关子查询的结果；&lt;br /&gt;
# 任何完全由上述类型的子表达式组成的表达式；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以下是“WHERE”子句中具有范围条件的查询示例：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_col &amp;gt; 1&lt;br /&gt;
  AND key_col &amp;lt; 10;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_col = 1&lt;br /&gt;
  OR key_col IN (15,18,20);&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_col LIKE 'ab%'&lt;br /&gt;
  OR key_col BETWEEN 'bar' AND 'foo';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 在优化程序常数传播阶段，某些非常数值可以转换为常数。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
MySQL 尝试从“WHERE”子句中为每个可能的索引'''提取范围条件'''。在提取过程中，删除了不能用于构建范围条件的条件，合并了产生重叠范围的条件，并删除了产生空范围的条件。【？？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：【？？？？？？？？？】&amp;lt;br/&amp;gt;&lt;br /&gt;
请考虑以下语句，其中 key1 是索引列，而 nonkey 没有索引：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE&lt;br /&gt;
  (key1 &amp;lt; 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR&lt;br /&gt;
  (key1 &amp;lt; 'bar' AND nonkey = 4) OR&lt;br /&gt;
  (key1 &amp;lt; 'uux' AND key1 &amp;gt; 'z');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
密钥 key1 的提取过程如下：&lt;br /&gt;
# 从原始的 WHERE 子句开始：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(key1 &amp;lt; 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR&lt;br /&gt;
(key1 &amp;lt; 'bar' AND nonkey = 4) OR&lt;br /&gt;
(key1 &amp;lt; 'uux' AND key1 &amp;gt; 'z')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 删除“nonkey = 4”【B树索引“=”结果不为范围】和“key1 LIKE '%b'”【“LIKE”以通配符开始结果不为范围】，因为它们不能用于范围扫描。删除它们的正确方法是将它们替换为“TRUE”，这样我们在进行范围扫描时就不会丢失任何匹配的行。用 TRUE 替换它们会产生：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(key1 &amp;lt; 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR&lt;br /&gt;
(key1 &amp;lt; 'bar' AND TRUE) OR&lt;br /&gt;
(key1 &amp;lt; 'uux' AND key1 &amp;gt; 'z')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 折叠始终为 true 或 false 的条件：&lt;br /&gt;
#* (key1 LIKE 'abcde%' OR TRUE) 始终为真&lt;br /&gt;
#* (key1 &amp;lt; 'uux' AND key1 &amp;gt; 'z') 始终为假&lt;br /&gt;
# 用常量替换这些条件将产生：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(key1 &amp;lt; 'abc' AND TRUE) OR (key1 &amp;lt; 'bar' AND TRUE) OR (FALSE)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 删除不必要的 TRUE 和 FALSE 常量将产生：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(key1 &amp;lt; 'abc') OR (key1 &amp;lt; 'bar')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将重叠的间隔合并为一个会产生用于范围扫描的最终条件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(key1 &amp;lt; 'bar')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
一般而言(如前面的示例所示)，范围扫描所使用的条件比“WHERE”子句的限制要少。 MySQL 执行附加检查以过滤出 满足范围条件但不完整的“WHERE”子句的行。【？】&lt;br /&gt;
&lt;br /&gt;
范围条件提取算法可以处理任意深度的嵌套 AND / OR 结构，并且其输出不取决于条件在 WHERE 子句中出现的顺序。&lt;br /&gt;
&lt;br /&gt;
MySQL 不支持为空间索引的range访问方法合并多个范围。要解决此限制，可以将“UNION”与相同的“SELECT”语句一起使用，除了将每个空间谓词放在不同的“SELECT”中。&lt;br /&gt;
&lt;br /&gt;
=== 多部分索引的范围访问方法【？？？】 ===&lt;br /&gt;
多部分索引的范围条件是单部分索引的范围条件的扩展。&lt;br /&gt;
&lt;br /&gt;
Multipart 索引的范围条件是单部分索引的范围条件的扩展。Multipart 索引上的范围条件将索引行限制在一个或几个键 Tuples 间隔内。使用从索引开始的 Sequences，在一组键 Tuples 上定义键 Tuples 间隔。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
例如，考虑定义为“key1(key_part1, key_part2, key_part3)”的 Multipart 索引，并按键 Sequences 列出以下一组键 Tuples：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1  key_part2  key_part3&lt;br /&gt;
  NULL       1          'abc'&lt;br /&gt;
  NULL       1          'xyz'&lt;br /&gt;
  NULL       2          'foo'&lt;br /&gt;
   1         1          'abc'&lt;br /&gt;
   1         1          'xyz'&lt;br /&gt;
   1         2          'abc'&lt;br /&gt;
   2         1          'aaa'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
条件“key_part1 = 1”定义了此间隔：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(1,-inf,-inf) &amp;lt;= (key_part1,key_part2,key_part3) &amp;lt; (1,+inf,+inf)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
该间隔涵盖了先前数据集中的第 4，第 5 和第 6 个 Tuples，并且可以由范围访问方法使用。&lt;br /&gt;
&lt;br /&gt;
相反，条件“key_part3 = 'abc'”并未定义单个间隔，并且不能被范围访问方法使用。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
关于范围条件如何作用于 Multipart 索引：【？？？】&lt;br /&gt;
# 对于 HASH 索引，可以使用每个包含相同值的间隔。【？？？】&lt;br /&gt;
#: 这意味着只能针对以下形式的条件生成间隔：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 cmp const1&lt;br /&gt;
AND key_part2 cmp const2&lt;br /&gt;
AND ...&lt;br /&gt;
AND key_partN cmp constN;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 这里，const1，const2，…是常量，cmp 是 =，&amp;lt;=&amp;gt; 或 IS NULL 比较运算符之一，并且条件涵盖所有索引部分。（也就是说，存在 N 条件， N-part 索引的每个部分都有一个条件）例如，以下是由三部分组成的 HASH索引 的范围条件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 = 1 AND key_part2 IS NULL AND key_part3 = 'foo'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 对于 B树 索引，间隔可用于与“AND”组合的条件，其中每个条件使用 =，&amp;lt;=&amp;gt;，IS NULL，&amp;gt;，&amp;lt;，&amp;gt;=，&amp;lt;=，!=，&amp;lt;&amp;gt;，BETWEEN 或 LIKE 'pattern' 将键部分与常数值进行比较（其中'pattern'不能以通配符开头）。只要可以确定包含所有与条件匹配的行的单个键 Tuples，就可以使用一个间隔（如果使用 &amp;lt;&amp;gt; 或 !=，则可以使用两个间隔)。【？？？】&lt;br /&gt;
#: 只要比较运算符是 =，&amp;lt;=&amp;gt; 或 IS NULL，优化器就会尝试使用其他关键部分来确定间隔。如果运算符是 &amp;gt;，&amp;lt;，&amp;gt;=，&amp;lt;=，!=，&amp;lt;&amp;gt;，BETWEEN 或 LIKE，则优化器将使用它，但不再考虑其他关键部分。对于以下表达式，优化器使用第一个比较中的 =。它还从第二次比较中使用 &amp;gt;=，但不考虑其他关键部分，并且不将第三次比较用于间隔构造：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 = 'foo' AND key_part2 &amp;gt;= 10 AND key_part3 &amp;gt; 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 单个间隔为：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
('foo',10,-inf) &amp;lt; (key_part1,key_part2,key_part3) &amp;lt; ('foo',+inf,+inf)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 创建的间隔可能包含比初始条件更多的行。例如，前面的时间间隔包含不满足原始条件的值('foo', 11, 0)。&lt;br /&gt;
# 如果将覆盖间隔中包含的行集合的条件与“OR”组合，则它们将形成覆盖间隔中的并集内包含的行集合的条件。如果条件与“AND”组合，则它们将形成一个条件，该条件覆盖其间隔的交点内包含的一组行。例如，对于由两部分组成的索引的这种情况：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(key_part1 = 1 AND key_part2 &amp;lt; 2) OR (key_part1 &amp;gt; 5)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 间隔为：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(1,-inf) &amp;lt; (key_part1,key_part2) &amp;lt; (1,2)&lt;br /&gt;
(5,-inf) &amp;lt; (key_part1,key_part2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 在此示例中，第一行的间隔使用一个关键部分作为左边界，使用两个关键部分作为右边界。第二行的间隔仅使用一个关键部分。 EXPLAIN 输出中的 key_len 列表示所使用的键前缀的最大长度。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在某些情况下，key_len 可能表明已使用了关键部件，但这可能不是您期望的。【？？？】&lt;br /&gt;
: 假设 key_part1 和 key_part2 可以是 NULL。然后 key_len 列显示以下条件的两个关键 Component 长度：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 &amp;gt;= 1 AND key_part2 &amp;lt; 2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 但是，实际上，条件已转换为：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 &amp;gt;= 1 AND key_part2 IS NOT NULL&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 多值比较的等距范围优化【？？？】 ===&lt;br /&gt;
考虑以下表达式，其中“col_name”是索引列：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
col_name IN(val1, ..., valN)&lt;br /&gt;
col_name = val1 OR ... OR col_name = valN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如果 col_name 等于多个值中的任何一个，则每个表达式为 true。这些比较是相等范围比较（其中“范围”是单个值）。优化器估算读取相等行以进行相等范围比较的成本，如下所示：&lt;br /&gt;
# 如果 col_name 上有唯一索引，则每个范围的行估计为 1，因为最多一行可以具有给定值。&lt;br /&gt;
# 否则，col_name 上的任何索引都是唯一的，优化器可以使用对索引或索引统计数据的深入估算来估计每个范围的行数。【？？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用'''索引下潜'''时，优化器在范围的每个末端进行下潜，并将范围中的行数用作估计值。例如，表达式“col_name IN (10, 20, 30)”具有三个相等范围，并且优化程序对每个范围进行两次下潜以生成行估计。每对下潜都会得出具有给定值的行数的估计值。【？？？】&lt;br /&gt;
* 索引下潜可提供准确的行估计，但是随着表达式中比较值的数量增加，优化器将花费更长的时间来生成行估计。使用索引统计信息的准确性不如使用索引统计法准确，但允许对大型值列表进行更快的行估计。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''eq_range_index_dive_limit'''系统变量使您可以配置优化器从一种行估计策略切换到另一种行估计策略的值的数量：&lt;br /&gt;
# 要允许索引下潜用于最多 N 个相等范围的比较，请将 eq_range_index_dive_limit 设置为 N + 1。&lt;br /&gt;
# 要禁用统计信息的使用，并且无论 N 始终使用索引潜水，请将 eq_range_index_dive_limit 设置为 0。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
要更新表索引统计信息以获得最佳估计值，请使用“'''ANALYZE TABLE'''”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
即使在本应使用索引下潜的条件下，对于满足所有这些条件的查询也将跳过它们：&lt;br /&gt;
# 存在单索引“FORCE INDEX”索引提示。其思想是，如果强制使用索引，那么执行下潜索引的额外开销将无济于事。&lt;br /&gt;
# 索引不是唯一的，不是“FULLTEXT”索引。&lt;br /&gt;
# 没有子查询。&lt;br /&gt;
# 没有“DISTINCT”，“GROUP BY”或“ORDER BY”子句。&lt;br /&gt;
这些下潜跳过条件仅适用于单表查询。对于多表查询（联接），不会跳过索引下潜。&lt;br /&gt;
&lt;br /&gt;
=== 行构造函数表达式的范围优化【？？？】 ===&lt;br /&gt;
优化程序可以将范围扫描访问方法应用于以下形式的查询：&lt;br /&gt;
'''&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' ));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
* 以前，要使用范围扫描，必须将查询编写为：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' )&lt;br /&gt;
OR ( col_1 = 'c' AND col_2 = 'd' );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
为了使优化器使用范围扫描，查询必须满足以下条件：&lt;br /&gt;
# '''仅使用“IN()”谓词，而不使用“NOT IN()”'''。&lt;br /&gt;
# 在“IN()”谓词的左侧，行构造函数仅包含列引用。&lt;br /&gt;
# 在“IN()”谓词的右侧，行构造函数仅包含运行时常量，这些常量是在执行期间绑定到常量的 Literals 或本地列引用。&lt;br /&gt;
# 在“IN()”谓词的右侧，有多个行构造器。&lt;br /&gt;
&lt;br /&gt;
=== 限制内存用于范围优化【？？？】 ===&lt;br /&gt;
要控制范围优化器可用的内存，请使用 '''range_optimizer_max_mem_size''' 系统变量：&lt;br /&gt;
# 值 0 表示“无限制”。&lt;br /&gt;
# 值大于 0 时，优化程序将在考虑范围访问方法时跟踪消耗的内存。如果将要超出指定的限制，则将放弃范围访问方法，而改为考虑其他方法，包括全表扫描。这可能不太理想。如果发生这种情况，则会发生以下警告（其中 N 是当前的 range_optimizer_max_mem_size 值）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
Warning    3170    Memory capacity of N bytes for&lt;br /&gt;
                   'range_optimizer_max_mem_size' exceeded. Range&lt;br /&gt;
                   optimization was not done for this query.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 对于“UPDATE”和“DELETE”语句，如果优化器退回到全表扫描并且启用了 sql_safe_updates 系统变量，则会发生错误而不是警告，因为实际上，没有键用于确定要修改的行。&lt;br /&gt;
* 对于超出可用范围优化内存的单个查询，并且对于该查询，优化器后退到次优计划，增大 range_optimizer_max_mem_size 值可以提高性能。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
若要估计处理范围表达式所需的内存量，请使用以下准则：【？】&lt;br /&gt;
# 对于如下所示的简单查询，其中存在一个用于范围访问方法的候选键，每个与“'''OR'''”谓词的组合大约使用 230 个字节：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(*) FROM t&lt;br /&gt;
WHERE a=1 OR a=2 OR a=3 OR .. . a=N;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 同样，对于以下查询，每个与“'''AND'''”谓词的组合大约使用 125 个字节：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(*) FROM t&lt;br /&gt;
WHERE a=1 AND b=1 AND c=1 ... N;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 对于带有“'''IN()'''”谓词的查询：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(*) FROM t&lt;br /&gt;
WHERE a IN (1,2, ..., M) AND b IN (1,2, ..., N);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* “IN()”列表中的每个 Literals 值都算作与“OR”组合的谓词。如果有两个“IN()”列表，则谓词与“OR”组合的数量是每个列表中 Literals 值数量的乘积。因此，在前一种情况下与OR组合的谓词数为“M × N”。&lt;br /&gt;
#* 在 5.7.11 之前，每个谓词与“OR”相结合的字节数更高，大约为 700 个字节。&lt;br /&gt;
&lt;br /&gt;
== '''索引合并'''优化 ==&lt;br /&gt;
索引合并访问方法'''检索具有多个范围扫描的行，并将其结果合并到一个范围扫描中'''。&lt;br /&gt;
* 此访问方法仅合并来自'''单表'''的索引扫描，而不合并跨多个表的扫描。&lt;br /&gt;
* 合并可以生成其基础扫描的并集、交集或交集的并集。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可能使用索引合并的示例查询：【？？？】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM tbl_name&lt;br /&gt;
  WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1, t2&lt;br /&gt;
  WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')&lt;br /&gt;
  AND t2.key1 = t1.some_col;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1, t2&lt;br /&gt;
  WHERE t1.key1 = 1&lt;br /&gt;
  AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note：'''&amp;lt;br/&amp;gt;&lt;br /&gt;
索引合并优化算法的已知限制：&lt;br /&gt;
# 如果您的查询有一个带有深度“AND”/“OR”嵌套的复杂“WHERE”子句，并且 MySQL 没有选择最佳方案，请尝试使用以下标识转换分发术语：【？】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(x AND y) OR z =&amp;gt; (x OR z) AND (y OR z)&lt;br /&gt;
(x OR y) AND z =&amp;gt; (x AND z) OR (y AND z)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 索引合并不适用于全文索引。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在 '''EXPLAIN''' 输出中，索引合并方法在“type”列中显示为“index_merge”。 在这种情况下，“key”列包含使用的索引列表，而“key_len”包含这些索引的最长键部分的列表。&lt;br /&gt;
: 索引合并访问方法有几个算法，这些算法显示在 EXPLAIN 输出中的“Extra”字段：&lt;br /&gt;
* Using intersect(...)&lt;br /&gt;
* Using union(...)&lt;br /&gt;
* Using sort_union(...)&lt;br /&gt;
索引合并的使用取决于“optimizer_switch”系统变量的“index_merge”，“index_merge_intersection”，“index_merge_union”和“index_merge_sort_union”标志的值。&lt;br /&gt;
: 默认情况下，所有这些标志均为 on。要仅启用某些算法，请将 index_merge 设置为 off，并仅启用应允许的其他算法。&lt;br /&gt;
&lt;br /&gt;
=== 索引合并“交叉”访问算法 ===&lt;br /&gt;
当表的“WHERE”子句转换为不同键上的多个范围条件并用“'''AND'''”组合在一起，并且每个条件是以下之一时，此访问算法适用：&lt;br /&gt;
# 这种形式的 N 部分表达式，其中索引正好有 N 部分（即，所有索引部分都包含在内）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 = const1 AND key_part2 = const2 ... AND key_partN = constN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# InnoDB 表主键上的任何范围条件。&lt;br /&gt;
示例：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM innodb_table&lt;br /&gt;
  WHERE primary_key &amp;lt; 10 AND key_col1 = 20;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM tbl_name&lt;br /&gt;
  WHERE key1_part1 = 1 AND key1_part2 = 2 AND key2 = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
索引合并交集算法对所有使用的索引执行'''同时扫描'''，并生成从合并索引扫描接收到的行序列的'''交集'''。&lt;br /&gt;
&lt;br /&gt;
# 如果查询中使用的所有列都被使用的索引覆盖，则不会检索完整的表行（在这种情况下，“EXPLAIN”在“Extra”字段输出中包含“Using index”）。这是此类查询的示例：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(*) FROM t1 WHERE key1 = 1 AND key2 = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 如果使用的索引未覆盖查询中使用的所有列，则仅在满足所有使用的键的范围条件时才检索完整行。【？】&lt;br /&gt;
如果合并的条件之一是 InnoDB 表的主键上的条件，则该条件不用于行检索，而是用于过滤出使用其他条件检索的行。【？】&lt;br /&gt;
&lt;br /&gt;
=== 索引合并“联合”访问算法 ===&lt;br /&gt;
（似于索引“合并”交集算法的标准）&amp;lt;br/&amp;gt;&lt;br /&gt;
当表的“WHERE”子句转换为不同键上的多个范围条件并用“'''OR'''”组合在一起，并且每个条件是以下条件之一时，该算法适用：&lt;br /&gt;
# 这种形式的 N 部分表达式，其中索引正好有 N 部分（即，所有索引部分都包含在内）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
key_part1 = const1 OR key_part2 = const2 ... OR key_partN = constN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# InnoDB 表主键上的任何范围条件。&lt;br /&gt;
# 索引“合并”交集算法适用的条件。&lt;br /&gt;
示例：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key1 = 1 OR key2 = 2 OR key3 = 3;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM innodb_table&lt;br /&gt;
  WHERE (key1 = 1 AND key2 = 2)&lt;br /&gt;
     OR (key3 = 'foo' AND key4 = 'bar') AND key5 = 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 索引合并“排序联合”访问算法 ===&lt;br /&gt;
当“WHERE”子句转换为“'''OR'''”组合的多个范围条件，但不适用于索引合并“联合”算法时，此访问算法适用。&lt;br /&gt;
示例：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM tbl_name&lt;br /&gt;
  WHERE key_col1 &amp;lt; 10 OR key_col2 &amp;lt; 20;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM tbl_name&lt;br /&gt;
  WHERE (key_col1 &amp;gt; 10 OR key_col2 = 20) AND nonkey_col = 30;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
“排序联合”算法和“联合”算法的区别在于：“排序联合”算法必须首先获取所有行的行 id，并在返回任何行之前对它们进行排序。【？？？】&lt;br /&gt;
&lt;br /&gt;
== 引擎条件“下推”优化【“非索引列”和“常量”之间直接比较】 ==&lt;br /&gt;
这种优化提高了'''“非索引列”和“常量”之间直接比较'''的效率。在这种情况下，条件将“推入”存储引擎进行评估。&lt;br /&gt;
* 此优化只能由'''NDB'''存储引擎使用。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于 NDB Cluster，这种优化可以消除在集群的数据节点和发出查询的 MySQL 服务器之间通过网络发送不匹配行的需要。并且相对于未使用条件下推的案例，可以提高 5 到 10 倍的查询速度。【！】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&amp;lt;br/&amp;gt;&lt;br /&gt;
假设 NDB 群集表定义如下：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t1 (&lt;br /&gt;
    a INT,&lt;br /&gt;
    b INT,&lt;br /&gt;
    KEY(a)&lt;br /&gt;
) ENGINE=NDB;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
条件下推可以用于查询，例如此处显示的查询，其中包括'''非索引列和常量之间的比较'''：【包括使用“'''&amp;gt;'''”或“'''&amp;lt;'''”运算符】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT a, b FROM t1 WHERE b = 10;&lt;br /&gt;
SELECT a, b FROM t1 WHERE a &amp;lt; 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
在'''EXPLAIN'''的输出中可以看到条件下推的使用：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot; highlight=&amp;quot;6,12&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; EXPLAIN SELECT a,b FROM t1 WHERE b = 10\G&lt;br /&gt;
*************************** 1. row ***************************&lt;br /&gt;
           id: 1&lt;br /&gt;
  select_type: SIMPLE&lt;br /&gt;
        table: t1&lt;br /&gt;
         type: ALL&lt;br /&gt;
possible_keys: NULL&lt;br /&gt;
          key: NULL&lt;br /&gt;
      key_len: NULL&lt;br /&gt;
          ref: NULL&lt;br /&gt;
         rows: 10&lt;br /&gt;
        Extra: Using where with pushed condition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot; highlight=&amp;quot;6,12&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; EXPLAIN SELECT a, b FROM t1 WHERE a &amp;lt; 2\G&lt;br /&gt;
*************************** 1. row ***************************&lt;br /&gt;
           id: 1&lt;br /&gt;
  select_type: SIMPLE&lt;br /&gt;
        table: t1&lt;br /&gt;
         type: range&lt;br /&gt;
possible_keys: a&lt;br /&gt;
          key: a&lt;br /&gt;
      key_len: 5&lt;br /&gt;
          ref: NULL&lt;br /&gt;
         rows: 2&lt;br /&gt;
        Extra: Using where with pushed condition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
但条件下推与以下两个查询'''不能一起使用'''：【！！！】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT a,b FROM t1 WHERE a = 10;&lt;br /&gt;
SELECT a,b FROM t1 WHERE b + 1 = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''列上存在索引'''；【索引访问方法将更有效，因此将优先于条件下推】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT a,b FROM t1 WHERE a = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''涉及的非索引列是间接的'''；&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT a,b FROM t1 WHERE b + 1 = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
条件下推支持的其他比较包括：&lt;br /&gt;
# column [NOT] '''LIKE''' pattern&lt;br /&gt;
#* pattern 必须是包含要匹配的模式的字符串 Literals；&lt;br /&gt;
# column '''IS''' [NOT] '''NULL'''&lt;br /&gt;
# column '''IN''' (value_list)&lt;br /&gt;
#* value_list 中的每个项目都必须是恒定的 Literals 值。&lt;br /&gt;
# column '''BETWEEN''' constant1 '''AND''' constant2&lt;br /&gt;
#* constant1 和 constant2 必须分别是一个常量 Literals 值。&lt;br /&gt;
在上述列表中的所有情况下，都有可能将条件转换为列与常量之间的一个或多个直接比较的形式。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
默认情况下，引擎条件下推处于启用状态。要在服务器启动时禁用它，请设置“optimizer_switch”系统变量。例如，在“my.cnf”文件中，使用以下几行：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
optimizer_switch=engine_condition_pushdown=off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
或，在运行时，禁用条件下推，如下所示：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SET optimizer_switch='engine_condition_pushdown=off';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
引擎条件下推的'''限制'''：&lt;br /&gt;
# 条件下推仅受'''NDB'''存储引擎支持。&lt;br /&gt;
# 列只能与常量进行比较；但是，这包括计算结果为常数的表达式。&lt;br /&gt;
# 比较中使用的列不能是任何“BLOB”或“TEXT”类型。此排除范围也扩展到“JSON”，“BIT”和“ENUM”列。&lt;br /&gt;
# 要与列进行比较的字符串值必须使用与列相同的排序规则。&lt;br /&gt;
# 不直接支持联接。涉及多表的条件将在可能的情况下分别推送。使用扩展的“EXPLAIN”输出来确定实际推低哪些条件。&lt;br /&gt;
&lt;br /&gt;
== 索引条件“下推”优化【将部分“WHERE”条件下推到存储引擎】 ==&lt;br /&gt;
索引条件下推（'''ICP'''）是针对 MySQL 使用索引从表中检索行的情况的优化。&lt;br /&gt;
# 如果没有 ICP，则存储引擎将遍历索引以在基表中定位行，并将其返回给 MySQL 服务器，该 MySQL 服务器将评估这些行的“WHERE”条件。【“存储引擎”：定位查找】&lt;br /&gt;
#* 不使用“索引条件下推”的情况下，如何进行索引扫描：&lt;br /&gt;
#*# 获取下一行，首先读取索引元组，然后使用索引元组查找并读取整个表行。&lt;br /&gt;
#*# 测试适用于此表的“WHERE”条件的一部分。根据测试结果接受或拒绝该行。&lt;br /&gt;
# 启用 ICP 后，如果“WHERE”条件的某些部分'''可以仅使用索引中的列进行评估'''，则 MySQL 服务器会将这部分“WHERE”条件下推到存储引擎。然后，存储引擎通过使用索引项来评估推送的索引条件，并且只有在满足此条件的情况下，才从表中读取行。 【“存储引擎”：先评估，再定位查找】&lt;br /&gt;
#* 使用“索引条件下推”的情况下，如何进行索引扫描：&lt;br /&gt;
#*# 获取下一行的索引元组（而不是整个表行）。&lt;br /&gt;
#*# 测试适用于此表、可仅使用索引列检查的“WHERE”条件部分。如果不满足条件，则转到下一行的索引元组。&lt;br /&gt;
#*# 如果满足条件，请使用索引元组来定位和读取整个表行。&lt;br /&gt;
#*# 测试适用于此表的“WHERE”条件的其余部分。根据测试结果接受或拒绝行。&lt;br /&gt;
#* 减少了：&lt;br /&gt;
#*# 存储引擎必须访问基表的次数；&lt;br /&gt;
#*# MySQL 服务器必须访问存储引擎的次数；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
索引条件下推优化的适用性取决于以下条件：&lt;br /&gt;
# 当需要访问完整表行时，ICP 用于“range”，“ref”，“eq_ref”和“ref_or_null”访问方法。&lt;br /&gt;
# ICP 可用于 InnoDB 和 MyISAM 表，包括分区的 InnoDB 和 MyISAM 表。&lt;br /&gt;
# 对于 InnoDB 表，ICP 仅用于'''辅助索引'''。&lt;br /&gt;
#* ICP 的目标是减少全行读取的次数，从而减少 I/O 操作。对于 InnoDB 聚集索引，完整的记录已被读取到 InnoDB 缓冲区中。在这种情况下使用 ICP 不会减少 I/O。&lt;br /&gt;
# 在虚拟生成的列上创建的二级索引不支持 ICP。 InnoDB 支持虚拟生成的列上的二级索引。&lt;br /&gt;
# '''引用子查询的条件不能下推'''。&lt;br /&gt;
# 涉及存储函数的条件不能下推。存储引擎无法调用存储的函数。&lt;br /&gt;
# 触发条件不能下推。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 当使用“索引条件下推”时，“'''EXPLAIN'''”输出在“Extra”列中显示“'''Using index condition'''”。 &lt;br /&gt;
** 它不会显示“Using index”，因为在必须读取整个表行时，该方法不适用。&lt;br /&gt;
* 默认情况下，索引条件下推处于启用状态。可以通过使用“optimizer_switch”系统变量设置“index_condition_pushdown”标志来进行控制：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SET optimizer_switch = 'index_condition_pushdown=off';&lt;br /&gt;
SET optimizer_switch = 'index_condition_pushdown=on';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&amp;lt;br/&amp;gt;&lt;br /&gt;
假设一个表包含有关人员及其地址的信息，并且该表的索引定义为 INDEX (zipcode, lastname, firstname)。如果我们知道一个人的 zipcode 值，但不确定姓氏，可以这样搜索：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM people&lt;br /&gt;
  WHERE zipcode='95054'&lt;br /&gt;
  AND lastname LIKE '%etrunia%'&lt;br /&gt;
  AND address LIKE '%Main Street%';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
MySQL可以使用索引来扫描“zipcode='95054'”的人。&lt;br /&gt;
# 第二部分（lastname，如“%etrunia%”）不能用于限制必须扫描的行数【不使用索引】，因此如果没有“索引条件”下推，此查询必须检索“zipcode='95054'”的所有人的完整表行。&lt;br /&gt;
# 通过索引条件下推，MySQL '''在读取整个表行之前检查“lastname LIKE '%etrunia%'”部分。这避免了读取与匹配“zipcode”条件但不匹配“lastname”条件的索引元组相对应的完整行'''。&lt;br /&gt;
&lt;br /&gt;
== “'''嵌套循环连接'''”算法 ==&lt;br /&gt;
MySQL 使用嵌套循环算法或其上的变体在表之间执行联接。&lt;br /&gt;
&lt;br /&gt;
=== “嵌套循环连接”算法（NLJ） ===&lt;br /&gt;
一个简单的嵌套循环联接（NLJ）算法：一次从一个循环中的第一个表中读取行，然后将每一行传递给一个嵌套循环，该循环处理联接中的下一个表。重复此过程的次数与要连接的表的次数相同。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&amp;lt;br/&amp;gt;&lt;br /&gt;
假设要使用以下联接类型执行三个表 t1，t2 和 t3 之间的联接：【？】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
Table   Join Type&lt;br /&gt;
t1      range&lt;br /&gt;
t2      ref&lt;br /&gt;
t3      ALL&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如果使用简单的 NLJ 算法，则按以下方式处理联接：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
for each row in t1 matching range {&lt;br /&gt;
  for each row in t2 matching reference key {&lt;br /&gt;
    for each row in t3 {&lt;br /&gt;
      if row satisfies join conditions, send to client&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
因为 NLJ 算法一次将行从外循环传递到内循环，所以它通常会'''多次读取在内循环中处理的表'''。&lt;br /&gt;
&lt;br /&gt;
=== “块嵌套循环连接”算法（BNL） ===&lt;br /&gt;
块嵌套循环（BNL）连接算法：'''使用外部循环中读取的行的缓冲，来减少必须读取内部循环中的表的次数'''。&lt;br /&gt;
: 例如，如果将 10 行读入一个缓冲区并将该缓冲区传递给下一个内部循环，则可以将内部循环中读取的每一行与缓冲区中的所有10行进行比较。这将使必须读取内部表的次数减少一个数量级。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
MySQL 连接缓冲具有以下 Feature：&lt;br /&gt;
# 当联接的类型为“ALL”或“index”（换句话说，当无法使用任何可能的键，并且分别对数据行或索引行进行完全扫描时）或“range”时，可以使用联接缓冲。【？？？】&lt;br /&gt;
#* 缓冲的使用也适用于外部联接。&lt;br /&gt;
# 连接缓冲区永远不会为第一个非恒定表分配，即使其类型为“ALL”或“index”。&lt;br /&gt;
# 联接中只有感兴趣的列存储在其联接缓冲区中，而不是整个行。&lt;br /&gt;
# join_buffer_size 系统变量确定用于处理查询的每个连接缓冲区的大小。&lt;br /&gt;
# 为每个可以缓冲的连接分配一个缓冲区，因此可以使用多个连接缓冲区来处理给定查询。&lt;br /&gt;
# '''在执行连接之前分配一个连接缓冲区，并在查询完成后释放连接缓冲区'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&amp;lt;br/&amp;gt;&lt;br /&gt;
对于先前为 NLJ 算法描述的示例连接（不带缓冲），使用连接缓冲按如下方式进行连接：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for each row in t1 matching range {&lt;br /&gt;
  for each row in t2 matching reference key {&lt;br /&gt;
    store used columns from t1, t2 in join buffer&lt;br /&gt;
    if buffer is full {&lt;br /&gt;
      for each row in t3 {&lt;br /&gt;
        for each t1, t2 combination in join buffer {&lt;br /&gt;
          if row satisfies join conditions, send to client&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      empty join buffer&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if buffer is not empty {&lt;br /&gt;
  for each row in t3 {&lt;br /&gt;
    for each t1, t2 combination in join buffer {&lt;br /&gt;
      if row satisfies join conditions, send to client&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
如果 S 是连接缓冲区中每个已存储的 t1，t2 组合的大小，并且 C 是缓冲区中的组合数目，则对表 t3 进行扫描的次数为：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(S * C)/join_buffer_size + 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
t3 的扫描次数随着 join_buffer_size 的值增加而减少，直到 join_buffer_size 足够大以容纳所有先前的行组合为止。那时，通过增大它无法获得任何速度。&lt;br /&gt;
&lt;br /&gt;
== 嵌套联接优化 ==&lt;br /&gt;
&lt;br /&gt;
== Outer Join 优化【？？？】 ==&lt;br /&gt;
外部联接包括“'''LEFT JOIN'''”和“'''RIGHT JOIN'''”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
MySQL 实现了“A LEFT JOIN B join_specification”（左连接规范），如下所示：【在说屁】&lt;br /&gt;
# 表 B 设置为取决于表 A 以及 A 所依赖的所有表。&lt;br /&gt;
# 表 A 设置为依赖于“LEFT JOIN”条件中使用的所有表（除 B 外）。&lt;br /&gt;
# “LEFT JOIN”条件用于决定如何从表 B 中检索行。（换句话说，不使用“WHERE”子句中的任何条件）&lt;br /&gt;
# 执行所有标准的连接优化，不同之处在于'''始终在 表所依赖的所有表 之后读取该表'''。&lt;br /&gt;
#* 如果存在循环依赖关系，则会发生错误。&lt;br /&gt;
# 执行所有标准的“WHERE”优化。&lt;br /&gt;
# 如果 A 中存在与“WHERE”子句匹配的行，但 B 中没有与“ON”条件匹配的行，则会生成多余的 B 行，并将所有列都设置为 NULL。【？】&lt;br /&gt;
# 如果您使用“LEFT JOIN”查找某个表中不存在的行，并进行以下测试：在“WHERE”中使用“col_name IS NULL”，而 col_name 是声明为 NOT NULL 的列，则在找到符合“LEFT JOIN”条件的一行之后 MySQL 停止搜索更多行（对于特定行组合键）。【？】&lt;br /&gt;
* “RIGHT JOIN”的实现类似于“LEFT JOIN”的实现，但表角色相反。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于“LEFT JOIN”，'''如果“WHERE”条件对于生成的“NULL”行始终为 false，则“LEFT JOIN”更改为内部联接'''。【？】&lt;br /&gt;
: 例如，如果 t2.column1 是 NULL，则在以下查询中 WHERE 子句为 false：&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:因此，将查询转换为内部联接是安全的：&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
现在，优化程序可以在表 t1 之前使用表 t2，如果这样做会导致更好的查询计划。&lt;br /&gt;
* 要提供有关表连接顺序的提示，请使用“'''STRAIGHT_JOIN'''”。但是，STRAIGHT_JOIN 可能会禁止使用索引，因为它禁用了半联接转换。【'''“STRAIGHT_JOIN”强制优化器按照“FROM”子句中列出的顺序连接表'''】&lt;br /&gt;
&lt;br /&gt;
== Outer Join 简化 ==&lt;br /&gt;
&lt;br /&gt;
== 多范围读取优化【？】 ==&lt;br /&gt;
问题：当表较大且未存储在存储引擎的高速缓存中时，在辅助索引上使用范围扫描来读取行会导致对表的许多随机磁盘访问。&lt;br /&gt;
&lt;br /&gt;
通过磁盘扫描“多范围读取”（Multi-Range Read，'''MRR'''）优化：&lt;br /&gt;
# MySQL 尝试通过首先仅扫描索引并收集相关行的键来减少用于范围扫描的随机磁盘访问次数。&lt;br /&gt;
# 然后对键进行排序，最后使用主键的顺序从基表中检索行。&lt;br /&gt;
磁盘扫描 MRR 的动机是减少随机磁盘访问的次数，并对基表数据进行更有序的扫描。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
多范围读取优化具有以下优点：&lt;br /&gt;
# MRR 使基于索引元组的数据行可以顺序访问，而不是以随机顺序访问。服务器获取一组满足查询条件的索引元组，并根据数据行 ID 顺序对它们进行排序，然后使用排序后的元组按顺序检索数据行。这使得数据访问更加高效且成本更低。&lt;br /&gt;
# 对于需要通过索引元组访问数据行的操作（例如范围索引扫描和使用索引作为联接属性的等联接），MRR 支持对键访问请求的批处理。 MRR 在一系列索引范围内进行迭代以获得合格的索引元组。随着这些结果的累积，它们将用于访问相应的数据行，而在开始读取数据行之前不必获取所有索引元组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在虚拟生成的列上创建的二级索引不支持 MRR 优化。【InnoDB 支持虚拟生成的列上的二级索引】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以下方案说明了 MRR 优化何时可以发挥优势：&lt;br /&gt;
# 方案 A：MRR 可用于 InnoDB 和 MyISAM 表，以进行索引范围扫描和等联接操作。&lt;br /&gt;
## 索引元组的一部分累积在缓冲区中。&lt;br /&gt;
## 缓冲区中的元组按其数据行 ID 排序。&lt;br /&gt;
## 根据排序的索引元组序列访问数据行。&lt;br /&gt;
# 方案 B：MRR 可用于 '''NDB''' 表以进行多范围索引扫描，或在通过属性执行均等联接时使用。【？？？】&lt;br /&gt;
## 一部分范围（可能是单键范围）累积在提交查询的中心节点上的缓冲区中。【？】&lt;br /&gt;
## 范围被发送到访问数据行的执行节点。【？】&lt;br /&gt;
## 被访问的行被打包到程序包中并发送回中心节点。【？】&lt;br /&gt;
## 收到的带有数据行的数据包将放置在缓冲区中。【？】&lt;br /&gt;
## 从缓冲区读取数据行。【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
使用 MRR 时，“EXPLAIN”输出中的“Extra”列显示“Using MRR”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE：&lt;br /&gt;
* 如果不需要访问完整表行以产生查询结果，则 InnoDB 和 MyISAM 不使用 MRR。&lt;br /&gt;
*: 如果可以完全基于索引元组中的信息（通过covering index）产生结果，则这种情况 MRR 没有任何好处。&lt;br /&gt;
* 两个“optimizer_switch”系统变量标志提供了使用 MRR 优化的接口：'''mrr'''标志控制是否启用 MRR。&lt;br /&gt;
*: 如果启用了mrr(on)，则'''mrr_cost_based'''标志控制优化器是尝试在使用还是不使用 MRR（on）之间做出基于成本的选择，还是在可能的情况下（off）使用 MRR。&lt;br /&gt;
** 默认情况下，mrr 是 on，mrr_cost_based 是 on。&lt;br /&gt;
* 对于 MRR，存储引擎使用“read_rnd_buffer_size”系统变量的值作为可为其缓冲区分配的内存大小。引擎最多使用 read_rnd_buffer_size 个字节，并确定一次处理要处理的范围数。&lt;br /&gt;
&lt;br /&gt;
== 阻止嵌套循环和批量key访问联接 ==&lt;br /&gt;
&lt;br /&gt;
== 条件过滤【？？？】 ==&lt;br /&gt;
在联接处理中，'''前缀行'''是“从联接中的一个表传递到下一个表的那些行”。通常，优化程序会尝试在连接顺序的早期放置前缀计数较低的表，以防止行组合的数量迅速增加。&lt;br /&gt;
* 在某种程度上，优化器可以使用有关从一个表中选择并传递到下一个表的行的条件的信息，它可以更准确地计算行估计并选择最佳执行计划。&lt;br /&gt;
关于“'''条件过滤'''”：&lt;br /&gt;
# 在没有“条件过滤”的情况下，表的前缀行计数基于：“WHERE”子句根据“优化器选择的访问方法”所选择的估计行数。【？】&lt;br /&gt;
# 通过“条件过滤”，优化器可以使用“WHERE”子句中访问方法未考虑的其他相关条件，从而改善其前缀行数估计。【？】&lt;br /&gt;
#: 例如，即使可以使用基于索引的访问方法从联接中的当前表中选择行，“WHERE”子句中的表也可能有其他条件，可以筛选（进一步限制）传递到下一个表的限定行的估值。【？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
仅在以下情况下，'''条件'''才有助于过滤估计：【？？？】&lt;br /&gt;
# 它引用当前表。&lt;br /&gt;
# 它取决于连接序列中一个或多个常量值。&lt;br /&gt;
# 访问方法尚未考虑它。【？？？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在“'''EXPLAIN'''”输出中：“rows”列指示所选访问方法的行估计，而“filtered”列反映条件过滤的效果。 filtered值表示为百分比。最大值为 100，表示没有行过滤发生。值从 100 减小表示过滤量增加。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
前缀行数（估计从当前表通过联接传递到下一个表的行数）是 rows 和 filtered 值的乘积。即，前缀行数是估计的行数，该估计的行数由于估计的滤波效果而减少。&lt;br /&gt;
: 例如，如果 rows 为 1000 且 filtered 为 20％，则条件过滤会将估算的行数 1000 减少为前缀行数 1000×20％= 1000×0.2 = 200.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例：'''【？？？？？？】&amp;lt;br/&amp;gt;&lt;br /&gt;
考虑以下查询：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT *&lt;br /&gt;
  FROM employee JOIN department ON employee.dept_no = department.dept_no&lt;br /&gt;
  WHERE employee.first_name = 'John'&lt;br /&gt;
  AND employee.hire_date BETWEEN '2018-01-01' AND '2018-06-01';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
假设数据集具有以下 Feature：&lt;br /&gt;
# employee 表具有 1024 行。&lt;br /&gt;
# department 表有 12 行。&lt;br /&gt;
# 两个表在 dept_no 上都有一个索引。&lt;br /&gt;
# employee 表在 first_name 上具有索引。&lt;br /&gt;
# 8 个行在 employee.first_name 上满足此条件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
employee.first_name = 'John'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 150 个行在employee.hire_date上满足此条件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
employee.hire_date BETWEEN '2018-01-01' AND '2018-06-01'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 1 行满足以下两个条件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
employee.first_name = 'John'&lt;br /&gt;
AND employee.hire_date BETWEEN '2018-01-01' AND '2018-06-01'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
没有条件过滤，EXPLAIN 会产生如下输出：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
+----+------------+--------+------------------+---------+---------+------+----------+&lt;br /&gt;
| id | table      | type   | possible_keys    | key     | ref     | rows | filtered |&lt;br /&gt;
+----+------------+--------+------------------+---------+---------+------+----------+&lt;br /&gt;
| 1  | employee   | ref    | name,h_date,dept | name    | const   | 8    | 100.00   |&lt;br /&gt;
| 1  | department | eq_ref | PRIMARY          | PRIMARY | dept_no | 1    | 100.00   |&lt;br /&gt;
+----+------------+--------+------------------+---------+---------+------+----------+&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 对于employee，在name索引上的访问方法将拾取与名称'John'匹配的 8 行。没有进行任何过滤(filtered为 100％)，因此所有行都是下一张表的前缀行：前缀行计数为 rows×filtered = 8×100％= 8。&lt;br /&gt;
通过条件过滤，优化器还考虑了 WHERE 子句中的条件，而访问方法并未考虑这些条件。在这种情况下，优化器使用'''试探法'''【？？？】来估计 employee.hire_date 上的 BETWEEN 条件的过滤效果为 16.31％。结果，EXPLAIN 产生如下输出：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
+----+------------+--------+------------------+---------+---------+------+----------+&lt;br /&gt;
| id | table      | type   | possible_keys    | key     | ref     | rows | filtered |&lt;br /&gt;
+----+------------+--------+------------------+---------+---------+------+----------+&lt;br /&gt;
| 1  | employee   | ref    | name,h_date,dept | name    | const   | 8    | 16.31    |&lt;br /&gt;
| 1  | department | eq_ref | PRIMARY          | PRIMARY | dept_no | 1    | 100.00   |&lt;br /&gt;
+----+------------+--------+------------------+---------+---------+------+----------+&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 现在，前缀行计数为rows×filtered = 8×16.31％= 1.3，它更紧密地反映了实际数据集。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通常，优化器不会为最后一个联接表计算条件过滤效果（前缀行数减少），因为没有下一个表可以将行传递给该表。 EXPLAIN 发生异常：为了提供更多信息，将为所有联接的表（包括最后一个表）计算过滤效果。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
要控制优化器是否考虑其他过滤条件，请使用“'''optimizer_switch'''”系统变量的“'''condition_fanout_filter'''”标志。&lt;br /&gt;
* 默认情况下，此标志是启用的，但可以禁用它以抑制条件过滤（例如，如果发现特定查询不使用它会产生更好的性能）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果优化器高估了条件过滤的效果，则性能可能会比不使用条件过滤的情况差。在这种情况下，这些技术可能会帮助：&lt;br /&gt;
# 如果未对列进行'''索引'''，请对其进行索引，以便优化程序获得有关列值分布的一些信息，并可以改善其行估计。&lt;br /&gt;
# 更改'''联接顺序'''。完成此操作的方法包括连接顺序优化器提示，紧跟在 SELECT 之后的 STRAIGHT_JOIN 以及 STRAIGHT_JOIN 连接运算符。&lt;br /&gt;
# 禁用会话的条件过滤：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SET optimizer_switch = 'condition_fanout_filter=off';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IS NULL 优化 ==&lt;br /&gt;
MySQL 可以对“col_name IS NULL”执行与“col_name = constant_value”相同的优化。&lt;br /&gt;
: 例如，MySQL 可以使用索引和范围来搜索带有“IS NULL”的 NULL。&lt;br /&gt;
: 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM tbl_name WHERE key_col IS NULL;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM tbl_name WHERE key_col &amp;lt;=&amp;gt; NULL;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM tbl_name WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 如果“WHERE”子句包含声明为“NOT NULL”的列的“col_name IS NULL”条件，则该表达式将被优化。&lt;br /&gt;
** 在该列无论如何都会产生 NULL 的情况下（例如，如果它来自“LEFT JOIN”右侧的表），则不会进行此优化。&lt;br /&gt;
* MySQL 还可以优化组合“col_name = expr OR col_name IS NULL”，这种形式在已解析的子查询中很常见。使用此优化时，EXPLAIN 显示“ref_or_null”。&lt;br /&gt;
* 此优化可以为任何关键部分处理一个“IS NULL”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
假设在表 t2 的列 a 和 b 上有索引，则对查询进行一些优化的示例：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE t1.a=expr OR t1.a IS NULL;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1, t2 WHERE t1.a=t2.a OR t2.a IS NULL;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1, t2&lt;br /&gt;
  WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1, t2&lt;br /&gt;
  WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL);&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1, t2&lt;br /&gt;
  WHERE (t1.a=t2.a AND t2.a IS NULL AND ...)&lt;br /&gt;
  OR (t1.a=t2.a AND t2.a IS NULL AND ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* “ref_or_null”的工作方式是先读取参考键，然后单独搜索具有 NULL 键值的行。【？？？】&lt;br /&gt;
* '''优化只能处理一个“IS NULL”级别'''。&lt;br /&gt;
*: 在以下查询中，MySQL 仅在表达式“(t1.a=t2.a AND t2.a IS NULL)”上使用键查找，而不能在 b 上使用键部分：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1, t2&lt;br /&gt;
  WHERE (t1.a=t2.a AND t2.a IS NULL)&lt;br /&gt;
  OR (t1.b=t2.b AND t2.b IS NULL);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ORDER BY 优化【？】 ==&lt;br /&gt;
=== 使用索引满足 ORDER BY ===&lt;br /&gt;
在某些情况下，MySQL 可以使用索引来满足“ORDER BY”子句，并避免执行 filesort 操作【？？？】时涉及的额外排序。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
即使“ORDER BY”与索引不完全匹配，也可以使用索引：&lt;br /&gt;
# 只要索引的所有未使用部分和所有额外“ORDER BY”列都是“WHERE”子句中的常量。&lt;br /&gt;
# 如果索引不包含查询访问的所有列，则仅当索引访问比其他访问方法便宜时才使用索引。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例1：'''使用索引来解析 ORDER BY&amp;lt;br/&amp;gt;&lt;br /&gt;
假设“(key_part1, key_part2)”上有一个索引，以下查询可以使用该索引来解析“ORDER BY”部分。【'''优化器是否实际上这样做取决于如果还必须读取索引中没有的列，则读取索引是否比表扫描更有效'''。】&lt;br /&gt;
* 在此查询中，(key_part1, key_part2) 上的索引使优化程序避免排序：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  ORDER BY key_part1, key_part2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: 但是，查询使用“SELECT *”，它选择的列可能多于“key_part1”和“key_part2”。在这种情况下，扫描整个索引并查找表行以查找索引中未包含的列可能比扫描表并排序结果要昂贵。如果是这样，优化器可能不会使用该索引。【如果“SELECT *”仅选择索引列，则将使用索引并避免排序。】&lt;br /&gt;
*: 如果 t1 是 InnoDB 表，则表主键隐式属于索引的一部分，并且该索引可用于解析此查询的 ORDER BY：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT pk, key_part1, key_part2 FROM t1&lt;br /&gt;
  ORDER BY key_part1, key_part2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 在此查询中，key_part1 是常量，因此通过索引访问的所有行都按 key_part2 顺序，并且如果 WHERE 子句的选择性足以使索引范围扫描比表扫描便宜，则 (key_part1, key_part2) 上的索引可以避免排序：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_part1 = constant&lt;br /&gt;
  ORDER BY key_part2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 在接下来的两个查询中，是否使用索引类似于前面没有显示“DESC”的相同查询：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  ORDER BY key_part1 DESC, key_part2 DESC;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_part1 = constant&lt;br /&gt;
  ORDER BY key_part2 DESC;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 在接下来的两个查询中，将 key_part1 与常量进行比较。如果 WHERE 子句的选择性足以使索引范围扫描比表扫描便宜，那么将使用索引：【！！！】&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_part1 &amp;gt; constant&lt;br /&gt;
  ORDER BY key_part1 ASC;&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_part1 &amp;lt; constant&lt;br /&gt;
  ORDER BY key_part1 DESC;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 在下一个查询中，ORDER BY 不命名 key_part1，但是所有选择的行都有一个常量 key_part1 值，因此仍可以使用索引：【？？？】&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1&lt;br /&gt;
  WHERE key_part1 = constant1 AND key_part2 &amp;gt; constant2&lt;br /&gt;
  ORDER BY key_part2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例2：'''不能使用索引来解析 ORDER BY，尽管它仍可以使用索引来查找与 WHERE 子句匹配的行。&amp;lt;br/&amp;gt;&lt;br /&gt;
* 该查询对不同的索引使用 ORDER BY：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 ORDER BY key1, key2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 该查询在索引的非连续部分上使用 ORDER BY：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE key2=constant ORDER BY key1_part1, key1_part3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 该查询混合了“ASC”和“DESC”：【！！！】&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 用于获取行的索引与在 ORDER BY 中使用的索引不同：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE key2=constant ORDER BY key1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 该查询使用 ORDER BY，且表达式中包含除索引列名称以外的术语：【！！！】&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 ORDER BY ABS(key);&lt;br /&gt;
SELECT * FROM t1 ORDER BY -key;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 该查询联接了许多表，并且 ORDER BY 中的列并非全部来自用于检索行的第一个非恒定表。&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 该查询具有不同的“ORDER BY”和“GROUP BY”表达式。【！！！】&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 仅在“ORDER BY”子句中命名的列的前缀上存在索引。在这种情况下，索引不能用于完全解析排序顺序。【！！！】&lt;br /&gt;
*: 例如，如果仅对“CHAR(20)”列的前 10 个字节进行索引，则索引无法区分第 10 个字节之后的值，因此需要'''filesort'''。&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 索引不按顺序存储行。例如，这对于内存表中的哈希索引是正确的。【！！！】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE：'''&amp;lt;br/&amp;gt;&lt;br /&gt;
* 索引的可用性可能会受到'''列别名'''的使用的影响。假设对 t1.a 列进行了索引。在此语句中，选择列表中列的名称为 a。它引用 t1.a，就像在 ORDER BY 中引用 a 一样，因此可以使用 t1.a 上的索引：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT a FROM t1 ORDER BY a;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: 在此语句中，选择列表中列的名称也是 a，但这是别名。它引用“ABS(a)”，就像引用 ORDER BY 中的 a 一样，因此不能使用 t1.a 上的索引：【？？？】&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT ABS(a) AS a FROM t1 ORDER BY a;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: 在下面的语句中，ORDER BY 引用的名称不是选择列表中列的名称。但是 t1 中有一列名为 a，因此 ORDER BY 指向 t1.a 且可以使用 t1.a 上的索引。（当然，生成的排序顺序可能与“ABS(a)”的顺序完全不同）&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT ABS(a) AS b FROM t1 ORDER BY a;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 默认情况下，MySQL 对“'''GROUP BY''' col1, col2, ...”查询进行排序，就好像您在查询中也包含了“'''ORDER BY''' col1, col2, ...”一样。如果您包含一个显式的“ORDER BY”子句，该子句包含相同的列列表，则 MySQL 会对其进行优化，而不会造成任何速度损失，尽管排序仍然会发生。【！！！“GROUP BY”和“ORDER BY”】&lt;br /&gt;
** 如果查询包含“GROUP BY”，但您希望'''避免对结果进行排序的开销'''，则可以通过指定 '''ORDER BY NULL''' 来抑制排序。例如：&lt;br /&gt;
'''&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
INSERT INTO foo&lt;br /&gt;
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
** 优化器可能仍选择使用排序来实现分组操作。 “ORDER BY NULL”禁止对结果进行排序，而不是通过分组操作来确定结果的先前排序。 &lt;br /&gt;
** 【默认情况下，“GROUP BY”隐式排序（即“GROUP BY”列没有“ASC”或“DESC”指示符）。但是，不建议依靠“GROUP BY”排序（隐式或显示都不建议）。要产生给定的排序顺序，请提供“ORDER BY”子句。】&lt;br /&gt;
&lt;br /&gt;
=== 使用 filesort 满足 ORDER BY 【？？？】===&lt;br /&gt;
如果不能使用索引来满足“ORDER BY”子句，则 MySQL 执行“filesort操作”以读取表行并对它们进行排序。'''filesort构成查询执行中的额外排序阶段'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
为了获得filesort操作的内存，优化器会预先分配固定数量的“sort_buffer_size”字节。各个会话可以根据需要更改此变量的会话值，以避免过多的内存使用，或根据需要分配更多的内存。&lt;br /&gt;
&lt;br /&gt;
如果结果集太大而无法容纳在内存中，则 filesort 操作会根据需要使用临时磁盘文件。某些类型的查询特别适合完全在内存中的filesort操作。&lt;br /&gt;
: 例如，优化器可以使用filesort来有效地在内存中处理“ORDER BY”操作，而无需使用临时文件，该“ORDER BY”操作用于以下形式的查询(和子查询)：【？？？】&lt;br /&gt;
'''&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT ... FROM single_table ... ORDER BY non_index_column [DESC] LIMIT [M,]N;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;'''&lt;br /&gt;
此类查询在仅显示较大结果集中的几行的 Web 应用程序中很常见。&lt;br /&gt;
: 示例：【？？？】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT col1, ... FROM t1 ... ORDER BY name LIMIT 10;&lt;br /&gt;
SELECT col1, ... FROM t1 ... ORDER BY RAND() LIMIT 15;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 影响 ORDER BY 优化 ===&lt;br /&gt;
对于不使用filesort的慢“ORDER BY”查询，请尝试将“'''max_length_for_sort_data'''”系统变量降低为适合触发filesort的值。【将此变量的值设置得太高的症状是磁盘活动过多和 CPU 活动较低的组合】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
要提高“ORDER BY”的速度，请检查是否可以使 MySQL 使用索引而不是额外的排序阶段。如果这不可能，请尝试以下策略：&lt;br /&gt;
# 增加“'''sort_buffer_size'''”变量值。理想情况下，该值应足够大以使整个结果集适合排序缓冲区（以避免写入磁盘和合并过程），但该值至少必须足够大以容纳 15 个元组。（最多合并 15 个临时磁盘文件，并且每个文件中至少必须有一个元组在内存中）&lt;br /&gt;
#: 考虑到存储在排序缓冲区中的列值的大小受“'''max_sort_length'''”系统变量值的影响。【例如，如果元组存储长字符串列的值，而您增加了“max_sort_length”的值，则排序缓冲区元组的大小也会增加，并且可能需要您增加“max_sort_length”。】对于由字符串表达式（例如调用字符串值函数的结果）计算出的列值，filesort算法无法确定表达式值的最大长度，因此必须为每个元组分配“max_sort_length”个字节。【？？？】&lt;br /&gt;
#: 要监视合并通过次数（以合并临时文件），请检查“Sort_merge_passes” status 变量。&lt;br /&gt;
# 增加“'''read_rnd_buffer_size'''”变量值，以便一次读取更多行。&lt;br /&gt;
# 更改'''tmpdir'''系统变量以指向具有大量可用空间的专用文件系统。变量值可以列出以循环方式使用的多个路径。&lt;br /&gt;
#* 您可以使用此功能将负载分散到多个目录中。在 Unix 上用冒号(:)和在 Windows 上用分号(;)分隔路径。路径应命名位于不同物理磁盘上的文件系统中的目录，而不是同一磁盘上的不同分区。&lt;br /&gt;
&lt;br /&gt;
=== ORDER BY 执行计划信息可用 ===&lt;br /&gt;
使用'''EXPLAIN'''，可以检查 MySQL 是否可以使用索引来解析“ORDER BY”子句：&lt;br /&gt;
* 如果 EXPLAIN 输出的“Extra”列不包含“Using filesort”，则使用索引，而不执行filesort。&lt;br /&gt;
* 如果 EXPLAIN 输出的“Extra”列包含“'''Using filesort'''”，则不使用索引，而执行filesort。&lt;br /&gt;
此外，如果执行filesort，则优化器跟踪输出将包含 filesort_summary 块。例如：【？】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;filesort_summary&amp;quot;: {&lt;br /&gt;
  &amp;quot;rows&amp;quot;: 100,&lt;br /&gt;
  &amp;quot;examined_rows&amp;quot;: 100,&lt;br /&gt;
  &amp;quot;number_of_tmp_files&amp;quot;: 0,&lt;br /&gt;
  &amp;quot;sort_buffer_size&amp;quot;: 25192,&lt;br /&gt;
  &amp;quot;sort_mode&amp;quot;: &amp;quot;&amp;lt;sort_key, packed_additional_fields&amp;gt;&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
其中，“sort_mode”值提供有关排序缓冲区中元组内容的信息：&lt;br /&gt;
* &amp;lt;sort_key, rowid&amp;gt;：这表明排序缓冲区是元组对，包含原始表行的“排序键值”和“行 ID”。元组按排序键值排序，并且行 ID 用于从表中读取行。&lt;br /&gt;
* &amp;lt;sort_key, additional_fields&amp;gt;：这表明排序缓冲区元组包含“排序键值”和“查询所引用的列”。元组通过排序键值进行排序，并且列值直接从元组中读取。&lt;br /&gt;
* &amp;lt;sort_key, packed_additional_fields&amp;gt;：与以前的变体一样，但其他列紧密地包装在一起，而不是使用固定长度的编码。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
EXPLAIN 不能区分优化器是否在内存中执行filesort。在优化器跟踪输出中可以看到内存中filesort的使用。寻找filesort_priority_queue_optimization。【？？？】&lt;br /&gt;
&lt;br /&gt;
== GROUP BY 优化【？？？】 ==&lt;br /&gt;
满足“GROUP BY”子句的最通用方法是：'''扫描整个表'''并创建一个'''新的临时表'''，其中每个组中的所有行都是连续的，然后使用该临时表发现组并应用聚合函数（如果有）。&lt;br /&gt;
* 在某些情况下，MySQL 可以做得更好，并且'''可以使用索引访问来避免创建临时表'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
为“GROUP BY”使用索引的最重要的先决条件是，所有“GROUP BY”列都引用同一索引中的属性，并且索引按顺序存储其键（例如，对于 B树 索引是这样，但对于 HASH 索引则不是这样）。&lt;br /&gt;
临时表的使用是否可以替换为索引访问，还取决于在查询中使用索引的哪些部分、为这些部分指定的条件以及所选的聚合函数。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
有两种通过索引访问执行 GROUP BY 查询的方法，如以下各节所述。第一种方法将分组操作与所有范围谓词(如果有)一起应用。第二种方法首先执行范围扫描，然后对所得的 Tuples 进行分组。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在 MySQL 中，使用 GROUP BY 进行排序，因此服务器也可以将 ORDER BY 优化应用于分组。但是，不建议依赖隐式或显式 GROUP BY 排序。&lt;br /&gt;
&lt;br /&gt;
=== 松散索引扫描 ===&lt;br /&gt;
处理 GROUP BY 的最有效方法是'''使用索引直接检索分组列'''。&lt;br /&gt;
: 通过这种访问方法，MySQL 使用键排序的某些索引类型的属性（例如 B树）。使用此属性，可以在索引中使用查找组，而不必考虑索引中满足所有 WHERE 条件的所有键。此访问方法仅考虑索引中的一部分键，因此称为“松散索引扫描”。&lt;br /&gt;
# 如果没有 WHERE 子句，则“松散索引扫描”将读取与组数一样多的键，该数目可能比所有键的数目小得多。&lt;br /&gt;
# 如果 WHERE 子句包含范围谓词，则“松散索引扫描”将查找满足范围条件的每个组的第一个键，并再次读取尽可能少的键数。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在以下情况下可以这样做：&lt;br /&gt;
# 查询是在单个表上。&lt;br /&gt;
# GROUP BY 仅命名构成索引最左前缀的列，不命名其他列。（如果查询具有 DISTINCT 子句，而不是 GROUP BY，则所有不同的属性都引用构成索引最左前缀的列）&lt;br /&gt;
#: 例如，如果表 t1 在(c1,c2,c3)上具有索引，则松散索引扫描适用于查询具有“GROUP BY c1, c2”。如果查询具有“GROUP BY c2, c3”（列不是最左边的前缀）或“GROUP BY c1, c2, c4”（c4不在索引中），则此方法不适用。&lt;br /&gt;
# 选择列表中使用的唯一聚合函数（如果有）是“MIN()”和“MAX()”，它们全部引用同一列。该列必须在索引中，并且必须紧接着 GROUP BY 中的列。&lt;br /&gt;
# 除了“MIN()”或“MAX()”函数的参数外，除查询中所引用的 GROUP BY 之外的其他任何索引部分都必须是常量（即，必须与常量相等地引用）。&lt;br /&gt;
# 对于索引中的列，必须索引完整的列值，而不仅仅是索引。&lt;br /&gt;
#: 例如，对于 c1 VARCHAR(20), INDEX (c1(10))，索引仅使用 c1 值的前缀，不能用于宽松索引扫描。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果“宽松索引扫描”适用于查询，则“EXPLAIN”输出在“Extra”列中显示“Using index for group-by”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&amp;lt;br/&amp;gt;&lt;br /&gt;
假设在表 t1(c1,c2,c3,c4) 上有一个索引 idx(c1,c2,c3)。松散索引扫描访问方法可用于以下查询：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT c1, c2 FROM t1 GROUP BY c1, c2;&lt;br /&gt;
SELECT DISTINCT c1, c2 FROM t1;&lt;br /&gt;
SELECT c1, MIN(c2) FROM t1 GROUP BY c1;&lt;br /&gt;
SELECT c1, c2 FROM t1 WHERE c1 &amp;lt; const GROUP BY c1, c2;&lt;br /&gt;
SELECT MAX(c3), MIN(c3), c1, c2 FROM t1 WHERE c2 &amp;gt; const GROUP BY c1, c2;&lt;br /&gt;
SELECT c2 FROM t1 WHERE c1 &amp;lt; const GROUP BY c1, c2;&lt;br /&gt;
SELECT c1, c2 FROM t1 WHERE c3 = const GROUP BY c1, c2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
无法使用此快速选择方法执行以下查询：&lt;br /&gt;
# 除 MIN() 或 MAX() 以外，还有其他聚合函数：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT c1, SUM(c2) FROM t1 GROUP BY c1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# GROUP BY 子句中的列不构成索引的最左前缀：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT c1, c2 FROM t1 GROUP BY c2, c3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 该查询引用的是 GROUP BY 部分之后的键的一部分，并且该部分与常量不相等：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT c1, c3 FROM t1 GROUP BY c1, c2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 如果查询包含 WHERE c3 = const，则可以使用松散索引扫描。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
除了已经支持的“MIN()”和“MAX()”引用之外，“松散索引扫描”访问方法还可以应用于选择列表中的其他形式的聚合函数引用：&lt;br /&gt;
# 支持“AVG(DISTINCT)”，“SUM(DISTINCT)”和“COUNT(DISTINCT)”。&lt;br /&gt;
#* “AVG(DISTINCT)”和“SUM(DISTINCT)”采用一个参数。 “COUNT(DISTINCT)”可以有多个列参数。&lt;br /&gt;
# 查询中不得包含“”GROUP BY或“”DISTINCT子句。&lt;br /&gt;
# 先前描述的松散索引扫描限制仍然适用。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&amp;lt;br/&amp;gt;&lt;br /&gt;
假设在表 t1(c1,c2,c3,c4) 上有一个索引 idx(c1,c2,c3)。松散索引扫描访问方法可用于以下查询：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT COUNT(DISTINCT c1), SUM(DISTINCT c1) FROM t1;&lt;br /&gt;
&lt;br /&gt;
SELECT COUNT(DISTINCT c1, c2), COUNT(DISTINCT c2, c1) FROM t1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 紧密索引扫描 ===&lt;br /&gt;
紧密索引扫描可以是完全索引扫描，也可以是范围索引扫描，具体取决于查询条件。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
当不满足松散索引扫描的条件时，仍然可以避免为 GROUP BY 查询创建临时表。如果 WHERE 子句中存在范围条件，则此方法仅读取满足这些条件的键。否则，它将执行索引扫描。由于此方法读取 WHERE 子句定义的每个范围内的所有键，或者如果没有范围条件，则扫描整个索引，因此称为紧密索引扫描。对于紧密索引扫描，只有在找到满足范围条件的所有键之后，才执行分组操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
要使此方法起作用，查询中的所有列都有一个常量相等条件就足够了，该查询引用的部分键位于 GROUP BY 键的部分之前或部分之间。相等条件中的常量填充搜索键中的任何“空白”，以便可以形成索引的完整前缀。这些索引前缀可用于索引查找。如果 group by 结果需要排序，并且可以形成作为索引前缀的搜索键，MySQL还可以避免额外的排序操作，因为在有序索引中使用前缀进行搜索已经按顺序检索所有键。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&amp;lt;br/&amp;gt;&lt;br /&gt;
假设在表 t1(c1,c2,c3,c4) 上有一个索引 idx(c1,c2,c3)。以下查询不适用于前面所述的“松散索引扫描”访问方法，但仍适用于“紧索引扫描”访问方法。&lt;br /&gt;
# GROUP BY 中有一个缝隙，但已被条件c2 = 'a'覆盖：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT c1, c2, c3 FROM t1 WHERE c2 = 'a' GROUP BY c1, c3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# GROUP BY并非以键的第一部分开头，但是存在为该部分提供常量的条件：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT c1, c2, c3 FROM t1 WHERE c1 = 'a' GROUP BY c2, c3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DISTINCT 优化 ==&lt;br /&gt;
在许多情况下，'''“DISTINCT”和“ORDER BY”结合需要一个临时表'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在大多数情况下，'''“DISTINCT”子句可以视为“GROUP BY”的特例'''。例如，以下两个查询是等效的：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT DISTINCT c1, c2, c3 FROM t1&lt;br /&gt;
WHERE c1 &amp;gt; const;&lt;br /&gt;
&lt;br /&gt;
SELECT c1, c2, c3 FROM t1&lt;br /&gt;
WHERE c1 &amp;gt; const GROUP BY c1, c2, c3;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
由于这种等效性，适用于“GROUP BY”查询的优化也可以应用于带有“DISTINCT”子句的查询。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 当结合“LIMIT row_count”和“DISTINCT”时，MySQL 一旦找到 row_count 个唯一行，就会停止运行。&lt;br /&gt;
* 如果不使用查询中命名的所有表中的列，MySQL会在找到第一个匹配项后立即停止扫描任何未使用的表。&lt;br /&gt;
*: 在以下情况下，假设在 t2 之前使用 t1（您可以使用“EXPLAIN”进行检查），则当 MySQL 在 t2 中找到第一行时，它将停止从 t2（对于 t1 中的任何特定行）读取：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT DISTINCT t1.a FROM t1, t2 where t1.a=t2.a;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LIMIT 查询优化 ==&lt;br /&gt;
【LIMIT：从结果集中只需要指定数量的行，而非整个结果集】&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MySQL 有时会优化具有“LIMIT row_count”子句而没有“HAVING”子句的查询：&lt;br /&gt;
# 如果只选择“LIMIT”的几行，MySQL在某些情况下会使用索引，而'''通常它会执行全表扫描'''。&lt;br /&gt;
# 如果将“LIMIT row_count”和“ORDER BY”结合使用，MySQL 会在找到排序结果前面的 row_count 个行后立即停止排序，而'''不是对整个结果进行排序'''。&lt;br /&gt;
#* 如果通过使用索引进行排序，这将非常快。&lt;br /&gt;
#* 如果必须执行“filesort”（文件排序？），则在找到前面的 row_count 个行之前，将选择所有匹配但不带有 LIMIT 子句的行，并对其中的大多数或全部进行排序。找到初始行后，MySQL 不会对结果集的其余部分进行排序。【？】&lt;br /&gt;
#*【此行为的一种体现是，具有和不具有 LIMIT 的 ORDER BY 查询可能以不同的 Sequences 返回行】&lt;br /&gt;
# 如果将“LIMIT row_count”和“DISTINCT”结合使用，MySQL 将在找到 row_count 唯一行后立即停止。&lt;br /&gt;
# 在某些情况下，可以通过按顺序读取索引（或对索引进行排序），然后计算汇总直到索引值更改来解决“GROUP BY”。在这种情况下，“LIMIT row_count”不会计算任何不必要的“GROUP BY”值。&lt;br /&gt;
# MySQL 一旦向 Client 端发送了所需的行数，它将立即中止查询，除非您使用“'''SQL_CALC_FOUND_ROWS'''”【见：“[http://wiki.eijux.com/MySQL_%E5%87%BD%E6%95%B0%E5%92%8C%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%9A%E4%BF%A1%E6%81%AF%E5%87%BD%E6%95%B0 MySQL 函数和运算符：信息函数]”的“FOUND_ROWS()”部分，其用于“知道该语句在没有 LIMIT 的情况下将返回多少行”】。&lt;br /&gt;
#* 在这种情况下，可以使用“SELECT FOUND_ROWS()”检索行数。&lt;br /&gt;
# “LIMIT 0”快速返回一个空集。这对于检查查询的有效性很有用。&lt;br /&gt;
#* 它还可以用于获取使用 MySQL API 的应用程序中结果列元数据的类型的结果列的类型。通过mysql Client 端程序，您可以使用“--column-type-info”选项显示结果列类型。【？】&lt;br /&gt;
# 如果服务器使用临时表来解析查询，则它使用“LIMIT row_count”子句来计算所需的空间。【？】&lt;br /&gt;
# 如果没有为“ORDER BY”使用索引，但是也存在“LIMIT”子句，则优化器可能能够避免使用合并文件，并使用内存中“filesort”操作对内存中的行进行排序。【？】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果“ORDER BY”列中的多行具有相同的值，服务器可以按任意顺序返回这些行，并且根据总体执行计划的不同，返回的顺序也可能不同。换句话说，这些行的排序顺序相对于非排序列是不确定的。&lt;br /&gt;
** 影响执行计划的一个因素是“LIMIT”，因此具有 LIMIT 和不具有 LIMIT 的“ORDER BY”查询可能以不同的顺序返回行。&lt;br /&gt;
**: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; SELECT * FROM ratings ORDER BY category;&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
| id | category | rating |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
|  1 |        1 |    4.5 |&lt;br /&gt;
|  5 |        1 |    3.2 |&lt;br /&gt;
|  3 |        2 |    3.7 |&lt;br /&gt;
|  4 |        2 |    3.5 |&lt;br /&gt;
|  6 |        2 |    3.5 |&lt;br /&gt;
|  2 |        3 |    5.0 |&lt;br /&gt;
|  7 |        3 |    2.7 |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
&lt;br /&gt;
mysql&amp;gt; SELECT * FROM ratings ORDER BY category LIMIT 5;&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
| id | category | rating |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
|  1 |        1 |    4.5 |&lt;br /&gt;
|  5 |        1 |    3.2 |&lt;br /&gt;
|  4 |        2 |    3.5 |&lt;br /&gt;
|  3 |        2 |    3.7 |&lt;br /&gt;
|  6 |        2 |    3.5 |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** 要确保带有 LIMIT 和不带有 LIMIT 的行顺序相同，请在 ORDER BY 子句中包括其他列以使顺序确定。&lt;br /&gt;
**: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; SELECT * FROM ratings ORDER BY category, id;&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
| id | category | rating |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
|  1 |        1 |    4.5 |&lt;br /&gt;
|  5 |        1 |    3.2 |&lt;br /&gt;
|  3 |        2 |    3.7 |&lt;br /&gt;
|  4 |        2 |    3.5 |&lt;br /&gt;
|  6 |        2 |    3.5 |&lt;br /&gt;
|  2 |        3 |    5.0 |&lt;br /&gt;
|  7 |        3 |    2.7 |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
&lt;br /&gt;
mysql&amp;gt; SELECT * FROM ratings ORDER BY category, id LIMIT 5;&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
| id | category | rating |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
|  1 |        1 |    4.5 |&lt;br /&gt;
|  5 |        1 |    3.2 |&lt;br /&gt;
|  3 |        2 |    3.7 |&lt;br /&gt;
|  4 |        2 |    3.5 |&lt;br /&gt;
|  6 |        2 |    3.5 |&lt;br /&gt;
+----+----------+--------+&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 函数调用优化 ==&lt;br /&gt;
MySQL 函数在内部被标记为确定性或不确定性。&lt;br /&gt;
* 不确定：如果给定参数固定值的函数可以'''为不同的调用返回不同的结果'''。如：“RAND()”，“UUID()”。&lt;br /&gt;
&lt;br /&gt;
如果一个函数被标记为不确定的，则对 WHERE 子句中的每一行（从一个表中选择时）或行组合（从多表联接中选择时）的引用进行评估。&lt;br /&gt;
&lt;br /&gt;
MySQL 还根据参数的类型（参数是表列还是常量值）确定何时评估函数。每当表列更改值时，都必须评估将表列作为参数的确定性函数。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''非确定性函数可能会影响查询性能'''。例如，某些优化可能不可用，或者可能需要更多锁定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
假设表 t 具有以下定义：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t (id INT NOT NULL PRIMARY KEY, col_a VARCHAR(100));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
考虑以下两个查询：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t WHERE id = POW(1,2);&lt;br /&gt;
SELECT * FROM t WHERE id = FLOOR(1 + RAND() * 49);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
由于与主键的相等性比较，两个查询似乎都使用了主键查找，但这仅适用于第一个查询：&lt;br /&gt;
# 第一个查询始终最多产生一行，因为带有常量参数的“POW()”是常量值，用于索引查找。&lt;br /&gt;
# 第二个查询包含一个使用不确定函数“RAND()”的表达式，该函数在查询中不是常量，但实际上对于表 t 的每一行都有一个新值。因此，查询将读取表的每一行，评估每一行的谓词，并输出主键与随机值匹配的所有行。这可能是零行，一行或多行，具体取决于 id 列的值和 RAND() 序列中的值。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''不确定性的影响不仅限于“SELECT”语句'''。此“UPDATE”语句使用非确定性函数来选择要修改的行：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
UPDATE t SET col_a = some_expr WHERE id = FLOOR(1 + RAND() * 49);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
大概的目的是最多更新主键与表达式匹配的一行。但是，它可能更新零，一或多个行，具体取决于 id 列的值和 RAND() 序列中的值。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
刚刚描述的行为对性能和复制有影响：&lt;br /&gt;
* 由于不确定函数不会产生恒定值，因此优化器无法使用其他可能适用的策略，例如索引查找。结果可能是全表扫描。&lt;br /&gt;
* InnoDB 可能升级为范围键锁定，而不是为一个匹配的行获取单个行锁定。&lt;br /&gt;
* 无法确定执行的更新对于复制是不安全的。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
困难源于对表的每一行都对“RAND()”函数进行一次评估的事实。为了避免进行多功能评估，请使用以下技术之一：&lt;br /&gt;
# 将包含不确定性函数的表达式移到单独的语句，将值保存在'''变量'''中。在原始语句中，'''将表达式替换为对变量的引用'''，优化器可以将该变量视为常量值：【！】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SET @keyval = FLOOR(1 + RAND() * 49);&lt;br /&gt;
UPDATE t SET col_a = some_expr WHERE id = @keyval;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 将随机值分配给派生表中的'''变量'''。此技术使变量'''在 WHERE 子句中的比较中使用之前被分配一个值'''：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SET optimizer_switch = 'derived_merge=off';&lt;br /&gt;
UPDATE t, (SELECT @keyval := FLOOR(1 + RAND() * 49)) AS dt&lt;br /&gt;
SET col_a = some_expr WHERE id = @keyval;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 如前所述，WHERE 子句中的不确定性表达式可能会阻止优化并导致表扫描。但是，如果其他表达式是确定性的，则可以部分优化 WHERE 子句。例如：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t WHERE partial_key=5 AND some_column=RAND();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 如果优化器可以使用“partial_key”来减少所选行的集合，则执行“RAND()”的次数将减少，从而减少了不确定性对优化的影响。&lt;br /&gt;
&lt;br /&gt;
== 行构造函数表达式优化 ==&lt;br /&gt;
行构造函数【？？？就是用函数表示条件语句？？？】允许'''同时比较多个值'''。&lt;br /&gt;
: 例如，以下两个语句在语义上是等效的：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1 WHERE (column1,column2) = (1,1);&lt;br /&gt;
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 另外，优化器以'''相同的方式处理两个表达式'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果行构造器的列不覆盖索引的前缀，则优化器不太可能使用可用索引。&lt;br /&gt;
&lt;br /&gt;
示例：表在(c1, c2, c3)上具有主键：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE t1 (&lt;br /&gt;
  c1 INT, c2 INT, c3 INT, c4 CHAR(100),&lt;br /&gt;
  PRIMARY KEY(c1,c2,c3)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
在此查询中，WHERE 子句使用索引中的所有列。但是，行构造器本身不包含索引前缀，因此优化器仅使用 c1：【“key_len=4”：c1的大小，而非联合主键的大小】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot; highlight=&amp;quot;2,8,11,12&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; EXPLAIN SELECT * FROM t1&lt;br /&gt;
       WHERE c1=1 AND (c2,c3) &amp;gt; (1,1)\G&lt;br /&gt;
*************************** 1. row ***************************&lt;br /&gt;
           id: 1&lt;br /&gt;
  select_type: SIMPLE&lt;br /&gt;
        table: t1&lt;br /&gt;
   partitions: NULL&lt;br /&gt;
         type: ref&lt;br /&gt;
possible_keys: PRIMARY&lt;br /&gt;
          key: PRIMARY&lt;br /&gt;
      key_len: 4&lt;br /&gt;
          ref: const&lt;br /&gt;
         rows: 3&lt;br /&gt;
     filtered: 100.00&lt;br /&gt;
        Extra: Using where&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
在这种情况下，使用等效的'''“非构造函数表达式”'''重写“行构造函数表达式”可能会导致更完整的索引使用。对于给定的查询，行构造函数 和等效的 非构造函数表达式 为：【？？？】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
(c2,c3) &amp;gt; (1,1)&lt;br /&gt;
c2 &amp;gt; 1 OR ((c2 = 1) AND (c3 &amp;gt; 1))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
使用索引中的所有三列重写查询以使用非构造函数表达式会在优化器中产生结果：【“key_len=12”：非联合主键的大小】&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot; highlight=&amp;quot;2,8,11,12&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; EXPLAIN SELECT * FROM t1&lt;br /&gt;
       WHERE c1 = 1 AND (c2 &amp;gt; 1 OR ((c2 = 1) AND (c3 &amp;gt; 1)))\G&lt;br /&gt;
*************************** 1. row ***************************&lt;br /&gt;
           id: 1&lt;br /&gt;
  select_type: SIMPLE&lt;br /&gt;
        table: t1&lt;br /&gt;
   partitions: NULL&lt;br /&gt;
         type: range&lt;br /&gt;
possible_keys: PRIMARY&lt;br /&gt;
          key: PRIMARY&lt;br /&gt;
      key_len: 12&lt;br /&gt;
          ref: NULL&lt;br /&gt;
         rows: 3&lt;br /&gt;
     filtered: 100.00&lt;br /&gt;
        Extra: Using where&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
因此，为了获得更好的结果，请'''避免将行构造函数与“AND”/“OR”表达式混合使用'''。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在某些情况下，优化器可以将范围访问方法应用于具有行构造函数参数的“IN()”表达式。&lt;br /&gt;
&lt;br /&gt;
== '''避免全表扫描''' ==&lt;br /&gt;
当 MySQL 使用全表扫描解析查询时，'''EXPLAIN'''的输出在“type”列中显示“'''ALL'''”【即，使用了“全表扫描”】。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这通常在以下情况下发生：&lt;br /&gt;
# '''表太小'''了，执行表扫描比进行键查找要快。这对于行数少于10行且行长较短的表很常见。&lt;br /&gt;
# 对于索引列，'''“ON”或“WHERE”子句中没有可用的限制'''。&lt;br /&gt;
# 正将索引列与常量值进行比较，MySQL 已经计算出（基于索引树）'''常量覆盖了表的很大一部分，并且表扫描会更快'''。【？？？】&lt;br /&gt;
# 正在通过另一列使用'''基数低的键'''（许多行与键值匹配）。&lt;br /&gt;
#* 在这种情况下，MySQL 假定：通过使用键，它可能会执行许多键查找，而表扫描会更快。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于小型表，表扫描通常是适当的，并且对性能的影响可以忽略不计。对于大型表，请尝试以下技术，以避免优化器错误地选择表扫描：&lt;br /&gt;
# 使用“'''ANALYZE TABLE tbl_name'''”更新扫描表的 key 分布。&lt;br /&gt;
# 对被扫描的表使用“'''FORCE INDEX'''”来告诉 MySQL：与使用给定索引相比，表扫描非常昂贵：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM t1, t2 FORCE INDEX (index_for_column)&lt;br /&gt;
  WHERE t1.col_name=t2.col_name;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 使用“--max-seeks-for-key=1000”选项启动 mysqld，或使用“SET max_seeks_for_key=1000”告诉优化器假定没有键扫描会导致超过 1000 个键查找。&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6635</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6635"/>
		<updated>2023-04-18T10:07:57Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* This 绑定（This Binding） */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
 ''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪 ECMAScript 实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 生成器（Generator） || 此执行上下文正在评估的 Generator 对象。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
关于“this”的理解，参考：[https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/ 《Understanding JavaScript Function Invocation and &amp;quot;this&amp;quot;》]&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 10;&lt;br /&gt;
const b = 20;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(d, e) {&lt;br /&gt;
  var f = 50;&lt;br /&gt;
  return d * e * f * a;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(30, 40);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: 50&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 函数中使用了&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;&amp;lt;abbr title=&amp;quot;跨作用域的变量&amp;quot;&amp;gt;'''自由变量'''&amp;lt;/abbr&amp;gt;&amp;lt;/span&amp;gt;（“a”），将通过其“'''外部词法环境引用'''”（到“GlobalLexicalEnvironment”中）查找&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 600000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
注意：部分文章表述的是旧版本的 ES：&lt;br /&gt;
# [https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0 《Understanding Execution Context and Execution Stack in Javascript》]&lt;br /&gt;
#: [https://juejin.cn/post/7129510217863299102 《ES2018 最新 【译】理解Javascript中的执行上下文和执行栈》] —— 比较完善，列出了 ES 不同版本的变化&lt;br /&gt;
#: [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》] —— 不太准确&lt;br /&gt;
# [https://juejin.cn/post/6844903733495595016 《深入JavaScript系列（一）：词法环境》]&lt;br /&gt;
# [https://juejin.cn/post/7118721446615973896 《JavaScript筑基（三）：环境记录》]&lt;br /&gt;
# [https://limeii.github.io/2019/05/js-lexical-environment/ 《JS：深入理解JavaScript-词法环境》] —— 案例不错&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E5%8F%98%E9%87%8F%E3%80%81%E4%BD%9C%E7%94%A8%E5%9F%9F%E3%80%81%E9%97%AD%E5%8C%85&amp;diff=6634</id>
		<title>变量、作用域、闭包</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E5%8F%98%E9%87%8F%E3%80%81%E4%BD%9C%E7%94%A8%E5%9F%9F%E3%80%81%E9%97%AD%E5%8C%85&amp;diff=6634"/>
		<updated>2023-04-17T23:34:00Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 作用域参考：《【JavaScript】深入理解JS中的词法作用域与作用域链》 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 变量&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Variables&amp;quot;/&amp;gt; ==&lt;br /&gt;
 ECMAScript 6 中引入了 let、const。&lt;br /&gt;
&lt;br /&gt;
JavaScript 有三种声明方式：&lt;br /&gt;
# '''var'''：声明一个'''变量'''，初始化可选。&lt;br /&gt;
# '''let'''：声明一个'''变量'''，初始化可选。&lt;br /&gt;
# '''const'''：声明一个'''常量'''，必须初始化。&lt;br /&gt;
&lt;br /&gt;
 “局部变量”/“全局变量”只与其定义位置有关：在“函数内部”/“函数之外”声明的变量&lt;br /&gt;
&lt;br /&gt;
=== var：变量提升&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Hoisting&amp;quot;/&amp;gt; ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''提升（Hoisting）'''&amp;lt;/big&amp;gt;：变量和函数的'''声明'''会在物理层面（在编译阶段被放入内存中）移动到代码的最前面 —— 变量/函数的“初始化”和“使用”可以在“声明”之前（先使用再声明）。&lt;br /&gt;
 &lt;br /&gt;
 函数和变量相比，会被优先提升 —— 函数会被提升到更靠前的位置。&lt;br /&gt;
&lt;br /&gt;
# '''变量提升'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt;：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
bla = 2&lt;br /&gt;
var bla;&lt;br /&gt;
&lt;br /&gt;
// 可以理解为：&lt;br /&gt;
&lt;br /&gt;
var bla;&lt;br /&gt;
bla = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数提升'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;function&amp;quot;/&amp;gt;：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
hoisted(); // logs &amp;quot;foo&amp;quot;&lt;br /&gt;
function hoisted() {&lt;br /&gt;
    console.log('foo');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 可以理解为：&lt;br /&gt;
&lt;br /&gt;
function hoisted() {&lt;br /&gt;
    console.log('foo');&lt;br /&gt;
}&lt;br /&gt;
hoisted(); // logs &amp;quot;foo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''JavaScript 只会提升声明，不会提升其初始化'''&amp;lt;/span&amp;gt; —— 如果在“声明”和“初始化”之前“使用”，将使用 &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;'''undefined'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// “使用”先于“初始化”&lt;br /&gt;
console.log(num); // Returns undefined&lt;br /&gt;
var num;&lt;br /&gt;
num = 6;&lt;br /&gt;
&lt;br /&gt;
// “初始化”先于“使用”&lt;br /&gt;
num = 6;&lt;br /&gt;
console.log(num); // returns 6&lt;br /&gt;
var num;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''函数表达式（function expressions）不会被提升'''&amp;lt;/span&amp;gt; &lt;br /&gt;
&lt;br /&gt;
: 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
notHoisted(); // TypeError: notHoisted is not a function&lt;br /&gt;
&lt;br /&gt;
var notHoisted = function() {&lt;br /&gt;
    console.log('bar');&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== let：暂时性死区&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;/&amp;gt; ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''暂时性死区（Temporal dead zone，TDZ）'''&amp;lt;/big&amp;gt;：从“代码块的开始”直到“声明变量的行”，'''let''' 或 '''const''' 声明的变量都处于“暂时性死区”中 —— 这并不是“提升”！！！&lt;br /&gt;
&lt;br /&gt;
# 在“暂时性死区”中访问变量将抛出 '''ReferenceError'''：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
{ &lt;br /&gt;
    // TDZ starts at beginning of scope&lt;br /&gt;
    console.log(bar); // undefined&lt;br /&gt;
    console.log(foo); // ReferenceError&lt;br /&gt;
    var bar = 1;&lt;br /&gt;
    let foo = 2; &lt;br /&gt;
    // End of TDZ (for foo)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “暂时性死区”取决于“'''执行顺序'''”（时间），而非“代码顺序”（位置）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    // TDZ starts at beginning of scope&lt;br /&gt;
    const func = () =&amp;gt; console.log(letVar); // OK&lt;br /&gt;
    let letVar = 3; &lt;br /&gt;
    // End of TDZ (for letVar)&lt;br /&gt;
&lt;br /&gt;
    func(); // Called outside TDZ!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== var 与 let 的区别&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;/&amp;gt; ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ var 与 let&lt;br /&gt;
|-&lt;br /&gt;
! \ !! var !! let&lt;br /&gt;
|-&lt;br /&gt;
| '''块作用域''' || &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;✘&amp;lt;/span&amp;gt; || &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''变量提升''' || &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt; || &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;✘&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''重新声明''' &lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var user = &amp;quot;Pete&amp;quot;;&lt;br /&gt;
var user = &amp;quot;John&amp;quot;;&lt;br /&gt;
console.log(user); // John&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;✘&amp;lt;/span&amp;gt;&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let user;&lt;br /&gt;
let user; // SyntaxError: 'user' has already been declared&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 作用域&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Scope&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt;&amp;lt;ref&amp;gt;参考：[https://juejin.cn/post/7069578126979760158 《【JavaScript】深入理解JS中的词法作用域与作用域链》]&amp;lt;/ref&amp;gt; ==&lt;br /&gt;
 &amp;lt;big&amp;gt;'''作用域'''&amp;lt;/big&amp;gt;是当前的执行上下文，值和表达式在其中“可见”或可被访问。&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局作用域&amp;lt;/span&amp;gt;：可被当前'''文档'''中的任何其他代码所访问；&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;函数作用域&amp;lt;/span&amp;gt;：可被当前'''函数'''内部的其他代码所访问；&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''块作用域'''&amp;lt;/span&amp;gt;：可被当前'''块'''（由 '''&amp;lt;code&amp;gt;{ }&amp;lt;/code&amp;gt;''' 包围）内部的其他代码所访问；&lt;br /&gt;
#* 仅 let、const 支持&lt;br /&gt;
&lt;br /&gt;
 ECMAScript 6 之前没有“块作用域”：语句块中声明的变量将成为语句块所在函数（或全局作用域）的局部变量。&lt;br /&gt;
&lt;br /&gt;
=== 作用域链 ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''作用域链'''&amp;lt;/big&amp;gt;：由于作用域的层层嵌套而形成的关系。&lt;br /&gt;
&lt;br /&gt;
作用域链用于变量的查找过程：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = 10&lt;br /&gt;
&lt;br /&gt;
function outer() {&lt;br /&gt;
    var x = 20&lt;br /&gt;
    function inner() {&lt;br /&gt;
        console.log(x)&lt;br /&gt;
    }&lt;br /&gt;
    inner()&lt;br /&gt;
}&lt;br /&gt;
outer() // 20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 以上代码，包括三个作用域：&lt;br /&gt;
:# 全局作用域：包含变量 x（=10）&lt;br /&gt;
:# 函数作用域（outer）：包含变量 x（=20）&lt;br /&gt;
:# 函数作用域（inner）：不包含变量&lt;br /&gt;
: 查找过程：&lt;br /&gt;
:# console.log(x) 将在“函数作用域（inner）”中查找变量“x”：失败&lt;br /&gt;
:# 在“函数作用域（outer）”查找变量“x”：成功（x = 20）&lt;br /&gt;
:# 使用该变量：输出 20&lt;br /&gt;
&lt;br /&gt;
=== 作用域模型：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''词法作用域'''&amp;lt;/span&amp;gt;&amp;lt;ref&amp;gt;参考：[https://www.freecodecamp.org/chinese/news/javascript-lexical-scope-tutorial/ 《JavaScript 中的词法作用域——JS 中的作用域究竟是什么？》]&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
从语言的层面来说，作用域模型分两种：（根据作用域的生成时机）&lt;br /&gt;
# '''静态作用域'''：在'''代码编写时'''完成划分，作用域沿以'''定义位置'''向外延伸&lt;br /&gt;
#* 也称“&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''词法作用域'''&amp;lt;/span&amp;gt;”，是最为普遍的一种作用域模型&lt;br /&gt;
# '''动态作用域'''：在'''代码运行时'''完成划分，作用域链以'''调用栈'''向外延伸&lt;br /&gt;
#* 由 bash、Perl 等语言所使用&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''词法作用域（Lexical Scope）'''&amp;lt;/span&amp;gt;：即“词法分析时生成的作用域”，'''根据源代码中“声明变量的位置”来确定该变量在何处可用'''&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let x = &amp;quot;Eijux&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
function getX() {&lt;br /&gt;
  return x;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
console.log(getX()) // Eijux&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 变量 x 的“词法作用域”为“全局作用域”（定义时的作用域）而非“getX 函数作用域”&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 一个声明（定义变量、函数等）的“词法作用域”就是其“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''定义时的作用域'''&amp;lt;/span&amp;gt;” —— 注意：&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;'''并不是“调用时的作用域”'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = 0&lt;br /&gt;
&lt;br /&gt;
function foo() {&lt;br /&gt;
    var x = 1&lt;br /&gt;
    bar()&lt;br /&gt;
}&lt;br /&gt;
function bar() {&lt;br /&gt;
    console.log(x) // 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
foo()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 由于“词法作用域”（定义时的作用域）决定了：foo、bar 的上级作用域是“全局作用域”，所以 bar 中使用的 x 来自“全局作用域”而非“foo 函数作用域”&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 欺骗“词法作用域” ====&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
虽然“词法作用域”在代码编写时就确定，但仍然可以修改：&lt;br /&gt;
# '''eval()'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;eval&amp;quot;/&amp;gt;：将传入的字符串当做 JavaScript 代码进行执行&lt;br /&gt;
#*有性能和安全隐患，'''不建议使用'''&lt;br /&gt;
# '''with'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;with&amp;quot;/&amp;gt;：扩展一个语句的作用域链&lt;br /&gt;
#* 有语义不明和兼容问题，'''已弃用'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# 通过 eval() 修改词法作用域：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var num = 10&lt;br /&gt;
var str = &amp;quot;var num = 20&amp;quot;&lt;br /&gt;
&lt;br /&gt;
function fn(str) {&lt;br /&gt;
    eval(str)&lt;br /&gt;
    console.log(num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn(str)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 通过 with 修改词法作用域：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = { a: 1 }&lt;br /&gt;
&lt;br /&gt;
function fn(obj) {&lt;br /&gt;
    with (obj) {&lt;br /&gt;
        a = 2&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
console.log(x.a) // 1&lt;br /&gt;
fn(x)&lt;br /&gt;
console.log(x.a) // 2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 闭包&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;closure&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;closure&amp;quot;/&amp;gt; ==&lt;br /&gt;
 &amp;lt;big&amp;gt;'''闭包（closure）'''&amp;lt;/big&amp;gt;：'''函数'''以及其捆绑的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''词法环境（lexical environment）'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt;的组合&lt;br /&gt;
 &lt;br /&gt;
 —— “词法环境”包含了这个闭包创建时作用域内的任何局部变量&lt;br /&gt;
&lt;br /&gt;
'''在 JavaScript 中，闭包会随着函数的创建而被同时创建。'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
function makeAdder(x) {&lt;br /&gt;
    // 返回一个函数&lt;br /&gt;
    return function (y) {&lt;br /&gt;
        return x + y&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var add5 = makeAdder(5) // 闭包&lt;br /&gt;
var add10 = makeAdder(10) // 闭包&lt;br /&gt;
&lt;br /&gt;
console.log(add5(2));  // 7&lt;br /&gt;
console.log(add10(2)); // 12&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 以上代码包含两个闭包 add5、add10，二者：&lt;br /&gt;
:# 共享相同的“函数定义”：makeAdder&lt;br /&gt;
:# 保存不同的“词法环境”：add5 中 x 为 5，add10 中 x 为 10&lt;br /&gt;
&lt;br /&gt;
 简单来说，闭包让开发者可以从内部函数访问外部函数的作用域&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''一个有意思的例子'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;TypeScript&amp;quot; name=&amp;quot;variable&amp;quot;/&amp;gt; ===&lt;br /&gt;
 一个涉及到“'''Event Loop'''”、“'''var 作用域'''”、“'''闭包'''”（“'''词法环境'''”）的例子。&lt;br /&gt;
&lt;br /&gt;
对于以下代码：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(function() { console.log(i) }, 100 * i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 其输出如何 ❓&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; | 是否预期输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
0&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
...&lt;br /&gt;
9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; | 但，实际输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
10&lt;br /&gt;
10&lt;br /&gt;
10&lt;br /&gt;
...&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
原因分析：&lt;br /&gt;
# 【var 作用域】：var 变量的作用域在 for 外部 —— 每次循环使用的都是同一个 &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt;&lt;br /&gt;
#* var 变量是没有“块作用域”的 ！！！&lt;br /&gt;
# 【闭包】：for 循环将会创建 10 个闭包，它们：&lt;br /&gt;
#: 共享相同的“函数定义”：&amp;lt;code&amp;gt; function() { console.log(i) } &amp;lt;/code&amp;gt;&lt;br /&gt;
#: 共享相同的“词法环境”（“变量环境”），'''其“环境记录器”将使用同一个 var 变量''' —— &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt;&lt;br /&gt;
# 【Event Loop】：setTimeout 是一个任务，将在 for 所有循环完成之后执行 —— 而 &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt; 在所有循环之后其值为 10&lt;br /&gt;
综上：各个闭包将在 for 所有循环完成之后，使用同一个 &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt; 值（10）来执行函数。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 解决问题有多种方式： 总之，&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''使闭包不再使用相同的词法环境'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt; 即可&lt;br /&gt;
 &lt;br /&gt;
 '''思路一： 若“函数”执行依赖于“外部变量”，则使“词法环境”的“外部环境引用”不同'''&lt;br /&gt;
 &lt;br /&gt;
 '''思路二： 若“函数”执行依赖于“内部变量 / 参数”，则使“词法环境”的“环境记录”不同'''&lt;br /&gt;
&lt;br /&gt;
'''思路一'''：函数的执行依赖于“外部变量”，则“使用 '''let''' / '''const'''（块作用域）”保证每次迭代的“词法环境”的“外部环境引用”不同&lt;br /&gt;
# '''使用 let 替换 var'''：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (let i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(function() { console.log(i) }, 100 * i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''使用 let/const 捕获 var'''：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    let v = i&lt;br /&gt;
    setTimeout(function() { console.log(v) }, 100 * v)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''思路二'''：若“函数”执行依赖于“参数”，则“使用参数捕获外部变量”保证每次迭代的“词法环境”的“环境记录”不同&lt;br /&gt;
# 通过“'''立即执行的函数表达式（IIFE）'''”&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;IIFE&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt;： —— 【将产生不必要的闭包（嵌套闭包）】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    (function(v) {&lt;br /&gt;
        setTimeout(function() { console.log(v) }, 100 * v)&lt;br /&gt;
    })(i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 通过“'''向函数传递变量作为参数'''”： —— 【没有不必要的闭包】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(function(v) { console.log(v) }, 100 * i, i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 等同于：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
function fn(v) {&lt;br /&gt;
    console.log(v)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(fn, 100 * i, i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
&lt;br /&gt;
=== '''var 没有“块作用域”'''&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt; ===&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''var 变量没有“块作用域”'''：将会使用（块所在的）“函数作用域”或“全局作用域”&amp;lt;/span&amp;gt; —— 这是因为在早期的 JavaScript 中，块没有&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;'''词法环境'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''var 将透传 if、for 和其它代码块'''&lt;br /&gt;
&lt;br /&gt;
示例一：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
if (true) {&lt;br /&gt;
    var x = 5;&lt;br /&gt;
}&lt;br /&gt;
console.log(x); // 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (true) {&lt;br /&gt;
    let y = 5;&lt;br /&gt;
}&lt;br /&gt;
console.log(y); // ReferenceError: y is not defined&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
示例二：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
function f() {&lt;br /&gt;
    console.log(tmp);&lt;br /&gt;
    if (false) {&lt;br /&gt;
        var tmp = 'hello world';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
f(); // undefined&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 由于变量提升：即使 var 定义的代码块永远不会执行，变量也存在，但初始化不会执行&lt;br /&gt;
&lt;br /&gt;
=== let 会不会“提升”？ ===&lt;br /&gt;
 关于这一点，MDN 都描述得前后不一致，也是很操蛋了……&lt;br /&gt;
 &lt;br /&gt;
 1、MDN：《语法和数据类型》&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Variables&amp;quot;/&amp;gt;：&lt;br /&gt;
     在 ECMAScript 6 中，let和const同样会被提升变量到代码块的顶部但是不会被赋予初始值。在变量声明之前引用这个变量，将抛出引用错误（ReferenceError）。这个变量将从代码块一开始的时候就处在一个“暂时性死区”，直到这个变量被声明为止。&lt;br /&gt;
 &lt;br /&gt;
 2、MDN：《语法和数据类型》&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;/&amp;gt;：&lt;br /&gt;
     var 和 let 的另一个重要区别，let 声明的变量不会在作用域中被提升，它是在编译时才初始化（参考下面的暂时性死区）。&lt;br /&gt;
&lt;br /&gt;
两种说法，以一个类似示例来说明：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var foo = 33;&lt;br /&gt;
if (foo) {&lt;br /&gt;
    console.log(foo) // ReferenceError: Cannot access 'foo' before initialization&lt;br /&gt;
    let foo = 44;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
对于 ReferenceError 该如何解释呢 ❓ &lt;br /&gt;
# 说法一：由于 let 变量提升，导致此处使用“块作用域内定义变量”，但该变量处于“暂时性死区”，所以出现此错误。&lt;br /&gt;
#: 网上有内容更是强行将 let 变量创建分为三个过程：创建、初始化、赋值 …… 有点扯。&lt;br /&gt;
# 说法二：由于'''词法作用域'''，导致此处使用“块作用域内定义变量”，但该变量处于“暂时性死区”，所以出现此错误。&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt; 个人理解：let 并不会提升，以上示例是“词法作用域”影响。—— 或许看看 JS 引擎执行过程更清楚&lt;br /&gt;
&lt;br /&gt;
=== 什么是“隐式声明的全局变量”？ ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''隐式声明的全局变量'''&amp;lt;/big&amp;gt;：直接对一个未声明的变量赋值，无论在函数内外都会将其“隐式地”声明为一个“全局变量”&lt;br /&gt;
&lt;br /&gt;
示例，以下变量全都是“隐式声明的全局变量”：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
x = '?'&lt;br /&gt;
&lt;br /&gt;
function fn() {&lt;br /&gt;
    x = 'hello'&lt;br /&gt;
    y = 'bye'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn()&lt;br /&gt;
console.log(x, y) // hello bye&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 严格模式下，“对一个未声明的变量赋值”将抛出 ReferenceError&lt;br /&gt;
# 非严格模式：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = 0;&lt;br /&gt;
function f() {&lt;br /&gt;
    var x = y = 1;&lt;br /&gt;
}&lt;br /&gt;
f();&lt;br /&gt;
&lt;br /&gt;
console.log(x, y); // 0 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 严格模式：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
var x = 0;&lt;br /&gt;
function f() {&lt;br /&gt;
    var x = y = 1; // ReferenceError: y is not defined&lt;br /&gt;
}&lt;br /&gt;
f();&lt;br /&gt;
&lt;br /&gt;
console.log(x, y);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== Wikioe ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;Wikioe&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;&amp;gt;参考：【'''[[JS 执行过程：执行上下文、词法环境]]'''】&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MDN ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;MDN&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Variables&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_Types MDN：《语法和数据类型》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Hoisting&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Glossary/Hoisting MDN：《Hoisting（变量提升）》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;function&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function MDN：《function》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;var&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var MDN：《var》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let MDN：《let》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Scope&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Glossary/Scope MDN：《Scope（作用域）》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;eval&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval MDN：《eval()》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;with&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/with MDN：《with》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;closure&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures MDN：《闭包》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;IIFE&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Glossary/IIFE MDN：《IIFE（立即调用函数表达式）》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
=== javascript.info ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;javascript.info&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;var&amp;quot;&amp;gt;参考：[https://zh.javascript.info/var javascript.info：《老旧的 &amp;quot;var&amp;quot;》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;closure&amp;quot;&amp;gt;参考：[https://zh.javascript.info/closure javascript.info：《变量作用域，闭包》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
=== TypeScript ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;TypeScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;TypeScript&amp;quot; name=&amp;quot;variable&amp;quot;&amp;gt;参考：[https://www.tslang.cn/docs/handbook/variable-declarations.html TypeScript：《变量声明》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
=== 其他 ===&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6633</id>
		<title>Event Loop：事件循环</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6633"/>
		<updated>2023-04-17T23:31:27Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/*  一个有意思的例子 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 在 MDN 上看到 JavaScript 的[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop 《并发模型与事件循环》]，但由于该页面内容过少，实在不变学习。&lt;br /&gt;
 &lt;br /&gt;
 而网络上搜到的内容大同小异，互相又有不小出入，难以拿捏。&lt;br /&gt;
 &lt;br /&gt;
 众所周知，JavaScript 是没有所谓源代码的“源代码”，所以这部分内容只能在“规范文件”中寻找了。&lt;br /&gt;
&lt;br /&gt;
* 以下内容参考《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;&amp;gt;参考：[https://html.spec.whatwg.org/multipage/webappapis.html#event-loops 《HTML Standard》：“Event loops”]&amp;lt;/ref&amp;gt;、MDN&amp;lt;ref name=&amp;quot;MDN&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&amp;lt;/ref&amp;gt;、与网络内容整理。&lt;br /&gt;
&lt;br /&gt;
== 前置知识 ==&lt;br /&gt;
 见：&amp;lt;big&amp;gt;'''[[浏览器基础：进程与线程]]'''&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 “一个 Tab 页面对应一个'''渲染进程'''”，而“渲染进程中只能存在一个 '''JS 引擎线程'''”（即，'''主线程'''），即：页面中的所有 JS 都由同一单线程运行。&lt;br /&gt;
&lt;br /&gt;
？？？？？？由于“渲染进程”负责了页面几乎所有的任务（事件、交互、脚本、渲染、网络），所以如何协调各个任务的执行是关键问题。&lt;br /&gt;
&lt;br /&gt;
[[File:浏览器的进程与线程.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“任务” ===&lt;br /&gt;
 JavaScript中，“任务”被分为两种：“同步任务”，“异步任务”。“异步任务”（Task）：又分为“宏任务”（MacroTask）与“微任务”（MicroTask）。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 是针对“异步任务”而言。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ——【'''P.S. 《HTML Standard》中已经不再有“宏任务”（MacroTask）这一说法 —— 它就是“任务”（task）'''】&lt;br /&gt;
&lt;br /&gt;
# 同步任务：在“主线程”上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务。&lt;br /&gt;
# 异步任务：不直接进入“主线程”，而进入“任务队列”（task queue）的任务。&lt;br /&gt;
## '''任务（task）'''：事件、解析、回调、使用资源、对 DOM 操作做出反应 ——【根据《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt;中定义】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''script(整体代码)、setTimeout、setInterval、setImmediate（node独有）、requestAnimationFrame(浏览器独有)、I/O、UI rendering'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，只有“已经处于 task queues 中”的任务才会被执行'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 setTimeout 引起的无限循环，会导致性能下降，但是很难导致直接崩溃】&lt;br /&gt;
## '''微任务（microtask）'''：——【暂无明确定义，见：[[#到底什么是“Microtasks”？]]】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''Promises 的回调、queueMicrotask()、process.nextTick（node独有）、Object.observe(废弃)、MutationObserver'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，“microtask queue 中的所有”任务会被执行（哪怕是中途添加的“microtask”），直到队列为空'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 Promises 引起无限循环，将直接导致崩溃。这也是为什么要求'''代码慎用“queueMicrotask()”'''】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;一点小小的猜测：&lt;br /&gt;
 &lt;br /&gt;
     来源于“渲染进程”中其他线程（非“JS 引擎线程”）引起的异步任务，即“任务（task）”。&lt;br /&gt;
     &lt;br /&gt;
     来源于“渲染进程”的“JS 引擎线程”引起的异步任务，即“微任务（microtask）”。&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“运行时”&amp;lt;ref&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
To run JavaScript code, the runtime engine maintains a set of agents in which to execute JavaScript code. Each agent is made up of a set of execution contexts, the execution context stack, a main thread, a set for any additional threads that may be created to handle workers, a task queue, and a microtask queue. Other than the main thread—which some browsers share across multiple agents—each component of an agent is unique to that agent.&lt;br /&gt;
&lt;br /&gt;
在执行 JavaScript 代码的时候，JavaScript 运行时实际上维护了一组用于执行 JavaScript 代码的代理。每个代理由一组执行上下文的集合、执行上下文栈、主线程、一组可能创建用于执行 worker 的额外的线程集合、一个任务队列以及一个微任务队列构成。除了主线程（某些浏览器在多个代理之间共享的主线程）之外，其他组成部分对该代理都是唯一的。 &lt;br /&gt;
&lt;br /&gt;
——MDN：《深入：微任务与 Javascript 运行时环境》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
An agent comprises a set of ECMAScript execution contexts, an execution context stack, a running execution context, an Agent Record, and an executing thread. Except for the executing thread, the constituents of an agent belong exclusively to that agent.&lt;br /&gt;
&lt;br /&gt;
“代理”（Agent）包括：一组ECMAScript执行上下文、执行上下文堆栈、运行的执行上下文、代理记录和执行线程。除了执行线程之外，代理的组成部分只属于该代理。 &lt;br /&gt;
&lt;br /&gt;
——《ECMAScript® 2023 Language Specification》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Conceptually, the agent concept is an architecture-independent, idealized &amp;quot;thread&amp;quot; in which JavaScript code runs. Such code can involve multiple globals/realms that can synchronously access each other, and thus needs to run in a single execution thread.&lt;br /&gt;
&lt;br /&gt;
从概念上讲，代理概念是一个独立于体系结构、理想化的“线程”，JavaScript代码在其中运行。这样的代码可能涉及多个全局/领域，这些全局/领域可以同步访问彼此，因此需要在单个执行线程中运行。&lt;br /&gt;
&lt;br /&gt;
——《HTML Standard》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://tc39.es/ecma262/#sec-agents 《ECMAScript® 2023 Language Specification》：“Agents”]&lt;br /&gt;
::# [https://html.spec.whatwg.org/multipage/webappapis.html#agents-and-agent-clusters 《HTML Standard》：“Agents and agent clusters”]&lt;br /&gt;
::# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&lt;br /&gt;
::# [https://github.com/Lawliet01/everyone-can-read-spec/blob/main/8.execution-environment.md 《【人人都能读标准】8.可视化JavaScript的运行环境：agents、执行上下文、Realm》]&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
 从概念上讲，&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''代理（Agent）'''&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt; 是一个独立于体系结构、理想化的“线程”，每个 ECMAScript 程序都必须在其中运行。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''代理是一种规范机制，不需要与任何特定的 ECMAScript 实现部件相对应。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agent 包括了：&lt;br /&gt;
# '''一组执行上下文（a set of execution contexts）&amp;lt;ref name=&amp;quot;execution_context&amp;quot;&amp;gt;参考：【'''[[JS 执行过程：执行上下文、词法环境]]'''】&amp;lt;/ref&amp;gt;'''：即，一组可执行、待执行的上下文&lt;br /&gt;
# '''执行上下文栈（the execution context stack）'''&amp;lt;ref name=&amp;quot;execution_context&amp;quot;/&amp;gt;：在一些文章中叫做“'''调用栈（call stack）'''”&lt;br /&gt;
#* 栈顶的那个上下文被称为“运行中的执行上下文（running execution context）”&lt;br /&gt;
# '''执行线程（an executing thread）'''：在一些文章中叫做“'''主线程（a main thread）'''”&lt;br /&gt;
# '''事件循环（event loop）'''：&lt;br /&gt;
#* 它包括了：一个“微任务队列（microtask queue）”，一个/多个“任务队列（task queue）”&lt;br /&gt;
# '''代理记录（Agent Record）'''：？？？&lt;br /&gt;
&lt;br /&gt;
* 一个宿主（浏览器、Node.js）可以有多个 Agent，Agent 之间相互隔离，可以通过发送消息进行通信。&lt;br /&gt;
* 当两个 Agent 同处一个“Agent Clusters”（代理集群）时，它们可以共享内存。&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''除了“执行线程”（主线程）、“事件循环”之外，代理的组成部分只属于该代理。'''&amp;lt;/span&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
     “执行线程”（主线程）：某些浏览器在多个代理之间共享主线程&lt;br /&gt;
     &lt;br /&gt;
     “事件循环”：可以在单个线程中协同调度多个窗口事件循环 —— 见：[[#Event Loop]]&lt;br /&gt;
 &lt;br /&gt;
 ——【《ECMAScript® 2023 Language Specification》、MDN 只提到：“执行线程”并不一定由“Agent”独占。但从《HTML Standard》对“Event Loop”的表述来看，似乎也并不一定由“Agent”独占】&lt;br /&gt;
 &lt;br /&gt;
 ——【尽管标准提到，不同的“Agent”允许共享同一条“执行线程”，但&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''现代浏览器基本上都是给每个“Agent”启用一条独立的“执行线程”'''&amp;lt;/span&amp;gt;。】&lt;br /&gt;
&lt;br /&gt;
Web 平台上存在以下类型的代理：&lt;br /&gt;
# '''Similar-origin window agent'''：即“同源窗口代理”，包含各种窗口对象，这些对象可以直接或通过使用 '''document.domain''' 相互访问。&lt;br /&gt;
#* &lt;br /&gt;
#* 两个“同源”的窗口对象可以位于不同的“Similar-origin window agent”中，例如，如果它们各自位于自己的浏览上下文组中。&lt;br /&gt;
# '''Dedicated worker agent'''：包含了一个 DedicatedWorkerGlobalScope；&lt;br /&gt;
# '''Shared worker agent'''：包含了一个 SharedWorkerGlobalScope；&lt;br /&gt;
# '''Service worker agent'''：包含了一个 ServiceWorkerGlobalScope；&lt;br /&gt;
# '''Worklet agent'''：包含了一个 WorkletGlobalScope 对象；&lt;br /&gt;
&lt;br /&gt;
== Event Loop&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt; ==&lt;br /&gt;
 要协调事件（event），用户交互（user interaction），脚本（script），渲染（rendering），网络（networking）等，用户代理必须使用本节中描述的事件循环。&lt;br /&gt;
&lt;br /&gt;
每个'''“代理”（Agent）'''有一个关联的“事件循环”，且该循环对该代理是'''唯一'''的。&lt;br /&gt;
# '''Similar-origin window agent''' 的事件循环称为“'''窗口事件循环'''”（'''window event loop'''）。&lt;br /&gt;
# '''Dedicated worker agent'''、'''Shared worker agent''' 或 '''Service worker agent''' 的事件循环称为“'''工作事件循环'''”（'''worker event loop'''）。&lt;br /&gt;
# '''Worklet agent''' 的事件循环称为“'''工件事件循环'''”（'''worklet event loop'''）。&lt;br /&gt;
&lt;br /&gt;
 Event loops do not necessarily correspond to implementation threads. For example, multiple window event loops could be cooperatively scheduled in a single thread.&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''事件循环不一定对应于“实现线程”（注：implementation threads，即“浏览器线程”）。例如，可以在单个线程中协同调度多个窗口事件循环。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 However, for the various worker agents that are allocated with &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; set to true, the JavaScript specification does place requirements on them regarding forward progress, which effectively amount to requiring dedicated per-agent threads in those cases.&lt;br /&gt;
 然而，对于 &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; 设置为 true 的各种 worker agents，JavaScript 规范确实对它们提出了关于“forward progress？”的要求，在这些情况下，这实际上相当于需要专用的每个代理线程。&lt;br /&gt;
&lt;br /&gt;
* 一个事件循环具有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个或多个“任务队列”（task queues）'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
** &amp;lt;q&amp;gt;'''任务队列是“集合”（set），而不是“队列”（queue）'''，因为事件循环处理模型从所选队列中获取第一个可运行的任务，而不是将第一个任务出列。&amp;lt;/q&amp;gt;&lt;br /&gt;
** &amp;lt;q&amp;gt;'''微任务队列（microtask queue）不是任务队列（task queues）'''。&amp;lt;/q&amp;gt;&lt;br /&gt;
* 每个事件循环都有一个当前“正在运行的任务”（currently running task），要么是一个任务，要么是 null。初始为空。&lt;br /&gt;
** 它用于处理可重入性。&lt;br /&gt;
* 每个事件循环都有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个“微任务队列”（microtask queue）'''&amp;lt;/span&amp;gt;，该队列是一个初始为空的微任务队列。&lt;br /&gt;
* 每个事件循环都有一个“正在执行微任务的检查点”（performing a microtask checkpoint）的布尔值。该值最初为 false。&lt;br /&gt;
** 它用于防止重入调用。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上次渲染机会时间”（last render opportunity time），最初设置为零。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上一个空闲周期的开始时间”（last idle period start time），最初设置为零。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 任务（Tasks） ===&lt;br /&gt;
“任务”（Tasks）包括以下几种：&lt;br /&gt;
# '''事件'''（Events）：在特定 EventTarget 对象上调度 Event 对象，通常由专用的任务完成。&lt;br /&gt;
# '''解析'''（Parsing）：HTML 解析器标记一个或多个字节，然后处理任何生成的标记，通常是一项任务。&lt;br /&gt;
# '''回调'''（Callbacks）：调用回调通常由一个专用的任务完成。&lt;br /&gt;
# '''使用资源'''（Using a resource）：当算法获取资源时，如果获取是以非阻塞的方式发生的，那么一旦部分或全部资源可用，就由任务执行对资源的处理。&lt;br /&gt;
# '''对 DOM 操作做出反应'''（Reacting to DOM manipulation）：一些元素具有响应 DOM 操作而触发的任务，例如：当该元素被插入到文档中时。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
从形式上讲，“任务”（Tasks）具有以下结构：&lt;br /&gt;
# 步骤（steps）：指定任务要完成的工作的一系列步骤。&lt;br /&gt;
# '''来源'''（source）：用于对相关任务进行分组和序列化。&lt;br /&gt;
# 文档（document）与任务关联的文档，对于不在“窗口事件循环”中的任务则为 null。&lt;br /&gt;
# 脚本评估环境设置对象集（A script evaluation environment settings object set）：用于跟踪任务期间的脚本评估。&lt;br /&gt;
根据其源字段（source），每个任务都被定义为来自特定的“任务源”（task source）。对于每个事件循环，每个“任务源”都必须与特定的“任务队列”相关联。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 通用任务源（task sources） ===&lt;br /&gt;
# '''DOM 操作任务源'''（The DOM manipulation task source）：用于对 DOM 操作做出反应的功能，例如在将元素插入文档时以非阻塞方式发生的事情。&lt;br /&gt;
# '''用户交互任务源'''（The user interaction task source）：用于对用户交互做出反应的功能，例如键盘或鼠标输入。&lt;br /&gt;
# '''网络任务源'''（The networking task source）：用于响应网络活动而触发的功能。&lt;br /&gt;
# '''导航和遍历任务源'''（The navigation and traversal task source）：用于对导航和历史遍历中涉及的任务进行排队。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''处理模型''' ===&lt;br /&gt;
只要事件循环存在，它就必须持续运行以下步骤：&lt;br /&gt;
# 让 oldestTask 和 taskStartTime 为 null。&lt;br /&gt;
# 如果事件循环有一个'''任务队列'''其中至少有一个可运行的任务，则：&lt;br /&gt;
## 由“实现”（浏览器）定义的规则，选择一个任务队列作为 taskQueue。（“微任务队列”并不是一个“任务队列”，所以不会被选择）——【“选择哪个任务队列”：由浏览器定义（即文档中的“implementation-defined”，客户端软件本身被称为一种“implementation”）决定，这就允许优先选择对性能敏感的任务】&lt;br /&gt;
## 将 taskStartTime 设置为“不安全的共享当前时间”。&lt;br /&gt;
## 将 oldestTask 设置为 taskQueue 中的'''第一个可运行任务'''，并将其从 taskQueue 中删除。——【任务队列是“set”，所以并非“出队”】&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置为 oldestTask。&lt;br /&gt;
## 执行 oldestTask 的步骤（Steps）。&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置回 null。&lt;br /&gt;
# '''执行微任务检查点'''：&lt;br /&gt;
## 如果事件循环的“正在执行微任务的检查点”为 true，则返回。——【检查重入】&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为 true。——【防止重入】&lt;br /&gt;
## 当事件循环的“微任务队列”不为空时：——【！！！'''不为空将一直重复执行'''！！！】&lt;br /&gt;
### 从事件循环的“微任务队列”中“出队”一个任务作为 oldestMicrotask。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置为 oldestMicrotask。&lt;br /&gt;
### 执行 oldestMicrotask。&lt;br /&gt;
###* 这可能涉及调用脚本的回调，并最终调用“clean up after running script”步骤，而该步骤的最后一步又将调用'''执行微任务检查点'''。这就是为什么设置“正在执行微任务的检查点”来防止“'''重入'''”。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置回null。&lt;br /&gt;
## 对于负责的事件循环为该事件循环的每个“环境设置对象”，通知该“环境设置对象”上 rejected 的 promise。&lt;br /&gt;
## 清理索引数据库事务。&lt;br /&gt;
## 执行 ClearKeptObjects()。&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为false。&lt;br /&gt;
# 将 hasARenderingOpportunity 设置为 false。&lt;br /&gt;
# 将现在时刻设置为“不安全的共享当前时间”。&lt;br /&gt;
# 如果 oldestTask 不为 null，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# '''更新渲染'''：如果这是一个窗口事件循环，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# ……（省略）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 总结 ===&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;&lt;br /&gt;
 当“调用栈”为空时（即，同步代码执行完毕时），“主线程”才会开始处理“（由 Event Loop 循环选取的）来自任务队列中的任务”。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 一次循环的顺序为：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务队列的“第一个可运行任务”（宏任务） -&amp;gt; 微任务队列的所有任务（微任务） -&amp;gt; 渲染'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 对于说法：“微任务 -&amp;gt; 渲染 -&amp;gt; 宏任务”，从代码运行结果来看似乎没问题，其实忽略了一点“'''script 脚本本身也是一个任务（宏任务）'''”。&lt;br /&gt;
&lt;br /&gt;
== 关于：Microtasks ==&lt;br /&gt;
&lt;br /&gt;
=== 到底什么是“Microtasks”？ ===&lt;br /&gt;
 无论是《ECMAScript® 2023 Language Specification》、《HTML Standard》、MDN，都没有找到关于“宏任务”、“微任务”的定义性描述。&lt;br /&gt;
 &lt;br /&gt;
 ——《ECMAScript® 2023 Language Specification》：压根就没提到 Microtasks 这个字&lt;br /&gt;
 &lt;br /&gt;
 ——《HTML Standard》：提到了 Microtask queuing：&lt;br /&gt;
     A microtask is a colloquial way of referring to a task that was created via the queue a microtask algorithm.&lt;br /&gt;
     微任务是一种口语化的方式，指的是通过“排队微任务算法”创建的任务。 ——【但文档中，与“任务”相比似乎只有“任务源”（task source）不同】&lt;br /&gt;
 &lt;br /&gt;
 —— MDN：只提到了“任务”（Tasks）与“微任务”（Microtasks）的区别&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 此外，在 Jake Archibald 的文章&amp;lt;ref&amp;gt;参考：[https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ 《Tasks, microtasks, queues and schedules》——Jake Archibald]&amp;lt;/ref&amp;gt;中提到：&lt;br /&gt;
     ECMAScript has the concept of &amp;quot;jobs&amp;quot; which are similar to microtasks, but the relationship isn't explicit aside from vague mailing list discussions. However, the general consensus is that promises should be part of the microtask queue, and for good reason.&lt;br /&gt;
     ECMAScript有类似于 microtasks 的“jobs”概念，但除了模糊的邮件列表讨论之外，这种关系并不明确。然而，普遍的共识是，promises 应该是 microtask queue 的一部分，这是有充分理由的。&lt;br /&gt;
     ……&lt;br /&gt;
     As mentioned, in ECMAScript land, they call microtasks &amp;quot;jobs&amp;quot;. In step 8.a of PerformPromiseThen, EnqueueJob is called to queue a microtask.&lt;br /&gt;
     如前所述，在 ECMAScript 领域，他们将微任务称为“jobs”。在 PerformPromiseThen 的步骤 8.a 中，调用 EnqueueJob 对 microtask 进行排队。&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 再此外，javascript.info 中有提到：&lt;br /&gt;
     Microtasks come solely from our code. They are usually created by promises……&amp;lt;ref&amp;gt;参考：[https://javascript.info/event-loop javascript.info：《Event loop: microtasks and macrotasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     微任务仅来自于我们的代码。它们通常是由 promise 创建的……&lt;br /&gt;
     &lt;br /&gt;
     Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue PromiseJobs, more often referred to as the “microtask queue” (V8 term).&amp;lt;ref&amp;gt;参考：[https://javascript.info/microtask-queue javascript.info：《Microtasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     异步任务需要适当的管理。为此，ECMA 标准规定了一个内部队列 PromiseJobs，通常被称为“微任务队列（microtask queue）”（V8 术语）。&lt;br /&gt;
&lt;br /&gt;
所以，Promise 异步任务（注意，仅仅是它的回调，而不是它本身）是 microtask 应该是“潜规则”了，此外，我们还可以使用“'''queueMicrotask()'''”方法来添加 microtask。&lt;br /&gt;
: ——【P.S. 对于 Node.js 并不清楚】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 为什么要支持“Microtasks”？&amp;lt;ref name=&amp;quot;MDN&amp;quot;/&amp;gt; ===&lt;br /&gt;
 微任务是另一种解决该问题的方案，通过将代码安排在下一次事件循环开始之前运行而不是必须要等到下一次开始之后才执行，这样可以&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''提供一个更好的访问级别'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 如何使用“Microtasks”？&amp;lt;ref&amp;gt;参考：&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide MDN：《在 JavaScript 中通过 queueMicrotask() 使用微任务》]&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/queueMicrotask MDN：《queueMicrotask()》]&lt;br /&gt;
# [https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing 《HTML Standard》：“Microtask queuing”]&lt;br /&gt;
&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
 '''Window''' 或 '''Worker''' 接口的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''queueMicrotask()'''&amp;lt;/span&amp;gt; 方法，将微任务加入队列以在控制返回浏览器的事件循环之前的安全时间执行。&lt;br /&gt;
&lt;br /&gt;
'''语法：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;queueMicrotask(() =&amp;gt; {/* ... */});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let callback = () =&amp;gt; log(&amp;quot;Regular timeout callback has run&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let urgentCallback = () =&amp;gt; log(&amp;quot;*** Oh noes! An urgent callback has run!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
log(&amp;quot;Main program started&amp;quot;);&lt;br /&gt;
setTimeout(callback, 0);&lt;br /&gt;
queueMicrotask(urgentCallback);&lt;br /&gt;
log(&amp;quot;Main program exiting&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Main program started&lt;br /&gt;
Main program exiting&lt;br /&gt;
*** Oh noes! An urgent callback has run!&lt;br /&gt;
Regular timeout callback has run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 关于 Node.js 中的 Event Loop，暂不了解，有时间再看看其他文章。&lt;br /&gt;
 &lt;br /&gt;
 参考：[https://juejin.cn/post/6844903764202094606 一次弄懂Event Loop（彻底解决此类面试问题）]&lt;br /&gt;
&lt;br /&gt;
 P.S.&lt;br /&gt;
 JavaScript 是没有一个 WebAPIs 结构的，网上文章图片展示的 WebAPIs 大概是指那些任务来自于 WebAPI，但是这种描述并不准确。&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''[[变量、作用域、闭包#一个有意思的例子 | 一个有意思的例子]]'''&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
== 写在后面 ==&lt;br /&gt;
 通过查询 EventLoop 的资料，前后沟通了许多内容，浅浅地做个梳理，以及一点点未解。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 首先，EventLoop 的资料集中在《HTML Standard》，而《ECMAScript® 2023 Language Specification》中并无只言片语，说明：'''EventLoop 并非 ECMAScript 语言的特性，而是 Web 相关规范'''。  ——【&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''即，EventLoop 并不由“JS 引擎”提供，而是依靠浏览器实现'''&amp;lt;/span&amp;gt; 】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 其次，Event Loop 提到了 ECMAScript 中的 Agent 概念：&lt;br /&gt;
 1、每个 Agent 都有且仅有一个关联的 Event Loop&lt;br /&gt;
 2、EventLoop 选取任务是交由 Agent 的“执行线程”（或者说：主线程）来执行&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 那么，问题来了&amp;lt;big&amp;gt;❓&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 1、Agent 与 浏览器的“渲染进程”是否有重叠呢？ —— 虽然《HTML Standard》描述 Agent 是一个“idealized &amp;quot;thread&amp;quot;”&lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 2、Agent 的“执行线程”是不是就是“渲染进程”的“JS 引擎线程”呢？ &lt;br /&gt;
     ——【我个人理解就是一个玩意儿（还有[https://developer.mozilla.org/zh-CN/docs/Glossary/Main_thread 《MDN：“主线程”》]），虽然概念不同】&lt;br /&gt;
 &lt;br /&gt;
 3、EventLoop 是由“渲染进程”中的某个线程实现吗？ &lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 网上并没有找到 Agent 相关的文章……&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E5%8F%98%E9%87%8F%E3%80%81%E4%BD%9C%E7%94%A8%E5%9F%9F%E3%80%81%E9%97%AD%E5%8C%85&amp;diff=6632</id>
		<title>变量、作用域、闭包</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E5%8F%98%E9%87%8F%E3%80%81%E4%BD%9C%E7%94%A8%E5%9F%9F%E3%80%81%E9%97%AD%E5%8C%85&amp;diff=6632"/>
		<updated>2023-04-17T23:27:10Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* Wikioe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 变量&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Variables&amp;quot;/&amp;gt; ==&lt;br /&gt;
 ECMAScript 6 中引入了 let、const。&lt;br /&gt;
&lt;br /&gt;
JavaScript 有三种声明方式：&lt;br /&gt;
# '''var'''：声明一个'''变量'''，初始化可选。&lt;br /&gt;
# '''let'''：声明一个'''变量'''，初始化可选。&lt;br /&gt;
# '''const'''：声明一个'''常量'''，必须初始化。&lt;br /&gt;
&lt;br /&gt;
 “局部变量”/“全局变量”只与其定义位置有关：在“函数内部”/“函数之外”声明的变量&lt;br /&gt;
&lt;br /&gt;
=== var：变量提升&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Hoisting&amp;quot;/&amp;gt; ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''提升（Hoisting）'''&amp;lt;/big&amp;gt;：变量和函数的'''声明'''会在物理层面（在编译阶段被放入内存中）移动到代码的最前面 —— 变量/函数的“初始化”和“使用”可以在“声明”之前（先使用再声明）。&lt;br /&gt;
 &lt;br /&gt;
 函数和变量相比，会被优先提升 —— 函数会被提升到更靠前的位置。&lt;br /&gt;
&lt;br /&gt;
# '''变量提升'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt;：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
bla = 2&lt;br /&gt;
var bla;&lt;br /&gt;
&lt;br /&gt;
// 可以理解为：&lt;br /&gt;
&lt;br /&gt;
var bla;&lt;br /&gt;
bla = 2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数提升'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;function&amp;quot;/&amp;gt;：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
hoisted(); // logs &amp;quot;foo&amp;quot;&lt;br /&gt;
function hoisted() {&lt;br /&gt;
    console.log('foo');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 可以理解为：&lt;br /&gt;
&lt;br /&gt;
function hoisted() {&lt;br /&gt;
    console.log('foo');&lt;br /&gt;
}&lt;br /&gt;
hoisted(); // logs &amp;quot;foo&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''JavaScript 只会提升声明，不会提升其初始化'''&amp;lt;/span&amp;gt; —— 如果在“声明”和“初始化”之前“使用”，将使用 &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;'''undefined'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// “使用”先于“初始化”&lt;br /&gt;
console.log(num); // Returns undefined&lt;br /&gt;
var num;&lt;br /&gt;
num = 6;&lt;br /&gt;
&lt;br /&gt;
// “初始化”先于“使用”&lt;br /&gt;
num = 6;&lt;br /&gt;
console.log(num); // returns 6&lt;br /&gt;
var num;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''函数表达式（function expressions）不会被提升'''&amp;lt;/span&amp;gt; &lt;br /&gt;
&lt;br /&gt;
: 示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
notHoisted(); // TypeError: notHoisted is not a function&lt;br /&gt;
&lt;br /&gt;
var notHoisted = function() {&lt;br /&gt;
    console.log('bar');&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== let：暂时性死区&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;/&amp;gt; ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''暂时性死区（Temporal dead zone，TDZ）'''&amp;lt;/big&amp;gt;：从“代码块的开始”直到“声明变量的行”，'''let''' 或 '''const''' 声明的变量都处于“暂时性死区”中 —— 这并不是“提升”！！！&lt;br /&gt;
&lt;br /&gt;
# 在“暂时性死区”中访问变量将抛出 '''ReferenceError'''：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
{ &lt;br /&gt;
    // TDZ starts at beginning of scope&lt;br /&gt;
    console.log(bar); // undefined&lt;br /&gt;
    console.log(foo); // ReferenceError&lt;br /&gt;
    var bar = 1;&lt;br /&gt;
    let foo = 2; &lt;br /&gt;
    // End of TDZ (for foo)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “暂时性死区”取决于“'''执行顺序'''”（时间），而非“代码顺序”（位置）：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    // TDZ starts at beginning of scope&lt;br /&gt;
    const func = () =&amp;gt; console.log(letVar); // OK&lt;br /&gt;
    let letVar = 3; &lt;br /&gt;
    // End of TDZ (for letVar)&lt;br /&gt;
&lt;br /&gt;
    func(); // Called outside TDZ!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== var 与 let 的区别&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;/&amp;gt; ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ var 与 let&lt;br /&gt;
|-&lt;br /&gt;
! \ !! var !! let&lt;br /&gt;
|-&lt;br /&gt;
| '''块作用域''' || &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;✘&amp;lt;/span&amp;gt; || &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''变量提升''' || &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt; || &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;✘&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''重新声明''' &lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var user = &amp;quot;Pete&amp;quot;;&lt;br /&gt;
var user = &amp;quot;John&amp;quot;;&lt;br /&gt;
console.log(user); // John&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;✘&amp;lt;/span&amp;gt;&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let user;&lt;br /&gt;
let user; // SyntaxError: 'user' has already been declared&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 作用域&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Scope&amp;quot;/&amp;gt;&amp;lt;ref&amp;gt;参考：[https://juejin.cn/post/7069578126979760158 《【JavaScript】深入理解JS中的词法作用域与作用域链》]&amp;lt;/ref&amp;gt; ==&lt;br /&gt;
 &amp;lt;big&amp;gt;'''作用域'''&amp;lt;/big&amp;gt;是当前的执行上下文，值和表达式在其中“可见”或可被访问。&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局作用域&amp;lt;/span&amp;gt;：可被当前'''文档'''中的任何其他代码所访问；&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;函数作用域&amp;lt;/span&amp;gt;：可被当前'''函数'''内部的其他代码所访问；&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''块作用域'''&amp;lt;/span&amp;gt;：可被当前'''块'''（由 '''&amp;lt;code&amp;gt;{ }&amp;lt;/code&amp;gt;''' 包围）内部的其他代码所访问；&lt;br /&gt;
#* 仅 let、const 支持&lt;br /&gt;
&lt;br /&gt;
 ECMAScript 6 之前没有“块作用域”：语句块中声明的变量将成为语句块所在函数（或全局作用域）的局部变量。&lt;br /&gt;
&lt;br /&gt;
=== 作用域链 ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''作用域链'''&amp;lt;/big&amp;gt;：由于作用域的层层嵌套而形成的关系。&lt;br /&gt;
&lt;br /&gt;
作用域链用于变量的查找过程：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = 10&lt;br /&gt;
&lt;br /&gt;
function outer() {&lt;br /&gt;
    var x = 20&lt;br /&gt;
    function inner() {&lt;br /&gt;
        console.log(x)&lt;br /&gt;
    }&lt;br /&gt;
    inner()&lt;br /&gt;
}&lt;br /&gt;
outer() // 20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 以上代码，包括三个作用域：&lt;br /&gt;
:# 全局作用域：包含变量 x（=10）&lt;br /&gt;
:# 函数作用域（outer）：包含变量 x（=20）&lt;br /&gt;
:# 函数作用域（inner）：不包含变量&lt;br /&gt;
: 查找过程：&lt;br /&gt;
:# console.log(x) 将在“函数作用域（inner）”中查找变量“x”：失败&lt;br /&gt;
:# 在“函数作用域（outer）”查找变量“x”：成功（x = 20）&lt;br /&gt;
:# 使用该变量：输出 20&lt;br /&gt;
&lt;br /&gt;
=== 作用域模型：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''词法作用域'''&amp;lt;/span&amp;gt;&amp;lt;ref&amp;gt;参考：[https://www.freecodecamp.org/chinese/news/javascript-lexical-scope-tutorial/ 《JavaScript 中的词法作用域——JS 中的作用域究竟是什么？》]&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
从语言的层面来说，作用域模型分两种：（根据作用域的生成时机）&lt;br /&gt;
# '''静态作用域'''：在'''代码编写时'''完成划分，作用域沿以'''定义位置'''向外延伸&lt;br /&gt;
#* 也称“&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''词法作用域'''&amp;lt;/span&amp;gt;”，是最为普遍的一种作用域模型&lt;br /&gt;
# '''动态作用域'''：在'''代码运行时'''完成划分，作用域链以'''调用栈'''向外延伸&lt;br /&gt;
#* 由 bash、Perl 等语言所使用&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''词法作用域（Lexical Scope）'''&amp;lt;/span&amp;gt;：即“词法分析时生成的作用域”，'''根据源代码中“声明变量的位置”来确定该变量在何处可用'''&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let x = &amp;quot;Eijux&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
function getX() {&lt;br /&gt;
  return x;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
console.log(getX()) // Eijux&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 变量 x 的“词法作用域”为“全局作用域”（定义时的作用域）而非“getX 函数作用域”&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 一个声明（定义变量、函数等）的“词法作用域”就是其“&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''定义时的作用域'''&amp;lt;/span&amp;gt;” —— 注意：&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;'''并不是“调用时的作用域”'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = 0&lt;br /&gt;
&lt;br /&gt;
function foo() {&lt;br /&gt;
    var x = 1&lt;br /&gt;
    bar()&lt;br /&gt;
}&lt;br /&gt;
function bar() {&lt;br /&gt;
    console.log(x) // 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
foo()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 由于“词法作用域”（定义时的作用域）决定了：foo、bar 的上级作用域是“全局作用域”，所以 bar 中使用的 x 来自“全局作用域”而非“foo 函数作用域”&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 欺骗“词法作用域” ====&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
虽然“词法作用域”在代码编写时就确定，但仍然可以修改：&lt;br /&gt;
# '''eval()'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;eval&amp;quot;/&amp;gt;：将传入的字符串当做 JavaScript 代码进行执行&lt;br /&gt;
#*有性能和安全隐患，'''不建议使用'''&lt;br /&gt;
# '''with'''&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;with&amp;quot;/&amp;gt;：扩展一个语句的作用域链&lt;br /&gt;
#* 有语义不明和兼容问题，'''已弃用'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# 通过 eval() 修改词法作用域：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var num = 10&lt;br /&gt;
var str = &amp;quot;var num = 20&amp;quot;&lt;br /&gt;
&lt;br /&gt;
function fn(str) {&lt;br /&gt;
    eval(str)&lt;br /&gt;
    console.log(num)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn(str)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 通过 with 修改词法作用域：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = { a: 1 }&lt;br /&gt;
&lt;br /&gt;
function fn(obj) {&lt;br /&gt;
    with (obj) {&lt;br /&gt;
        a = 2&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
console.log(x.a) // 1&lt;br /&gt;
fn(x)&lt;br /&gt;
console.log(x.a) // 2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 闭包&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;closure&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;closure&amp;quot;/&amp;gt; ==&lt;br /&gt;
 &amp;lt;big&amp;gt;'''闭包（closure）'''&amp;lt;/big&amp;gt;：'''函数'''以及其捆绑的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''词法环境（lexical environment）'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt;的组合&lt;br /&gt;
 &lt;br /&gt;
 —— “词法环境”包含了这个闭包创建时作用域内的任何局部变量&lt;br /&gt;
&lt;br /&gt;
'''在 JavaScript 中，闭包会随着函数的创建而被同时创建。'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
function makeAdder(x) {&lt;br /&gt;
    // 返回一个函数&lt;br /&gt;
    return function (y) {&lt;br /&gt;
        return x + y&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var add5 = makeAdder(5) // 闭包&lt;br /&gt;
var add10 = makeAdder(10) // 闭包&lt;br /&gt;
&lt;br /&gt;
console.log(add5(2));  // 7&lt;br /&gt;
console.log(add10(2)); // 12&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 以上代码包含两个闭包 add5、add10，二者：&lt;br /&gt;
:# 共享相同的“函数定义”：makeAdder&lt;br /&gt;
:# 保存不同的“词法环境”：add5 中 x 为 5，add10 中 x 为 10&lt;br /&gt;
&lt;br /&gt;
 简单来说，闭包让开发者可以从内部函数访问外部函数的作用域&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''一个有意思的例子'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;TypeScript&amp;quot; name=&amp;quot;variable&amp;quot;/&amp;gt; ===&lt;br /&gt;
 一个涉及到“'''Event Loop'''”、“'''var 作用域'''”、“'''闭包'''”（“'''词法环境'''”）的例子。&lt;br /&gt;
&lt;br /&gt;
对于以下代码：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(function() { console.log(i) }, 100 * i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 其输出如何 ❓&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; | 是否预期输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
0&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
...&lt;br /&gt;
9&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
| style=&amp;quot;width:50%;&amp;quot; | 但，实际输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
10&lt;br /&gt;
10&lt;br /&gt;
10&lt;br /&gt;
...&lt;br /&gt;
10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
原因分析：&lt;br /&gt;
# 【var 作用域】：var 变量的作用域在 for 外部 —— 每次循环使用的都是同一个 &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt;&lt;br /&gt;
#* var 变量是没有“块作用域”的 ！！！&lt;br /&gt;
# 【闭包】：for 循环将会创建 10 个闭包，它们：&lt;br /&gt;
#: 共享相同的“函数定义”：&amp;lt;code&amp;gt; function() { console.log(i) } &amp;lt;/code&amp;gt;&lt;br /&gt;
#: 共享相同的“词法环境”（“变量环境”），'''其“环境记录器”将使用同一个 var 变量''' —— &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt;&lt;br /&gt;
# 【Event Loop】：setTimeout 是一个任务，将在 for 所有循环完成之后执行 —— 而 &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt; 在所有循环之后其值为 10&lt;br /&gt;
综上：各个闭包将在 for 所有循环完成之后，使用同一个 &amp;lt;code&amp;gt; i &amp;lt;/code&amp;gt; 值（10）来执行函数。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 解决问题有多种方式： 总之，&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''使闭包不再使用相同的词法环境'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt; 即可&lt;br /&gt;
 &lt;br /&gt;
 '''思路一： 若“函数”执行依赖于“外部变量”，则使“词法环境”的“外部环境引用”不同'''&lt;br /&gt;
 &lt;br /&gt;
 '''思路二： 若“函数”执行依赖于“内部变量 / 参数”，则使“词法环境”的“环境记录”不同'''&lt;br /&gt;
&lt;br /&gt;
'''思路一'''：函数的执行依赖于“外部变量”，则“使用 '''let''' / '''const'''（块作用域）”保证每次迭代的“词法环境”的“外部环境引用”不同&lt;br /&gt;
# '''使用 let 替换 var'''：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (let i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(function() { console.log(i) }, 100 * i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''使用 let/const 捕获 var'''：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    let v = i&lt;br /&gt;
    setTimeout(function() { console.log(v) }, 100 * v)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''思路二'''：若“函数”执行依赖于“参数”，则“使用参数捕获外部变量”保证每次迭代的“词法环境”的“环境记录”不同&lt;br /&gt;
# 通过“'''立即执行的函数表达式（IIFE）'''”&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;IIFE&amp;quot;/&amp;gt;&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt;： —— 【将产生不必要的闭包（嵌套闭包）】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    (function(v) {&lt;br /&gt;
        setTimeout(function() { console.log(v) }, 100 * v)&lt;br /&gt;
    })(i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 通过“'''向函数传递变量作为参数'''”： —— 【没有不必要的闭包】&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(function(v) { console.log(v) }, 100 * i, i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 等同于：&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
function fn(v) {&lt;br /&gt;
    console.log(v)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (var i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
    setTimeout(fn, 100 * i, i)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
&lt;br /&gt;
=== '''var 没有“块作用域”'''&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;var&amp;quot;/&amp;gt; ===&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''var 变量没有“块作用域”'''：将会使用（块所在的）“函数作用域”或“全局作用域”&amp;lt;/span&amp;gt; —— 这是因为在早期的 JavaScript 中，块没有&amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;'''词法环境'''&amp;lt;/span&amp;gt;&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''var 将透传 if、for 和其它代码块'''&lt;br /&gt;
&lt;br /&gt;
示例一：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
if (true) {&lt;br /&gt;
    var x = 5;&lt;br /&gt;
}&lt;br /&gt;
console.log(x); // 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (true) {&lt;br /&gt;
    let y = 5;&lt;br /&gt;
}&lt;br /&gt;
console.log(y); // ReferenceError: y is not defined&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
示例二：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
function f() {&lt;br /&gt;
    console.log(tmp);&lt;br /&gt;
    if (false) {&lt;br /&gt;
        var tmp = 'hello world';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
f(); // undefined&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 由于变量提升：即使 var 定义的代码块永远不会执行，变量也存在，但初始化不会执行&lt;br /&gt;
&lt;br /&gt;
=== let 会不会“提升”？ ===&lt;br /&gt;
 关于这一点，MDN 都描述得前后不一致，也是很操蛋了……&lt;br /&gt;
 &lt;br /&gt;
 1、MDN：《语法和数据类型》&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Variables&amp;quot;/&amp;gt;：&lt;br /&gt;
     在 ECMAScript 6 中，let和const同样会被提升变量到代码块的顶部但是不会被赋予初始值。在变量声明之前引用这个变量，将抛出引用错误（ReferenceError）。这个变量将从代码块一开始的时候就处在一个“暂时性死区”，直到这个变量被声明为止。&lt;br /&gt;
 &lt;br /&gt;
 2、MDN：《语法和数据类型》&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;/&amp;gt;：&lt;br /&gt;
     var 和 let 的另一个重要区别，let 声明的变量不会在作用域中被提升，它是在编译时才初始化（参考下面的暂时性死区）。&lt;br /&gt;
&lt;br /&gt;
两种说法，以一个类似示例来说明：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var foo = 33;&lt;br /&gt;
if (foo) {&lt;br /&gt;
    console.log(foo) // ReferenceError: Cannot access 'foo' before initialization&lt;br /&gt;
    let foo = 44;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
对于 ReferenceError 该如何解释呢 ❓ &lt;br /&gt;
# 说法一：由于 let 变量提升，导致此处使用“块作用域内定义变量”，但该变量处于“暂时性死区”，所以出现此错误。&lt;br /&gt;
#: 网上有内容更是强行将 let 变量创建分为三个过程：创建、初始化、赋值 …… 有点扯。&lt;br /&gt;
# 说法二：由于'''词法作用域'''，导致此处使用“块作用域内定义变量”，但该变量处于“暂时性死区”，所以出现此错误。&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt; 个人理解：let 并不会提升，以上示例是“词法作用域”影响。—— 或许看看 JS 引擎执行过程更清楚&lt;br /&gt;
&lt;br /&gt;
=== 什么是“隐式声明的全局变量”？ ===&lt;br /&gt;
 &amp;lt;big&amp;gt;'''隐式声明的全局变量'''&amp;lt;/big&amp;gt;：直接对一个未声明的变量赋值，无论在函数内外都会将其“隐式地”声明为一个“全局变量”&lt;br /&gt;
&lt;br /&gt;
示例，以下变量全都是“隐式声明的全局变量”：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
x = '?'&lt;br /&gt;
&lt;br /&gt;
function fn() {&lt;br /&gt;
    x = 'hello'&lt;br /&gt;
    y = 'bye'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn()&lt;br /&gt;
console.log(x, y) // hello bye&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 严格模式下，“对一个未声明的变量赋值”将抛出 ReferenceError&lt;br /&gt;
# 非严格模式：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
var x = 0;&lt;br /&gt;
function f() {&lt;br /&gt;
    var x = y = 1;&lt;br /&gt;
}&lt;br /&gt;
f();&lt;br /&gt;
&lt;br /&gt;
console.log(x, y); // 0 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# 严格模式：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
var x = 0;&lt;br /&gt;
function f() {&lt;br /&gt;
    var x = y = 1; // ReferenceError: y is not defined&lt;br /&gt;
}&lt;br /&gt;
f();&lt;br /&gt;
&lt;br /&gt;
console.log(x, y);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== Wikioe ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;Wikioe&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;Wikioe&amp;quot; name=&amp;quot;lexical-environment&amp;quot;&amp;gt;参考：【'''[[JS 执行过程：执行上下文、词法环境]]'''】&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MDN ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;MDN&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Variables&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_Types MDN：《语法和数据类型》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Hoisting&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Glossary/Hoisting MDN：《Hoisting（变量提升）》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;function&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function MDN：《function》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;var&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var MDN：《var》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;let&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let MDN：《let》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;Scope&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Glossary/Scope MDN：《Scope（作用域）》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;eval&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval MDN：《eval()》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;with&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/with MDN：《with》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;closure&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures MDN：《闭包》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;MDN&amp;quot; name=&amp;quot;IIFE&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Glossary/IIFE MDN：《IIFE（立即调用函数表达式）》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
=== javascript.info ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;javascript.info&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;var&amp;quot;&amp;gt;参考：[https://zh.javascript.info/var javascript.info：《老旧的 &amp;quot;var&amp;quot;》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;javascript.info&amp;quot; name=&amp;quot;closure&amp;quot;&amp;gt;参考：[https://zh.javascript.info/closure javascript.info：《变量作用域，闭包》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
=== TypeScript ===&lt;br /&gt;
&amp;lt;references group=&amp;quot;TypeScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;TypeScript&amp;quot; name=&amp;quot;variable&amp;quot;&amp;gt;参考：[https://www.tslang.cn/docs/handbook/variable-declarations.html TypeScript：《变量声明》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
=== 其他 ===&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6631</id>
		<title>Event Loop：事件循环</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6631"/>
		<updated>2023-04-17T23:26:35Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 在 MDN 上看到 JavaScript 的[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop 《并发模型与事件循环》]，但由于该页面内容过少，实在不变学习。&lt;br /&gt;
 &lt;br /&gt;
 而网络上搜到的内容大同小异，互相又有不小出入，难以拿捏。&lt;br /&gt;
 &lt;br /&gt;
 众所周知，JavaScript 是没有所谓源代码的“源代码”，所以这部分内容只能在“规范文件”中寻找了。&lt;br /&gt;
&lt;br /&gt;
* 以下内容参考《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;&amp;gt;参考：[https://html.spec.whatwg.org/multipage/webappapis.html#event-loops 《HTML Standard》：“Event loops”]&amp;lt;/ref&amp;gt;、MDN&amp;lt;ref name=&amp;quot;MDN&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&amp;lt;/ref&amp;gt;、与网络内容整理。&lt;br /&gt;
&lt;br /&gt;
== 前置知识 ==&lt;br /&gt;
 见：&amp;lt;big&amp;gt;'''[[浏览器基础：进程与线程]]'''&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 “一个 Tab 页面对应一个'''渲染进程'''”，而“渲染进程中只能存在一个 '''JS 引擎线程'''”（即，'''主线程'''），即：页面中的所有 JS 都由同一单线程运行。&lt;br /&gt;
&lt;br /&gt;
？？？？？？由于“渲染进程”负责了页面几乎所有的任务（事件、交互、脚本、渲染、网络），所以如何协调各个任务的执行是关键问题。&lt;br /&gt;
&lt;br /&gt;
[[File:浏览器的进程与线程.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“任务” ===&lt;br /&gt;
 JavaScript中，“任务”被分为两种：“同步任务”，“异步任务”。“异步任务”（Task）：又分为“宏任务”（MacroTask）与“微任务”（MicroTask）。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 是针对“异步任务”而言。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ——【'''P.S. 《HTML Standard》中已经不再有“宏任务”（MacroTask）这一说法 —— 它就是“任务”（task）'''】&lt;br /&gt;
&lt;br /&gt;
# 同步任务：在“主线程”上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务。&lt;br /&gt;
# 异步任务：不直接进入“主线程”，而进入“任务队列”（task queue）的任务。&lt;br /&gt;
## '''任务（task）'''：事件、解析、回调、使用资源、对 DOM 操作做出反应 ——【根据《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt;中定义】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''script(整体代码)、setTimeout、setInterval、setImmediate（node独有）、requestAnimationFrame(浏览器独有)、I/O、UI rendering'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，只有“已经处于 task queues 中”的任务才会被执行'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 setTimeout 引起的无限循环，会导致性能下降，但是很难导致直接崩溃】&lt;br /&gt;
## '''微任务（microtask）'''：——【暂无明确定义，见：[[#到底什么是“Microtasks”？]]】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''Promises 的回调、queueMicrotask()、process.nextTick（node独有）、Object.observe(废弃)、MutationObserver'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，“microtask queue 中的所有”任务会被执行（哪怕是中途添加的“microtask”），直到队列为空'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 Promises 引起无限循环，将直接导致崩溃。这也是为什么要求'''代码慎用“queueMicrotask()”'''】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;一点小小的猜测：&lt;br /&gt;
 &lt;br /&gt;
     来源于“渲染进程”中其他线程（非“JS 引擎线程”）引起的异步任务，即“任务（task）”。&lt;br /&gt;
     &lt;br /&gt;
     来源于“渲染进程”的“JS 引擎线程”引起的异步任务，即“微任务（microtask）”。&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“运行时”&amp;lt;ref&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
To run JavaScript code, the runtime engine maintains a set of agents in which to execute JavaScript code. Each agent is made up of a set of execution contexts, the execution context stack, a main thread, a set for any additional threads that may be created to handle workers, a task queue, and a microtask queue. Other than the main thread—which some browsers share across multiple agents—each component of an agent is unique to that agent.&lt;br /&gt;
&lt;br /&gt;
在执行 JavaScript 代码的时候，JavaScript 运行时实际上维护了一组用于执行 JavaScript 代码的代理。每个代理由一组执行上下文的集合、执行上下文栈、主线程、一组可能创建用于执行 worker 的额外的线程集合、一个任务队列以及一个微任务队列构成。除了主线程（某些浏览器在多个代理之间共享的主线程）之外，其他组成部分对该代理都是唯一的。 &lt;br /&gt;
&lt;br /&gt;
——MDN：《深入：微任务与 Javascript 运行时环境》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
An agent comprises a set of ECMAScript execution contexts, an execution context stack, a running execution context, an Agent Record, and an executing thread. Except for the executing thread, the constituents of an agent belong exclusively to that agent.&lt;br /&gt;
&lt;br /&gt;
“代理”（Agent）包括：一组ECMAScript执行上下文、执行上下文堆栈、运行的执行上下文、代理记录和执行线程。除了执行线程之外，代理的组成部分只属于该代理。 &lt;br /&gt;
&lt;br /&gt;
——《ECMAScript® 2023 Language Specification》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Conceptually, the agent concept is an architecture-independent, idealized &amp;quot;thread&amp;quot; in which JavaScript code runs. Such code can involve multiple globals/realms that can synchronously access each other, and thus needs to run in a single execution thread.&lt;br /&gt;
&lt;br /&gt;
从概念上讲，代理概念是一个独立于体系结构、理想化的“线程”，JavaScript代码在其中运行。这样的代码可能涉及多个全局/领域，这些全局/领域可以同步访问彼此，因此需要在单个执行线程中运行。&lt;br /&gt;
&lt;br /&gt;
——《HTML Standard》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://tc39.es/ecma262/#sec-agents 《ECMAScript® 2023 Language Specification》：“Agents”]&lt;br /&gt;
::# [https://html.spec.whatwg.org/multipage/webappapis.html#agents-and-agent-clusters 《HTML Standard》：“Agents and agent clusters”]&lt;br /&gt;
::# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&lt;br /&gt;
::# [https://github.com/Lawliet01/everyone-can-read-spec/blob/main/8.execution-environment.md 《【人人都能读标准】8.可视化JavaScript的运行环境：agents、执行上下文、Realm》]&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
 从概念上讲，&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''代理（Agent）'''&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt; 是一个独立于体系结构、理想化的“线程”，每个 ECMAScript 程序都必须在其中运行。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''代理是一种规范机制，不需要与任何特定的 ECMAScript 实现部件相对应。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agent 包括了：&lt;br /&gt;
# '''一组执行上下文（a set of execution contexts）&amp;lt;ref name=&amp;quot;execution_context&amp;quot;&amp;gt;参考：【'''[[JS 执行过程：执行上下文、词法环境]]'''】&amp;lt;/ref&amp;gt;'''：即，一组可执行、待执行的上下文&lt;br /&gt;
# '''执行上下文栈（the execution context stack）'''&amp;lt;ref name=&amp;quot;execution_context&amp;quot;/&amp;gt;：在一些文章中叫做“'''调用栈（call stack）'''”&lt;br /&gt;
#* 栈顶的那个上下文被称为“运行中的执行上下文（running execution context）”&lt;br /&gt;
# '''执行线程（an executing thread）'''：在一些文章中叫做“'''主线程（a main thread）'''”&lt;br /&gt;
# '''事件循环（event loop）'''：&lt;br /&gt;
#* 它包括了：一个“微任务队列（microtask queue）”，一个/多个“任务队列（task queue）”&lt;br /&gt;
# '''代理记录（Agent Record）'''：？？？&lt;br /&gt;
&lt;br /&gt;
* 一个宿主（浏览器、Node.js）可以有多个 Agent，Agent 之间相互隔离，可以通过发送消息进行通信。&lt;br /&gt;
* 当两个 Agent 同处一个“Agent Clusters”（代理集群）时，它们可以共享内存。&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''除了“执行线程”（主线程）、“事件循环”之外，代理的组成部分只属于该代理。'''&amp;lt;/span&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
     “执行线程”（主线程）：某些浏览器在多个代理之间共享主线程&lt;br /&gt;
     &lt;br /&gt;
     “事件循环”：可以在单个线程中协同调度多个窗口事件循环 —— 见：[[#Event Loop]]&lt;br /&gt;
 &lt;br /&gt;
 ——【《ECMAScript® 2023 Language Specification》、MDN 只提到：“执行线程”并不一定由“Agent”独占。但从《HTML Standard》对“Event Loop”的表述来看，似乎也并不一定由“Agent”独占】&lt;br /&gt;
 &lt;br /&gt;
 ——【尽管标准提到，不同的“Agent”允许共享同一条“执行线程”，但&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''现代浏览器基本上都是给每个“Agent”启用一条独立的“执行线程”'''&amp;lt;/span&amp;gt;。】&lt;br /&gt;
&lt;br /&gt;
Web 平台上存在以下类型的代理：&lt;br /&gt;
# '''Similar-origin window agent'''：即“同源窗口代理”，包含各种窗口对象，这些对象可以直接或通过使用 '''document.domain''' 相互访问。&lt;br /&gt;
#* &lt;br /&gt;
#* 两个“同源”的窗口对象可以位于不同的“Similar-origin window agent”中，例如，如果它们各自位于自己的浏览上下文组中。&lt;br /&gt;
# '''Dedicated worker agent'''：包含了一个 DedicatedWorkerGlobalScope；&lt;br /&gt;
# '''Shared worker agent'''：包含了一个 SharedWorkerGlobalScope；&lt;br /&gt;
# '''Service worker agent'''：包含了一个 ServiceWorkerGlobalScope；&lt;br /&gt;
# '''Worklet agent'''：包含了一个 WorkletGlobalScope 对象；&lt;br /&gt;
&lt;br /&gt;
== Event Loop&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt; ==&lt;br /&gt;
 要协调事件（event），用户交互（user interaction），脚本（script），渲染（rendering），网络（networking）等，用户代理必须使用本节中描述的事件循环。&lt;br /&gt;
&lt;br /&gt;
每个'''“代理”（Agent）'''有一个关联的“事件循环”，且该循环对该代理是'''唯一'''的。&lt;br /&gt;
# '''Similar-origin window agent''' 的事件循环称为“'''窗口事件循环'''”（'''window event loop'''）。&lt;br /&gt;
# '''Dedicated worker agent'''、'''Shared worker agent''' 或 '''Service worker agent''' 的事件循环称为“'''工作事件循环'''”（'''worker event loop'''）。&lt;br /&gt;
# '''Worklet agent''' 的事件循环称为“'''工件事件循环'''”（'''worklet event loop'''）。&lt;br /&gt;
&lt;br /&gt;
 Event loops do not necessarily correspond to implementation threads. For example, multiple window event loops could be cooperatively scheduled in a single thread.&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''事件循环不一定对应于“实现线程”（注：implementation threads，即“浏览器线程”）。例如，可以在单个线程中协同调度多个窗口事件循环。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 However, for the various worker agents that are allocated with &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; set to true, the JavaScript specification does place requirements on them regarding forward progress, which effectively amount to requiring dedicated per-agent threads in those cases.&lt;br /&gt;
 然而，对于 &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; 设置为 true 的各种 worker agents，JavaScript 规范确实对它们提出了关于“forward progress？”的要求，在这些情况下，这实际上相当于需要专用的每个代理线程。&lt;br /&gt;
&lt;br /&gt;
* 一个事件循环具有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个或多个“任务队列”（task queues）'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
** &amp;lt;q&amp;gt;'''任务队列是“集合”（set），而不是“队列”（queue）'''，因为事件循环处理模型从所选队列中获取第一个可运行的任务，而不是将第一个任务出列。&amp;lt;/q&amp;gt;&lt;br /&gt;
** &amp;lt;q&amp;gt;'''微任务队列（microtask queue）不是任务队列（task queues）'''。&amp;lt;/q&amp;gt;&lt;br /&gt;
* 每个事件循环都有一个当前“正在运行的任务”（currently running task），要么是一个任务，要么是 null。初始为空。&lt;br /&gt;
** 它用于处理可重入性。&lt;br /&gt;
* 每个事件循环都有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个“微任务队列”（microtask queue）'''&amp;lt;/span&amp;gt;，该队列是一个初始为空的微任务队列。&lt;br /&gt;
* 每个事件循环都有一个“正在执行微任务的检查点”（performing a microtask checkpoint）的布尔值。该值最初为 false。&lt;br /&gt;
** 它用于防止重入调用。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上次渲染机会时间”（last render opportunity time），最初设置为零。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上一个空闲周期的开始时间”（last idle period start time），最初设置为零。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 任务（Tasks） ===&lt;br /&gt;
“任务”（Tasks）包括以下几种：&lt;br /&gt;
# '''事件'''（Events）：在特定 EventTarget 对象上调度 Event 对象，通常由专用的任务完成。&lt;br /&gt;
# '''解析'''（Parsing）：HTML 解析器标记一个或多个字节，然后处理任何生成的标记，通常是一项任务。&lt;br /&gt;
# '''回调'''（Callbacks）：调用回调通常由一个专用的任务完成。&lt;br /&gt;
# '''使用资源'''（Using a resource）：当算法获取资源时，如果获取是以非阻塞的方式发生的，那么一旦部分或全部资源可用，就由任务执行对资源的处理。&lt;br /&gt;
# '''对 DOM 操作做出反应'''（Reacting to DOM manipulation）：一些元素具有响应 DOM 操作而触发的任务，例如：当该元素被插入到文档中时。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
从形式上讲，“任务”（Tasks）具有以下结构：&lt;br /&gt;
# 步骤（steps）：指定任务要完成的工作的一系列步骤。&lt;br /&gt;
# '''来源'''（source）：用于对相关任务进行分组和序列化。&lt;br /&gt;
# 文档（document）与任务关联的文档，对于不在“窗口事件循环”中的任务则为 null。&lt;br /&gt;
# 脚本评估环境设置对象集（A script evaluation environment settings object set）：用于跟踪任务期间的脚本评估。&lt;br /&gt;
根据其源字段（source），每个任务都被定义为来自特定的“任务源”（task source）。对于每个事件循环，每个“任务源”都必须与特定的“任务队列”相关联。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 通用任务源（task sources） ===&lt;br /&gt;
# '''DOM 操作任务源'''（The DOM manipulation task source）：用于对 DOM 操作做出反应的功能，例如在将元素插入文档时以非阻塞方式发生的事情。&lt;br /&gt;
# '''用户交互任务源'''（The user interaction task source）：用于对用户交互做出反应的功能，例如键盘或鼠标输入。&lt;br /&gt;
# '''网络任务源'''（The networking task source）：用于响应网络活动而触发的功能。&lt;br /&gt;
# '''导航和遍历任务源'''（The navigation and traversal task source）：用于对导航和历史遍历中涉及的任务进行排队。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''处理模型''' ===&lt;br /&gt;
只要事件循环存在，它就必须持续运行以下步骤：&lt;br /&gt;
# 让 oldestTask 和 taskStartTime 为 null。&lt;br /&gt;
# 如果事件循环有一个'''任务队列'''其中至少有一个可运行的任务，则：&lt;br /&gt;
## 由“实现”（浏览器）定义的规则，选择一个任务队列作为 taskQueue。（“微任务队列”并不是一个“任务队列”，所以不会被选择）——【“选择哪个任务队列”：由浏览器定义（即文档中的“implementation-defined”，客户端软件本身被称为一种“implementation”）决定，这就允许优先选择对性能敏感的任务】&lt;br /&gt;
## 将 taskStartTime 设置为“不安全的共享当前时间”。&lt;br /&gt;
## 将 oldestTask 设置为 taskQueue 中的'''第一个可运行任务'''，并将其从 taskQueue 中删除。——【任务队列是“set”，所以并非“出队”】&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置为 oldestTask。&lt;br /&gt;
## 执行 oldestTask 的步骤（Steps）。&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置回 null。&lt;br /&gt;
# '''执行微任务检查点'''：&lt;br /&gt;
## 如果事件循环的“正在执行微任务的检查点”为 true，则返回。——【检查重入】&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为 true。——【防止重入】&lt;br /&gt;
## 当事件循环的“微任务队列”不为空时：——【！！！'''不为空将一直重复执行'''！！！】&lt;br /&gt;
### 从事件循环的“微任务队列”中“出队”一个任务作为 oldestMicrotask。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置为 oldestMicrotask。&lt;br /&gt;
### 执行 oldestMicrotask。&lt;br /&gt;
###* 这可能涉及调用脚本的回调，并最终调用“clean up after running script”步骤，而该步骤的最后一步又将调用'''执行微任务检查点'''。这就是为什么设置“正在执行微任务的检查点”来防止“'''重入'''”。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置回null。&lt;br /&gt;
## 对于负责的事件循环为该事件循环的每个“环境设置对象”，通知该“环境设置对象”上 rejected 的 promise。&lt;br /&gt;
## 清理索引数据库事务。&lt;br /&gt;
## 执行 ClearKeptObjects()。&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为false。&lt;br /&gt;
# 将 hasARenderingOpportunity 设置为 false。&lt;br /&gt;
# 将现在时刻设置为“不安全的共享当前时间”。&lt;br /&gt;
# 如果 oldestTask 不为 null，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# '''更新渲染'''：如果这是一个窗口事件循环，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# ……（省略）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 总结 ===&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;&lt;br /&gt;
 当“调用栈”为空时（即，同步代码执行完毕时），“主线程”才会开始处理“（由 Event Loop 循环选取的）来自任务队列中的任务”。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 一次循环的顺序为：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务队列的“第一个可运行任务”（宏任务） -&amp;gt; 微任务队列的所有任务（微任务） -&amp;gt; 渲染'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 对于说法：“微任务 -&amp;gt; 渲染 -&amp;gt; 宏任务”，从代码运行结果来看似乎没问题，其实忽略了一点“'''script 脚本本身也是一个任务（宏任务）'''”。&lt;br /&gt;
&lt;br /&gt;
== 关于：Microtasks ==&lt;br /&gt;
&lt;br /&gt;
=== 到底什么是“Microtasks”？ ===&lt;br /&gt;
 无论是《ECMAScript® 2023 Language Specification》、《HTML Standard》、MDN，都没有找到关于“宏任务”、“微任务”的定义性描述。&lt;br /&gt;
 &lt;br /&gt;
 ——《ECMAScript® 2023 Language Specification》：压根就没提到 Microtasks 这个字&lt;br /&gt;
 &lt;br /&gt;
 ——《HTML Standard》：提到了 Microtask queuing：&lt;br /&gt;
     A microtask is a colloquial way of referring to a task that was created via the queue a microtask algorithm.&lt;br /&gt;
     微任务是一种口语化的方式，指的是通过“排队微任务算法”创建的任务。 ——【但文档中，与“任务”相比似乎只有“任务源”（task source）不同】&lt;br /&gt;
 &lt;br /&gt;
 —— MDN：只提到了“任务”（Tasks）与“微任务”（Microtasks）的区别&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 此外，在 Jake Archibald 的文章&amp;lt;ref&amp;gt;参考：[https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ 《Tasks, microtasks, queues and schedules》——Jake Archibald]&amp;lt;/ref&amp;gt;中提到：&lt;br /&gt;
     ECMAScript has the concept of &amp;quot;jobs&amp;quot; which are similar to microtasks, but the relationship isn't explicit aside from vague mailing list discussions. However, the general consensus is that promises should be part of the microtask queue, and for good reason.&lt;br /&gt;
     ECMAScript有类似于 microtasks 的“jobs”概念，但除了模糊的邮件列表讨论之外，这种关系并不明确。然而，普遍的共识是，promises 应该是 microtask queue 的一部分，这是有充分理由的。&lt;br /&gt;
     ……&lt;br /&gt;
     As mentioned, in ECMAScript land, they call microtasks &amp;quot;jobs&amp;quot;. In step 8.a of PerformPromiseThen, EnqueueJob is called to queue a microtask.&lt;br /&gt;
     如前所述，在 ECMAScript 领域，他们将微任务称为“jobs”。在 PerformPromiseThen 的步骤 8.a 中，调用 EnqueueJob 对 microtask 进行排队。&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 再此外，javascript.info 中有提到：&lt;br /&gt;
     Microtasks come solely from our code. They are usually created by promises……&amp;lt;ref&amp;gt;参考：[https://javascript.info/event-loop javascript.info：《Event loop: microtasks and macrotasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     微任务仅来自于我们的代码。它们通常是由 promise 创建的……&lt;br /&gt;
     &lt;br /&gt;
     Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue PromiseJobs, more often referred to as the “microtask queue” (V8 term).&amp;lt;ref&amp;gt;参考：[https://javascript.info/microtask-queue javascript.info：《Microtasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     异步任务需要适当的管理。为此，ECMA 标准规定了一个内部队列 PromiseJobs，通常被称为“微任务队列（microtask queue）”（V8 术语）。&lt;br /&gt;
&lt;br /&gt;
所以，Promise 异步任务（注意，仅仅是它的回调，而不是它本身）是 microtask 应该是“潜规则”了，此外，我们还可以使用“'''queueMicrotask()'''”方法来添加 microtask。&lt;br /&gt;
: ——【P.S. 对于 Node.js 并不清楚】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 为什么要支持“Microtasks”？&amp;lt;ref name=&amp;quot;MDN&amp;quot;/&amp;gt; ===&lt;br /&gt;
 微任务是另一种解决该问题的方案，通过将代码安排在下一次事件循环开始之前运行而不是必须要等到下一次开始之后才执行，这样可以&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''提供一个更好的访问级别'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 如何使用“Microtasks”？&amp;lt;ref&amp;gt;参考：&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide MDN：《在 JavaScript 中通过 queueMicrotask() 使用微任务》]&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/queueMicrotask MDN：《queueMicrotask()》]&lt;br /&gt;
# [https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing 《HTML Standard》：“Microtask queuing”]&lt;br /&gt;
&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
 '''Window''' 或 '''Worker''' 接口的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''queueMicrotask()'''&amp;lt;/span&amp;gt; 方法，将微任务加入队列以在控制返回浏览器的事件循环之前的安全时间执行。&lt;br /&gt;
&lt;br /&gt;
'''语法：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;queueMicrotask(() =&amp;gt; {/* ... */});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let callback = () =&amp;gt; log(&amp;quot;Regular timeout callback has run&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let urgentCallback = () =&amp;gt; log(&amp;quot;*** Oh noes! An urgent callback has run!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
log(&amp;quot;Main program started&amp;quot;);&lt;br /&gt;
setTimeout(callback, 0);&lt;br /&gt;
queueMicrotask(urgentCallback);&lt;br /&gt;
log(&amp;quot;Main program exiting&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Main program started&lt;br /&gt;
Main program exiting&lt;br /&gt;
*** Oh noes! An urgent callback has run!&lt;br /&gt;
Regular timeout callback has run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 关于 Node.js 中的 Event Loop，暂不了解，有时间再看看其他文章。&lt;br /&gt;
 &lt;br /&gt;
 参考：[https://juejin.cn/post/6844903764202094606 一次弄懂Event Loop（彻底解决此类面试问题）]&lt;br /&gt;
&lt;br /&gt;
 P.S.&lt;br /&gt;
 JavaScript 是没有一个 WebAPIs 结构的，网上文章图片展示的 WebAPIs 大概是指那些任务来自于 WebAPI，但是这种描述并不准确。&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''[[变量、词法作用域、闭包#一个有意思的例子 | 一个有意思的例子]]'''&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
== 写在后面 ==&lt;br /&gt;
 通过查询 EventLoop 的资料，前后沟通了许多内容，浅浅地做个梳理，以及一点点未解。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 首先，EventLoop 的资料集中在《HTML Standard》，而《ECMAScript® 2023 Language Specification》中并无只言片语，说明：'''EventLoop 并非 ECMAScript 语言的特性，而是 Web 相关规范'''。  ——【&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''即，EventLoop 并不由“JS 引擎”提供，而是依靠浏览器实现'''&amp;lt;/span&amp;gt; 】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 其次，Event Loop 提到了 ECMAScript 中的 Agent 概念：&lt;br /&gt;
 1、每个 Agent 都有且仅有一个关联的 Event Loop&lt;br /&gt;
 2、EventLoop 选取任务是交由 Agent 的“执行线程”（或者说：主线程）来执行&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 那么，问题来了&amp;lt;big&amp;gt;❓&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 1、Agent 与 浏览器的“渲染进程”是否有重叠呢？ —— 虽然《HTML Standard》描述 Agent 是一个“idealized &amp;quot;thread&amp;quot;”&lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 2、Agent 的“执行线程”是不是就是“渲染进程”的“JS 引擎线程”呢？ &lt;br /&gt;
     ——【我个人理解就是一个玩意儿（还有[https://developer.mozilla.org/zh-CN/docs/Glossary/Main_thread 《MDN：“主线程”》]），虽然概念不同】&lt;br /&gt;
 &lt;br /&gt;
 3、EventLoop 是由“渲染进程”中的某个线程实现吗？ &lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 网上并没有找到 Agent 相关的文章……&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6630</id>
		<title>Event Loop：事件循环</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6630"/>
		<updated>2023-04-17T23:26:02Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 在 MDN 上看到 JavaScript 的[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop 《并发模型与事件循环》]，但由于该页面内容过少，实在不变学习。&lt;br /&gt;
 &lt;br /&gt;
 而网络上搜到的内容大同小异，互相又有不小出入，难以拿捏。&lt;br /&gt;
 &lt;br /&gt;
 众所周知，JavaScript 是没有所谓源代码的“源代码”，所以这部分内容只能在“规范文件”中寻找了。&lt;br /&gt;
&lt;br /&gt;
* 以下内容参考《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;&amp;gt;参考：[https://html.spec.whatwg.org/multipage/webappapis.html#event-loops 《HTML Standard》：“Event loops”]&amp;lt;/ref&amp;gt;、MDN&amp;lt;ref name=&amp;quot;MDN&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&amp;lt;/ref&amp;gt;、与网络内容整理。&lt;br /&gt;
&lt;br /&gt;
== 前置知识 ==&lt;br /&gt;
 见：&amp;lt;big&amp;gt;'''[[浏览器基础：进程与线程]]'''&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 “一个 Tab 页面对应一个'''渲染进程'''”，而“渲染进程中只能存在一个 '''JS 引擎线程'''”（即，'''主线程'''），即：页面中的所有 JS 都由同一单线程运行。&lt;br /&gt;
&lt;br /&gt;
？？？？？？由于“渲染进程”负责了页面几乎所有的任务（事件、交互、脚本、渲染、网络），所以如何协调各个任务的执行是关键问题。&lt;br /&gt;
&lt;br /&gt;
[[File:浏览器的进程与线程.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“任务” ===&lt;br /&gt;
 JavaScript中，“任务”被分为两种：“同步任务”，“异步任务”。“异步任务”（Task）：又分为“宏任务”（MacroTask）与“微任务”（MicroTask）。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 是针对“异步任务”而言。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ——【'''P.S. 《HTML Standard》中已经不再有“宏任务”（MacroTask）这一说法 —— 它就是“任务”（task）'''】&lt;br /&gt;
&lt;br /&gt;
# 同步任务：在“主线程”上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务。&lt;br /&gt;
# 异步任务：不直接进入“主线程”，而进入“任务队列”（task queue）的任务。&lt;br /&gt;
## '''任务（task）'''：事件、解析、回调、使用资源、对 DOM 操作做出反应 ——【根据《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt;中定义】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''script(整体代码)、setTimeout、setInterval、setImmediate（node独有）、requestAnimationFrame(浏览器独有)、I/O、UI rendering'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，只有“已经处于 task queues 中”的任务才会被执行'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 setTimeout 引起的无限循环，会导致性能下降，但是很难导致直接崩溃】&lt;br /&gt;
## '''微任务（microtask）'''：——【暂无明确定义，见：[[#到底什么是“Microtasks”？]]】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''Promises 的回调、queueMicrotask()、process.nextTick（node独有）、Object.observe(废弃)、MutationObserver'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，“microtask queue 中的所有”任务会被执行（哪怕是中途添加的“microtask”），直到队列为空'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 Promises 引起无限循环，将直接导致崩溃。这也是为什么要求'''代码慎用“queueMicrotask()”'''】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;一点小小的猜测：&lt;br /&gt;
 &lt;br /&gt;
     来源于“渲染进程”中其他线程（非“JS 引擎线程”）引起的异步任务，即“任务（task）”。&lt;br /&gt;
     &lt;br /&gt;
     来源于“渲染进程”的“JS 引擎线程”引起的异步任务，即“微任务（microtask）”。&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“运行时”&amp;lt;ref&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
To run JavaScript code, the runtime engine maintains a set of agents in which to execute JavaScript code. Each agent is made up of a set of execution contexts, the execution context stack, a main thread, a set for any additional threads that may be created to handle workers, a task queue, and a microtask queue. Other than the main thread—which some browsers share across multiple agents—each component of an agent is unique to that agent.&lt;br /&gt;
&lt;br /&gt;
在执行 JavaScript 代码的时候，JavaScript 运行时实际上维护了一组用于执行 JavaScript 代码的代理。每个代理由一组执行上下文的集合、执行上下文栈、主线程、一组可能创建用于执行 worker 的额外的线程集合、一个任务队列以及一个微任务队列构成。除了主线程（某些浏览器在多个代理之间共享的主线程）之外，其他组成部分对该代理都是唯一的。 &lt;br /&gt;
&lt;br /&gt;
——MDN：《深入：微任务与 Javascript 运行时环境》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
An agent comprises a set of ECMAScript execution contexts, an execution context stack, a running execution context, an Agent Record, and an executing thread. Except for the executing thread, the constituents of an agent belong exclusively to that agent.&lt;br /&gt;
&lt;br /&gt;
“代理”（Agent）包括：一组ECMAScript执行上下文、执行上下文堆栈、运行的执行上下文、代理记录和执行线程。除了执行线程之外，代理的组成部分只属于该代理。 &lt;br /&gt;
&lt;br /&gt;
——《ECMAScript® 2023 Language Specification》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Conceptually, the agent concept is an architecture-independent, idealized &amp;quot;thread&amp;quot; in which JavaScript code runs. Such code can involve multiple globals/realms that can synchronously access each other, and thus needs to run in a single execution thread.&lt;br /&gt;
&lt;br /&gt;
从概念上讲，代理概念是一个独立于体系结构、理想化的“线程”，JavaScript代码在其中运行。这样的代码可能涉及多个全局/领域，这些全局/领域可以同步访问彼此，因此需要在单个执行线程中运行。&lt;br /&gt;
&lt;br /&gt;
——《HTML Standard》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://tc39.es/ecma262/#sec-agents 《ECMAScript® 2023 Language Specification》：“Agents”]&lt;br /&gt;
::# [https://html.spec.whatwg.org/multipage/webappapis.html#agents-and-agent-clusters 《HTML Standard》：“Agents and agent clusters”]&lt;br /&gt;
::# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&lt;br /&gt;
::# [https://github.com/Lawliet01/everyone-can-read-spec/blob/main/8.execution-environment.md 《【人人都能读标准】8.可视化JavaScript的运行环境：agents、执行上下文、Realm》]&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
 从概念上讲，&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''代理（Agent）'''&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt; 是一个独立于体系结构、理想化的“线程”，每个 ECMAScript 程序都必须在其中运行。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''代理是一种规范机制，不需要与任何特定的 ECMAScript 实现部件相对应。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agent 包括了：&lt;br /&gt;
# '''一组执行上下文（a set of execution contexts）&amp;lt;ref name=&amp;quot;execution_context&amp;quot;&amp;gt;参考：【'''[[JS 执行过程：执行上下文、词法环境]]'''】&amp;lt;/ref&amp;gt;'''：即，一组可执行、待执行的上下文&lt;br /&gt;
# '''执行上下文栈（the execution context stack）'''&amp;lt;ref name=&amp;quot;execution_context&amp;quot;/&amp;gt;：在一些文章中叫做“'''调用栈（call stack）'''”&lt;br /&gt;
#* 栈顶的那个上下文被称为“运行中的执行上下文（running execution context）”&lt;br /&gt;
# '''执行线程（an executing thread）'''：在一些文章中叫做“'''主线程（a main thread）'''”&lt;br /&gt;
# '''事件循环（event loop）'''：&lt;br /&gt;
#* 它包括了：一个“微任务队列（microtask queue）”，一个/多个“任务队列（task queue）”&lt;br /&gt;
# '''代理记录（Agent Record）'''：？？？&lt;br /&gt;
&lt;br /&gt;
* 一个宿主（浏览器、Node.js）可以有多个 Agent，Agent 之间相互隔离，可以通过发送消息进行通信。&lt;br /&gt;
* 当两个 Agent 同处一个“Agent Clusters”（代理集群）时，它们可以共享内存。&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''除了“执行线程”（主线程）、“事件循环”之外，代理的组成部分只属于该代理。'''&amp;lt;/span&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
     “执行线程”（主线程）：某些浏览器在多个代理之间共享主线程&lt;br /&gt;
     &lt;br /&gt;
     “事件循环”：可以在单个线程中协同调度多个窗口事件循环 —— 见：[[#Event Loop]]&lt;br /&gt;
 &lt;br /&gt;
 ——【《ECMAScript® 2023 Language Specification》、MDN 只提到：“执行线程”并不一定由“Agent”独占。但从《HTML Standard》对“Event Loop”的表述来看，似乎也并不一定由“Agent”独占】&lt;br /&gt;
 &lt;br /&gt;
 ——【尽管标准提到，不同的“Agent”允许共享同一条“执行线程”，但&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''现代浏览器基本上都是给每个“Agent”启用一条独立的“执行线程”'''&amp;lt;/span&amp;gt;。】&lt;br /&gt;
&lt;br /&gt;
Web 平台上存在以下类型的代理：&lt;br /&gt;
# '''Similar-origin window agent'''：即“同源窗口代理”，包含各种窗口对象，这些对象可以直接或通过使用 '''document.domain''' 相互访问。&lt;br /&gt;
#* &lt;br /&gt;
#* 两个“同源”的窗口对象可以位于不同的“Similar-origin window agent”中，例如，如果它们各自位于自己的浏览上下文组中。&lt;br /&gt;
# '''Dedicated worker agent'''：包含了一个 DedicatedWorkerGlobalScope；&lt;br /&gt;
# '''Shared worker agent'''：包含了一个 SharedWorkerGlobalScope；&lt;br /&gt;
# '''Service worker agent'''：包含了一个 ServiceWorkerGlobalScope；&lt;br /&gt;
# '''Worklet agent'''：包含了一个 WorkletGlobalScope 对象；&lt;br /&gt;
&lt;br /&gt;
== Event Loop&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt; ==&lt;br /&gt;
 要协调事件（event），用户交互（user interaction），脚本（script），渲染（rendering），网络（networking）等，用户代理必须使用本节中描述的事件循环。&lt;br /&gt;
&lt;br /&gt;
每个'''“代理”（Agent）'''有一个关联的“事件循环”，且该循环对该代理是'''唯一'''的。&lt;br /&gt;
# '''Similar-origin window agent''' 的事件循环称为“'''窗口事件循环'''”（'''window event loop'''）。&lt;br /&gt;
# '''Dedicated worker agent'''、'''Shared worker agent''' 或 '''Service worker agent''' 的事件循环称为“'''工作事件循环'''”（'''worker event loop'''）。&lt;br /&gt;
# '''Worklet agent''' 的事件循环称为“'''工件事件循环'''”（'''worklet event loop'''）。&lt;br /&gt;
&lt;br /&gt;
 Event loops do not necessarily correspond to implementation threads. For example, multiple window event loops could be cooperatively scheduled in a single thread.&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''事件循环不一定对应于“实现线程”（注：implementation threads，即“浏览器线程”）。例如，可以在单个线程中协同调度多个窗口事件循环。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 However, for the various worker agents that are allocated with &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; set to true, the JavaScript specification does place requirements on them regarding forward progress, which effectively amount to requiring dedicated per-agent threads in those cases.&lt;br /&gt;
 然而，对于 &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; 设置为 true 的各种 worker agents，JavaScript 规范确实对它们提出了关于“forward progress？”的要求，在这些情况下，这实际上相当于需要专用的每个代理线程。&lt;br /&gt;
&lt;br /&gt;
* 一个事件循环具有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个或多个“任务队列”（task queues）'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
** &amp;lt;q&amp;gt;'''任务队列是“集合”（set），而不是“队列”（queue）'''，因为事件循环处理模型从所选队列中获取第一个可运行的任务，而不是将第一个任务出列。&amp;lt;/q&amp;gt;&lt;br /&gt;
** &amp;lt;q&amp;gt;'''微任务队列（microtask queue）不是任务队列（task queues）'''。&amp;lt;/q&amp;gt;&lt;br /&gt;
* 每个事件循环都有一个当前“正在运行的任务”（currently running task），要么是一个任务，要么是 null。初始为空。&lt;br /&gt;
** 它用于处理可重入性。&lt;br /&gt;
* 每个事件循环都有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个“微任务队列”（microtask queue）'''&amp;lt;/span&amp;gt;，该队列是一个初始为空的微任务队列。&lt;br /&gt;
* 每个事件循环都有一个“正在执行微任务的检查点”（performing a microtask checkpoint）的布尔值。该值最初为 false。&lt;br /&gt;
** 它用于防止重入调用。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上次渲染机会时间”（last render opportunity time），最初设置为零。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上一个空闲周期的开始时间”（last idle period start time），最初设置为零。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 任务（Tasks） ===&lt;br /&gt;
“任务”（Tasks）包括以下几种：&lt;br /&gt;
# '''事件'''（Events）：在特定 EventTarget 对象上调度 Event 对象，通常由专用的任务完成。&lt;br /&gt;
# '''解析'''（Parsing）：HTML 解析器标记一个或多个字节，然后处理任何生成的标记，通常是一项任务。&lt;br /&gt;
# '''回调'''（Callbacks）：调用回调通常由一个专用的任务完成。&lt;br /&gt;
# '''使用资源'''（Using a resource）：当算法获取资源时，如果获取是以非阻塞的方式发生的，那么一旦部分或全部资源可用，就由任务执行对资源的处理。&lt;br /&gt;
# '''对 DOM 操作做出反应'''（Reacting to DOM manipulation）：一些元素具有响应 DOM 操作而触发的任务，例如：当该元素被插入到文档中时。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
从形式上讲，“任务”（Tasks）具有以下结构：&lt;br /&gt;
# 步骤（steps）：指定任务要完成的工作的一系列步骤。&lt;br /&gt;
# '''来源'''（source）：用于对相关任务进行分组和序列化。&lt;br /&gt;
# 文档（document）与任务关联的文档，对于不在“窗口事件循环”中的任务则为 null。&lt;br /&gt;
# 脚本评估环境设置对象集（A script evaluation environment settings object set）：用于跟踪任务期间的脚本评估。&lt;br /&gt;
根据其源字段（source），每个任务都被定义为来自特定的“任务源”（task source）。对于每个事件循环，每个“任务源”都必须与特定的“任务队列”相关联。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 通用任务源（task sources） ===&lt;br /&gt;
# '''DOM 操作任务源'''（The DOM manipulation task source）：用于对 DOM 操作做出反应的功能，例如在将元素插入文档时以非阻塞方式发生的事情。&lt;br /&gt;
# '''用户交互任务源'''（The user interaction task source）：用于对用户交互做出反应的功能，例如键盘或鼠标输入。&lt;br /&gt;
# '''网络任务源'''（The networking task source）：用于响应网络活动而触发的功能。&lt;br /&gt;
# '''导航和遍历任务源'''（The navigation and traversal task source）：用于对导航和历史遍历中涉及的任务进行排队。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''处理模型''' ===&lt;br /&gt;
只要事件循环存在，它就必须持续运行以下步骤：&lt;br /&gt;
# 让 oldestTask 和 taskStartTime 为 null。&lt;br /&gt;
# 如果事件循环有一个'''任务队列'''其中至少有一个可运行的任务，则：&lt;br /&gt;
## 由“实现”（浏览器）定义的规则，选择一个任务队列作为 taskQueue。（“微任务队列”并不是一个“任务队列”，所以不会被选择）——【“选择哪个任务队列”：由浏览器定义（即文档中的“implementation-defined”，客户端软件本身被称为一种“implementation”）决定，这就允许优先选择对性能敏感的任务】&lt;br /&gt;
## 将 taskStartTime 设置为“不安全的共享当前时间”。&lt;br /&gt;
## 将 oldestTask 设置为 taskQueue 中的'''第一个可运行任务'''，并将其从 taskQueue 中删除。——【任务队列是“set”，所以并非“出队”】&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置为 oldestTask。&lt;br /&gt;
## 执行 oldestTask 的步骤（Steps）。&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置回 null。&lt;br /&gt;
# '''执行微任务检查点'''：&lt;br /&gt;
## 如果事件循环的“正在执行微任务的检查点”为 true，则返回。——【检查重入】&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为 true。——【防止重入】&lt;br /&gt;
## 当事件循环的“微任务队列”不为空时：——【！！！'''不为空将一直重复执行'''！！！】&lt;br /&gt;
### 从事件循环的“微任务队列”中“出队”一个任务作为 oldestMicrotask。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置为 oldestMicrotask。&lt;br /&gt;
### 执行 oldestMicrotask。&lt;br /&gt;
###* 这可能涉及调用脚本的回调，并最终调用“clean up after running script”步骤，而该步骤的最后一步又将调用'''执行微任务检查点'''。这就是为什么设置“正在执行微任务的检查点”来防止“'''重入'''”。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置回null。&lt;br /&gt;
## 对于负责的事件循环为该事件循环的每个“环境设置对象”，通知该“环境设置对象”上 rejected 的 promise。&lt;br /&gt;
## 清理索引数据库事务。&lt;br /&gt;
## 执行 ClearKeptObjects()。&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为false。&lt;br /&gt;
# 将 hasARenderingOpportunity 设置为 false。&lt;br /&gt;
# 将现在时刻设置为“不安全的共享当前时间”。&lt;br /&gt;
# 如果 oldestTask 不为 null，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# '''更新渲染'''：如果这是一个窗口事件循环，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# ……（省略）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 总结 ===&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;&lt;br /&gt;
 当“调用栈”为空时（即，同步代码执行完毕时），“主线程”才会开始处理“（由 Event Loop 循环选取的）来自任务队列中的任务”。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 一次循环的顺序为：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务队列的“第一个可运行任务”（宏任务） -&amp;gt; 微任务队列的所有任务（微任务） -&amp;gt; 渲染'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 对于说法：“微任务 -&amp;gt; 渲染 -&amp;gt; 宏任务”，从代码运行结果来看似乎没问题，其实忽略了一点“'''script 脚本本身也是一个任务（宏任务）'''”。&lt;br /&gt;
&lt;br /&gt;
== 关于：Microtasks ==&lt;br /&gt;
&lt;br /&gt;
=== 到底什么是“Microtasks”？ ===&lt;br /&gt;
 无论是《ECMAScript® 2023 Language Specification》、《HTML Standard》、MDN，都没有找到关于“宏任务”、“微任务”的定义性描述。&lt;br /&gt;
 &lt;br /&gt;
 ——《ECMAScript® 2023 Language Specification》：压根就没提到 Microtasks 这个字&lt;br /&gt;
 &lt;br /&gt;
 ——《HTML Standard》：提到了 Microtask queuing：&lt;br /&gt;
     A microtask is a colloquial way of referring to a task that was created via the queue a microtask algorithm.&lt;br /&gt;
     微任务是一种口语化的方式，指的是通过“排队微任务算法”创建的任务。 ——【但文档中，与“任务”相比似乎只有“任务源”（task source）不同】&lt;br /&gt;
 &lt;br /&gt;
 —— MDN：只提到了“任务”（Tasks）与“微任务”（Microtasks）的区别&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 此外，在 Jake Archibald 的文章&amp;lt;ref&amp;gt;参考：[https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ 《Tasks, microtasks, queues and schedules》——Jake Archibald]&amp;lt;/ref&amp;gt;中提到：&lt;br /&gt;
     ECMAScript has the concept of &amp;quot;jobs&amp;quot; which are similar to microtasks, but the relationship isn't explicit aside from vague mailing list discussions. However, the general consensus is that promises should be part of the microtask queue, and for good reason.&lt;br /&gt;
     ECMAScript有类似于 microtasks 的“jobs”概念，但除了模糊的邮件列表讨论之外，这种关系并不明确。然而，普遍的共识是，promises 应该是 microtask queue 的一部分，这是有充分理由的。&lt;br /&gt;
     ……&lt;br /&gt;
     As mentioned, in ECMAScript land, they call microtasks &amp;quot;jobs&amp;quot;. In step 8.a of PerformPromiseThen, EnqueueJob is called to queue a microtask.&lt;br /&gt;
     如前所述，在 ECMAScript 领域，他们将微任务称为“jobs”。在 PerformPromiseThen 的步骤 8.a 中，调用 EnqueueJob 对 microtask 进行排队。&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 再此外，javascript.info 中有提到：&lt;br /&gt;
     Microtasks come solely from our code. They are usually created by promises……&amp;lt;ref&amp;gt;参考：[https://javascript.info/event-loop javascript.info：《Event loop: microtasks and macrotasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     微任务仅来自于我们的代码。它们通常是由 promise 创建的……&lt;br /&gt;
     &lt;br /&gt;
     Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue PromiseJobs, more often referred to as the “microtask queue” (V8 term).&amp;lt;ref&amp;gt;参考：[https://javascript.info/microtask-queue javascript.info：《Microtasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     异步任务需要适当的管理。为此，ECMA 标准规定了一个内部队列 PromiseJobs，通常被称为“微任务队列（microtask queue）”（V8 术语）。&lt;br /&gt;
&lt;br /&gt;
所以，Promise 异步任务（注意，仅仅是它的回调，而不是它本身）是 microtask 应该是“潜规则”了，此外，我们还可以使用“'''queueMicrotask()'''”方法来添加 microtask。&lt;br /&gt;
: ——【P.S. 对于 Node.js 并不清楚】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 为什么要支持“Microtasks”？&amp;lt;ref name=&amp;quot;MDN&amp;quot;/&amp;gt; ===&lt;br /&gt;
 微任务是另一种解决该问题的方案，通过将代码安排在下一次事件循环开始之前运行而不是必须要等到下一次开始之后才执行，这样可以&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''提供一个更好的访问级别'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 如何使用“Microtasks”？&amp;lt;ref&amp;gt;参考：&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide MDN：《在 JavaScript 中通过 queueMicrotask() 使用微任务》]&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/queueMicrotask MDN：《queueMicrotask()》]&lt;br /&gt;
# [https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing 《HTML Standard》：“Microtask queuing”]&lt;br /&gt;
&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
 '''Window''' 或 '''Worker''' 接口的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''queueMicrotask()'''&amp;lt;/span&amp;gt; 方法，将微任务加入队列以在控制返回浏览器的事件循环之前的安全时间执行。&lt;br /&gt;
&lt;br /&gt;
'''语法：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;queueMicrotask(() =&amp;gt; {/* ... */});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let callback = () =&amp;gt; log(&amp;quot;Regular timeout callback has run&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let urgentCallback = () =&amp;gt; log(&amp;quot;*** Oh noes! An urgent callback has run!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
log(&amp;quot;Main program started&amp;quot;);&lt;br /&gt;
setTimeout(callback, 0);&lt;br /&gt;
queueMicrotask(urgentCallback);&lt;br /&gt;
log(&amp;quot;Main program exiting&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Main program started&lt;br /&gt;
Main program exiting&lt;br /&gt;
*** Oh noes! An urgent callback has run!&lt;br /&gt;
Regular timeout callback has run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 关于 Node.js 中的 Event Loop，暂不了解，有时间再看看其他文章。&lt;br /&gt;
 &lt;br /&gt;
 参考：[https://juejin.cn/post/6844903764202094606 一次弄懂Event Loop（彻底解决此类面试问题）]&lt;br /&gt;
&lt;br /&gt;
 P.S.&lt;br /&gt;
 JavaScript 是没有一个 WebAPIs 结构的，网上文章图片展示的 WebAPIs 大概是指那些任务来自于 WebAPI，但是这种描述并不准确。&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''[[变量、词法作用域、闭包#一个有意思的例子 | 一个有意思的例子]]'''&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
== 写在后面 ==&lt;br /&gt;
 通过查询 EventLoop 的资料，前后沟通了许多内容，浅浅地做个梳理，以及一点点未解。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 首先，EventLoop 的资料集中在《HTML Standard》，而《ECMAScript® 2023 Language Specification》中并无只言片语，说明：'''EventLoop 并非 ECMAScript 语言的特性，而是 Web 相关规范'''。  ——【&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''即，EventLoop 并不由“JS 引擎”提供，而是依靠浏览器实现'''&amp;lt;/span&amp;gt; 】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 其次，Event Loop 提到了 ECMAScript 中的 Agent 概念：&lt;br /&gt;
 1、每个 Agent 都有且仅有一个关联的 Event Loop&lt;br /&gt;
 2、EventLoop 选取任务是交由 Agent 的“执行线程”（或者说：主线程）来执行&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 那么，问题来了&amp;lt;big&amp;gt;❓&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 1、Agent 与 浏览器的“渲染进程”是否有重叠呢？ —— 虽然《HTML Standard》描述 Agent 是一个“idealized &amp;quot;thread&amp;quot;”&lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 2、Agent 的“执行线程”是不是就是“渲染进程”的“JS 引擎线程”呢？ &lt;br /&gt;
     ——【我个人理解就是一个玩意儿（还有[https://developer.mozilla.org/zh-CN/docs/Glossary/Main_thread 《MDN：“主线程”》]），虽然概念不同】&lt;br /&gt;
 &lt;br /&gt;
 3、EventLoop 是由“渲染进程”中的某个线程实现吗？ &lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 网上并没有找到 Agent 相关的文章……&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6629</id>
		<title>Event Loop：事件循环</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=Event_Loop%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&amp;diff=6629"/>
		<updated>2023-04-17T23:22:42Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 在 MDN 上看到 JavaScript 的[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop 《并发模型与事件循环》]，但由于该页面内容过少，实在不变学习。&lt;br /&gt;
 &lt;br /&gt;
 而网络上搜到的内容大同小异，互相又有不小出入，难以拿捏。&lt;br /&gt;
 &lt;br /&gt;
 众所周知，JavaScript 是没有所谓源代码的“源代码”，所以这部分内容只能在“规范文件”中寻找了。&lt;br /&gt;
&lt;br /&gt;
* 以下内容参考《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;&amp;gt;参考：[https://html.spec.whatwg.org/multipage/webappapis.html#event-loops 《HTML Standard》：“Event loops”]&amp;lt;/ref&amp;gt;、MDN&amp;lt;ref name=&amp;quot;MDN&amp;quot;&amp;gt;参考：[https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&amp;lt;/ref&amp;gt;、与网络内容整理。&lt;br /&gt;
&lt;br /&gt;
== 前置知识 ==&lt;br /&gt;
 见：&amp;lt;big&amp;gt;'''[[浏览器基础：进程与线程]]'''&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 “一个 Tab 页面对应一个'''渲染进程'''”，而“渲染进程中只能存在一个 '''JS 引擎线程'''”（即，'''主线程'''），即：页面中的所有 JS 都由同一单线程运行。&lt;br /&gt;
&lt;br /&gt;
？？？？？？由于“渲染进程”负责了页面几乎所有的任务（事件、交互、脚本、渲染、网络），所以如何协调各个任务的执行是关键问题。&lt;br /&gt;
&lt;br /&gt;
[[File:浏览器的进程与线程.png|400px]]&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“任务” ===&lt;br /&gt;
 JavaScript中，“任务”被分为两种：“同步任务”，“异步任务”。“异步任务”（Task）：又分为“宏任务”（MacroTask）与“微任务”（MicroTask）。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 是针对“异步任务”而言。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ——【'''P.S. 《HTML Standard》中已经不再有“宏任务”（MacroTask）这一说法 —— 它就是“任务”（task）'''】&lt;br /&gt;
&lt;br /&gt;
# 同步任务：在“主线程”上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务。&lt;br /&gt;
# 异步任务：不直接进入“主线程”，而进入“任务队列”（task queue）的任务。&lt;br /&gt;
## '''任务（task）'''：事件、解析、回调、使用资源、对 DOM 操作做出反应 ——【根据《HTML Standard》&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt;中定义】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''script(整体代码)、setTimeout、setInterval、setImmediate（node独有）、requestAnimationFrame(浏览器独有)、I/O、UI rendering'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，只有“已经处于 task queues 中”的任务才会被执行'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 setTimeout 引起的无限循环，会导致性能下降，但是很难导致直接崩溃】&lt;br /&gt;
## '''微任务（microtask）'''：——【暂无明确定义，见：[[#到底什么是“Microtasks”？]]】&lt;br /&gt;
##* 包括：&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''Promises 的回调、queueMicrotask()、process.nextTick（node独有）、Object.observe(废弃)、MutationObserver'''&amp;lt;/span&amp;gt;&lt;br /&gt;
##* 注意：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''Event Loop 开始时，“microtask queue 中的所有”任务会被执行（哪怕是中途添加的“microtask”），直到队列为空'''。&amp;lt;/span&amp;gt; &lt;br /&gt;
##*: ——【所以，如果一个 Promises 引起无限循环，将直接导致崩溃。这也是为什么要求'''代码慎用“queueMicrotask()”'''】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;一点小小的猜测：&lt;br /&gt;
 &lt;br /&gt;
     来源于“渲染进程”中其他线程（非“JS 引擎线程”）引起的异步任务，即“任务（task）”。&lt;br /&gt;
     &lt;br /&gt;
     来源于“渲染进程”的“JS 引擎线程”引起的异步任务，即“微任务（microtask）”。&lt;br /&gt;
&lt;br /&gt;
=== JavaScript的“运行时”&amp;lt;ref&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
To run JavaScript code, the runtime engine maintains a set of agents in which to execute JavaScript code. Each agent is made up of a set of execution contexts, the execution context stack, a main thread, a set for any additional threads that may be created to handle workers, a task queue, and a microtask queue. Other than the main thread—which some browsers share across multiple agents—each component of an agent is unique to that agent.&lt;br /&gt;
&lt;br /&gt;
在执行 JavaScript 代码的时候，JavaScript 运行时实际上维护了一组用于执行 JavaScript 代码的代理。每个代理由一组执行上下文的集合、执行上下文栈、主线程、一组可能创建用于执行 worker 的额外的线程集合、一个任务队列以及一个微任务队列构成。除了主线程（某些浏览器在多个代理之间共享的主线程）之外，其他组成部分对该代理都是唯一的。 &lt;br /&gt;
&lt;br /&gt;
——MDN：《深入：微任务与 Javascript 运行时环境》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
An agent comprises a set of ECMAScript execution contexts, an execution context stack, a running execution context, an Agent Record, and an executing thread. Except for the executing thread, the constituents of an agent belong exclusively to that agent.&lt;br /&gt;
&lt;br /&gt;
“代理”（Agent）包括：一组ECMAScript执行上下文、执行上下文堆栈、运行的执行上下文、代理记录和执行线程。除了执行线程之外，代理的组成部分只属于该代理。 &lt;br /&gt;
&lt;br /&gt;
——《ECMAScript® 2023 Language Specification》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Conceptually, the agent concept is an architecture-independent, idealized &amp;quot;thread&amp;quot; in which JavaScript code runs. Such code can involve multiple globals/realms that can synchronously access each other, and thus needs to run in a single execution thread.&lt;br /&gt;
&lt;br /&gt;
从概念上讲，代理概念是一个独立于体系结构、理想化的“线程”，JavaScript代码在其中运行。这样的代码可能涉及多个全局/领域，这些全局/领域可以同步访问彼此，因此需要在单个执行线程中运行。&lt;br /&gt;
&lt;br /&gt;
——《HTML Standard》&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
:: 参考：&lt;br /&gt;
::# [https://tc39.es/ecma262/#sec-agents 《ECMAScript® 2023 Language Specification》：“Agents”]&lt;br /&gt;
::# [https://html.spec.whatwg.org/multipage/webappapis.html#agents-and-agent-clusters 《HTML Standard》：“Agents and agent clusters”]&lt;br /&gt;
::# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth MDN：《深入：微任务与 Javascript 运行时环境》]&lt;br /&gt;
::# [https://github.com/Lawliet01/everyone-can-read-spec/blob/main/8.execution-environment.md 【人人都能读标准】8.可视化JavaScript的运行环境：agents、执行上下文、Realm]&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
 从概念上讲，&amp;lt;big&amp;gt;&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''代理（Agent）'''&amp;lt;/span&amp;gt;&amp;lt;/big&amp;gt; 是一个独立于体系结构、理想化的“线程”，每个 ECMAScript 程序都必须在其中运行。&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''代理是一种规范机制，不需要与任何特定的 ECMAScript 实现部件相对应。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agent 包括了：&lt;br /&gt;
# '''一组执行上下文（a set of execution contexts）'''：即，一组可执行、待执行的上下文&lt;br /&gt;
# '''执行上下文栈（the execution context stack）'''：在一些文章中叫做“'''调用栈（call stack）'''”&lt;br /&gt;
#* 栈顶的那个上下文被称为“运行中的执行上下文（running execution context）”&lt;br /&gt;
# '''执行线程（an executing thread）'''：在一些文章中叫做“'''主线程（a main thread）'''”&lt;br /&gt;
# '''事件循环（event loop）'''：&lt;br /&gt;
#* 它包括了：一个“微任务队列（microtask queue）”，一个/多个“任务队列（task queue）”&lt;br /&gt;
# '''代理记录（Agent Record）'''：？？？&lt;br /&gt;
&lt;br /&gt;
* 一个宿主（浏览器、Node.js）可以有多个 Agent，Agent 之间相互隔离，可以通过发送消息进行通信。&lt;br /&gt;
* 当两个 Agent 同处一个“Agent Clusters”（代理集群）时，它们可以共享内存。&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''除了“执行线程”（主线程）、“事件循环”之外，代理的组成部分只属于该代理。'''&amp;lt;/span&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
     “执行线程”（主线程）：某些浏览器在多个代理之间共享主线程&lt;br /&gt;
     &lt;br /&gt;
     “事件循环”：可以在单个线程中协同调度多个窗口事件循环 —— 见：[[#Event Loop]]&lt;br /&gt;
 &lt;br /&gt;
 ——【《ECMAScript® 2023 Language Specification》、MDN 只提到：“执行线程”并不一定由“Agent”独占。但从《HTML Standard》对“Event Loop”的表述来看，似乎也并不一定由“Agent”独占】&lt;br /&gt;
 &lt;br /&gt;
 ——【尽管标准提到，不同的“Agent”允许共享同一条“执行线程”，但&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''现代浏览器基本上都是给每个“Agent”启用一条独立的“执行线程”'''&amp;lt;/span&amp;gt;。】&lt;br /&gt;
&lt;br /&gt;
Web 平台上存在以下类型的代理：&lt;br /&gt;
# '''Similar-origin window agent'''：即“同源窗口代理”，包含各种窗口对象，这些对象可以直接或通过使用 '''document.domain''' 相互访问。&lt;br /&gt;
#* &lt;br /&gt;
#* 两个“同源”的窗口对象可以位于不同的“Similar-origin window agent”中，例如，如果它们各自位于自己的浏览上下文组中。&lt;br /&gt;
# '''Dedicated worker agent'''：包含了一个 DedicatedWorkerGlobalScope；&lt;br /&gt;
# '''Shared worker agent'''：包含了一个 SharedWorkerGlobalScope；&lt;br /&gt;
# '''Service worker agent'''：包含了一个 ServiceWorkerGlobalScope；&lt;br /&gt;
# '''Worklet agent'''：包含了一个 WorkletGlobalScope 对象；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Event Loop&amp;lt;ref name=&amp;quot;HTML-Standard&amp;quot;/&amp;gt; ==&lt;br /&gt;
 要协调事件（event），用户交互（user interaction），脚本（script），渲染（rendering），网络（networking）等，用户代理必须使用本节中描述的事件循环。&lt;br /&gt;
&lt;br /&gt;
每个'''“代理”（Agent）'''有一个关联的“事件循环”，且该循环对该代理是'''唯一'''的。&lt;br /&gt;
# '''Similar-origin window agent''' 的事件循环称为“'''窗口事件循环'''”（'''window event loop'''）。&lt;br /&gt;
# '''Dedicated worker agent'''、'''Shared worker agent''' 或 '''Service worker agent''' 的事件循环称为“'''工作事件循环'''”（'''worker event loop'''）。&lt;br /&gt;
# '''Worklet agent''' 的事件循环称为“'''工件事件循环'''”（'''worklet event loop'''）。&lt;br /&gt;
&lt;br /&gt;
 Event loops do not necessarily correspond to implementation threads. For example, multiple window event loops could be cooperatively scheduled in a single thread.&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''事件循环不一定对应于“实现线程”（注：implementation threads，即“浏览器线程”）。例如，可以在单个线程中协同调度多个窗口事件循环。'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 However, for the various worker agents that are allocated with &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; set to true, the JavaScript specification does place requirements on them regarding forward progress, which effectively amount to requiring dedicated per-agent threads in those cases.&lt;br /&gt;
 然而，对于 &amp;lt;nowiki&amp;gt;[[CanBlock]]&amp;lt;/nowiki&amp;gt; 设置为 true 的各种 worker agents，JavaScript 规范确实对它们提出了关于“forward progress？”的要求，在这些情况下，这实际上相当于需要专用的每个代理线程。&lt;br /&gt;
&lt;br /&gt;
* 一个事件循环具有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个或多个“任务队列”（task queues）'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
** &amp;lt;q&amp;gt;'''任务队列是“集合”（set），而不是“队列”（queue）'''，因为事件循环处理模型从所选队列中获取第一个可运行的任务，而不是将第一个任务出列。&amp;lt;/q&amp;gt;&lt;br /&gt;
** &amp;lt;q&amp;gt;'''微任务队列（microtask queue）不是任务队列（task queues）'''。&amp;lt;/q&amp;gt;&lt;br /&gt;
* 每个事件循环都有一个当前“正在运行的任务”（currently running task），要么是一个任务，要么是 null。初始为空。&lt;br /&gt;
** 它用于处理可重入性。&lt;br /&gt;
* 每个事件循环都有&amp;lt;span style=&amp;quot;color: Green&amp;quot;&amp;gt;'''一个“微任务队列”（microtask queue）'''&amp;lt;/span&amp;gt;，该队列是一个初始为空的微任务队列。&lt;br /&gt;
* 每个事件循环都有一个“正在执行微任务的检查点”（performing a microtask checkpoint）的布尔值。该值最初为 false。&lt;br /&gt;
** 它用于防止重入调用。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上次渲染机会时间”（last render opportunity time），最初设置为零。&lt;br /&gt;
* 每个窗口事件循环都有一个 DOMHighResTimeStamp 表示“上一个空闲周期的开始时间”（last idle period start time），最初设置为零。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 任务（Tasks） ===&lt;br /&gt;
“任务”（Tasks）包括以下几种：&lt;br /&gt;
# '''事件'''（Events）：在特定 EventTarget 对象上调度 Event 对象，通常由专用的任务完成。&lt;br /&gt;
# '''解析'''（Parsing）：HTML 解析器标记一个或多个字节，然后处理任何生成的标记，通常是一项任务。&lt;br /&gt;
# '''回调'''（Callbacks）：调用回调通常由一个专用的任务完成。&lt;br /&gt;
# '''使用资源'''（Using a resource）：当算法获取资源时，如果获取是以非阻塞的方式发生的，那么一旦部分或全部资源可用，就由任务执行对资源的处理。&lt;br /&gt;
# '''对 DOM 操作做出反应'''（Reacting to DOM manipulation）：一些元素具有响应 DOM 操作而触发的任务，例如：当该元素被插入到文档中时。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
从形式上讲，“任务”（Tasks）具有以下结构：&lt;br /&gt;
# 步骤（steps）：指定任务要完成的工作的一系列步骤。&lt;br /&gt;
# '''来源'''（source）：用于对相关任务进行分组和序列化。&lt;br /&gt;
# 文档（document）与任务关联的文档，对于不在“窗口事件循环”中的任务则为 null。&lt;br /&gt;
# 脚本评估环境设置对象集（A script evaluation environment settings object set）：用于跟踪任务期间的脚本评估。&lt;br /&gt;
根据其源字段（source），每个任务都被定义为来自特定的“任务源”（task source）。对于每个事件循环，每个“任务源”都必须与特定的“任务队列”相关联。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 通用任务源（task sources） ===&lt;br /&gt;
# '''DOM 操作任务源'''（The DOM manipulation task source）：用于对 DOM 操作做出反应的功能，例如在将元素插入文档时以非阻塞方式发生的事情。&lt;br /&gt;
# '''用户交互任务源'''（The user interaction task source）：用于对用户交互做出反应的功能，例如键盘或鼠标输入。&lt;br /&gt;
# '''网络任务源'''（The networking task source）：用于响应网络活动而触发的功能。&lt;br /&gt;
# '''导航和遍历任务源'''（The navigation and traversal task source）：用于对导航和历史遍历中涉及的任务进行排队。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''处理模型''' ===&lt;br /&gt;
只要事件循环存在，它就必须持续运行以下步骤：&lt;br /&gt;
# 让 oldestTask 和 taskStartTime 为 null。&lt;br /&gt;
# 如果事件循环有一个'''任务队列'''其中至少有一个可运行的任务，则：&lt;br /&gt;
## 由“实现”（浏览器）定义的规则，选择一个任务队列作为 taskQueue。（“微任务队列”并不是一个“任务队列”，所以不会被选择）——【“选择哪个任务队列”：由浏览器定义（即文档中的“implementation-defined”，客户端软件本身被称为一种“implementation”）决定，这就允许优先选择对性能敏感的任务】&lt;br /&gt;
## 将 taskStartTime 设置为“不安全的共享当前时间”。&lt;br /&gt;
## 将 oldestTask 设置为 taskQueue 中的'''第一个可运行任务'''，并将其从 taskQueue 中删除。——【任务队列是“set”，所以并非“出队”】&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置为 oldestTask。&lt;br /&gt;
## 执行 oldestTask 的步骤（Steps）。&lt;br /&gt;
## 将事件循环的“正在运行的任务”设置回 null。&lt;br /&gt;
# '''执行微任务检查点'''：&lt;br /&gt;
## 如果事件循环的“正在执行微任务的检查点”为 true，则返回。——【检查重入】&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为 true。——【防止重入】&lt;br /&gt;
## 当事件循环的“微任务队列”不为空时：——【！！！'''不为空将一直重复执行'''！！！】&lt;br /&gt;
### 从事件循环的“微任务队列”中“出队”一个任务作为 oldestMicrotask。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置为 oldestMicrotask。&lt;br /&gt;
### 执行 oldestMicrotask。&lt;br /&gt;
###* 这可能涉及调用脚本的回调，并最终调用“clean up after running script”步骤，而该步骤的最后一步又将调用'''执行微任务检查点'''。这就是为什么设置“正在执行微任务的检查点”来防止“'''重入'''”。&lt;br /&gt;
### 将事件循环的“正在运行的任务”设置回null。&lt;br /&gt;
## 对于负责的事件循环为该事件循环的每个“环境设置对象”，通知该“环境设置对象”上 rejected 的 promise。&lt;br /&gt;
## 清理索引数据库事务。&lt;br /&gt;
## 执行 ClearKeptObjects()。&lt;br /&gt;
## 将事件循环的“正在执行微任务的检查点”设置为false。&lt;br /&gt;
# 将 hasARenderingOpportunity 设置为 false。&lt;br /&gt;
# 将现在时刻设置为“不安全的共享当前时间”。&lt;br /&gt;
# 如果 oldestTask 不为 null，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# '''更新渲染'''：如果这是一个窗口事件循环，则：&lt;br /&gt;
## ……（省略）&lt;br /&gt;
# ……（省略）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 总结 ===&lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;&lt;br /&gt;
 当“调用栈”为空时（即，同步代码执行完毕时），“主线程”才会开始处理“（由 Event Loop 循环选取的）来自任务队列中的任务”。&lt;br /&gt;
 &lt;br /&gt;
 Event Loop 一次循环的顺序为：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''任务队列的“第一个可运行任务”（宏任务） -&amp;gt; 微任务队列的所有任务（微任务） -&amp;gt; 渲染'''&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 对于说法：“微任务 -&amp;gt; 渲染 -&amp;gt; 宏任务”，从代码运行结果来看似乎没问题，其实忽略了一点“'''script 脚本本身也是一个任务（宏任务）'''”。&lt;br /&gt;
&lt;br /&gt;
== 关于：Microtasks ==&lt;br /&gt;
&lt;br /&gt;
=== 到底什么是“Microtasks”？ ===&lt;br /&gt;
 无论是《ECMAScript® 2023 Language Specification》、《HTML Standard》、MDN，都没有找到关于“宏任务”、“微任务”的定义性描述。&lt;br /&gt;
 &lt;br /&gt;
 ——《ECMAScript® 2023 Language Specification》：压根就没提到 Microtasks 这个字&lt;br /&gt;
 &lt;br /&gt;
 ——《HTML Standard》：提到了 Microtask queuing：&lt;br /&gt;
     A microtask is a colloquial way of referring to a task that was created via the queue a microtask algorithm.&lt;br /&gt;
     微任务是一种口语化的方式，指的是通过“排队微任务算法”创建的任务。 ——【但文档中，与“任务”相比似乎只有“任务源”（task source）不同】&lt;br /&gt;
 &lt;br /&gt;
 —— MDN：只提到了“任务”（Tasks）与“微任务”（Microtasks）的区别&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 此外，在 Jake Archibald 的文章&amp;lt;ref&amp;gt;参考：[https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ 《Tasks, microtasks, queues and schedules》——Jake Archibald]&amp;lt;/ref&amp;gt;中提到：&lt;br /&gt;
     ECMAScript has the concept of &amp;quot;jobs&amp;quot; which are similar to microtasks, but the relationship isn't explicit aside from vague mailing list discussions. However, the general consensus is that promises should be part of the microtask queue, and for good reason.&lt;br /&gt;
     ECMAScript有类似于 microtasks 的“jobs”概念，但除了模糊的邮件列表讨论之外，这种关系并不明确。然而，普遍的共识是，promises 应该是 microtask queue 的一部分，这是有充分理由的。&lt;br /&gt;
     ……&lt;br /&gt;
     As mentioned, in ECMAScript land, they call microtasks &amp;quot;jobs&amp;quot;. In step 8.a of PerformPromiseThen, EnqueueJob is called to queue a microtask.&lt;br /&gt;
     如前所述，在 ECMAScript 领域，他们将微任务称为“jobs”。在 PerformPromiseThen 的步骤 8.a 中，调用 EnqueueJob 对 microtask 进行排队。&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 再此外，javascript.info 中有提到：&lt;br /&gt;
     Microtasks come solely from our code. They are usually created by promises……&amp;lt;ref&amp;gt;参考：[https://javascript.info/event-loop javascript.info：《Event loop: microtasks and macrotasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     微任务仅来自于我们的代码。它们通常是由 promise 创建的……&lt;br /&gt;
     &lt;br /&gt;
     Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue PromiseJobs, more often referred to as the “microtask queue” (V8 term).&amp;lt;ref&amp;gt;参考：[https://javascript.info/microtask-queue javascript.info：《Microtasks》]&amp;lt;/ref&amp;gt;&lt;br /&gt;
     异步任务需要适当的管理。为此，ECMA 标准规定了一个内部队列 PromiseJobs，通常被称为“微任务队列（microtask queue）”（V8 术语）。&lt;br /&gt;
&lt;br /&gt;
所以，Promise 异步任务（注意，仅仅是它的回调，而不是它本身）是 microtask 应该是“潜规则”了，此外，我们还可以使用“'''queueMicrotask()'''”方法来添加 microtask。&lt;br /&gt;
: ——【P.S. 对于 Node.js 并不清楚】&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 为什么要支持“Microtasks”？&amp;lt;ref name=&amp;quot;MDN&amp;quot;/&amp;gt; ===&lt;br /&gt;
 微任务是另一种解决该问题的方案，通过将代码安排在下一次事件循环开始之前运行而不是必须要等到下一次开始之后才执行，这样可以&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;'''提供一个更好的访问级别'''&amp;lt;/span&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 如何使用“Microtasks”？&amp;lt;ref&amp;gt;参考：&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_DOM_API/Microtask_guide MDN：《在 JavaScript 中通过 queueMicrotask() 使用微任务》]&lt;br /&gt;
# [https://developer.mozilla.org/zh-CN/docs/Web/API/queueMicrotask MDN：《queueMicrotask()》]&lt;br /&gt;
# [https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing 《HTML Standard》：“Microtask queuing”]&lt;br /&gt;
&amp;lt;/ref&amp;gt; ===&lt;br /&gt;
 '''Window''' 或 '''Worker''' 接口的 &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''queueMicrotask()'''&amp;lt;/span&amp;gt; 方法，将微任务加入队列以在控制返回浏览器的事件循环之前的安全时间执行。&lt;br /&gt;
&lt;br /&gt;
'''语法：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot;&amp;gt;queueMicrotask(() =&amp;gt; {/* ... */});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''示例：'''&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let callback = () =&amp;gt; log(&amp;quot;Regular timeout callback has run&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let urgentCallback = () =&amp;gt; log(&amp;quot;*** Oh noes! An urgent callback has run!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
log(&amp;quot;Main program started&amp;quot;);&lt;br /&gt;
setTimeout(callback, 0);&lt;br /&gt;
queueMicrotask(urgentCallback);&lt;br /&gt;
log(&amp;quot;Main program exiting&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: 输出：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
Main program started&lt;br /&gt;
Main program exiting&lt;br /&gt;
*** Oh noes! An urgent callback has run!&lt;br /&gt;
Regular timeout callback has run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 关于 Node.js 中的 Event Loop，暂不了解，有时间再看看其他文章。&lt;br /&gt;
 &lt;br /&gt;
 参考：[https://juejin.cn/post/6844903764202094606 一次弄懂Event Loop（彻底解决此类面试问题）]&lt;br /&gt;
&lt;br /&gt;
 P.S.&lt;br /&gt;
 JavaScript 是没有一个 WebAPIs 结构的，网上文章图片展示的 WebAPIs 大概是指那些任务来自于 WebAPI，但是这种描述并不准确。&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''[[变量、词法作用域、闭包#一个有意思的例子 | 一个有意思的例子]]'''&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
== 写在后面 ==&lt;br /&gt;
 通过查询 EventLoop 的资料，前后沟通了许多内容，浅浅地做个梳理，以及一点点未解。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 首先，EventLoop 的资料集中在《HTML Standard》，而《ECMAScript® 2023 Language Specification》中并无只言片语，说明：'''EventLoop 并非 ECMAScript 语言的特性，而是 Web 相关规范'''。  ——【&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''即，EventLoop 并不由“JS 引擎”提供，而是依靠浏览器实现'''&amp;lt;/span&amp;gt; 】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 其次，Event Loop 提到了 ECMAScript 中的 Agent 概念：&lt;br /&gt;
 1、每个 Agent 都有且仅有一个关联的 Event Loop&lt;br /&gt;
 2、EventLoop 选取任务是交由 Agent 的“执行线程”（或者说：主线程）来执行&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 那么，问题来了&amp;lt;big&amp;gt;❓&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 1、Agent 与 浏览器的“渲染进程”是否有重叠呢？ —— 虽然《HTML Standard》描述 Agent 是一个“idealized &amp;quot;thread&amp;quot;”&lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 2、Agent 的“执行线程”是不是就是“渲染进程”的“JS 引擎线程”呢？ &lt;br /&gt;
     ——【我个人理解就是一个玩意儿（还有[https://developer.mozilla.org/zh-CN/docs/Glossary/Main_thread 《MDN：“主线程”》]），虽然概念不同】&lt;br /&gt;
 &lt;br /&gt;
 3、EventLoop 是由“渲染进程”中的某个线程实现吗？ &lt;br /&gt;
     ——【？？？】&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 网上并没有找到 Agent 相关的文章……&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6628</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6628"/>
		<updated>2023-04-17T23:21:52Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 执行上下文（Execution Contexts） */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
 ''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪 ECMAScript 实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 生成器（Generator） || 此执行上下文正在评估的 Generator 对象。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 10;&lt;br /&gt;
const b = 20;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(d, e) {&lt;br /&gt;
  var f = 50;&lt;br /&gt;
  return d * e * f * a;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(30, 40);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: 50&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 函数中使用了&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;&amp;lt;abbr title=&amp;quot;跨作用域的变量&amp;quot;&amp;gt;'''自由变量'''&amp;lt;/abbr&amp;gt;&amp;lt;/span&amp;gt;（“a”），将通过其“'''外部词法环境引用'''”（到“GlobalLexicalEnvironment”中）查找&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 600000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
注意：部分文章表述的是旧版本的 ES：&lt;br /&gt;
# [https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0 《Understanding Execution Context and Execution Stack in Javascript》]&lt;br /&gt;
#: [https://juejin.cn/post/7129510217863299102 《ES2018 最新 【译】理解Javascript中的执行上下文和执行栈》] —— 比较完善，列出了 ES 不同版本的变化&lt;br /&gt;
#: [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》] —— 不太准确&lt;br /&gt;
# [https://juejin.cn/post/6844903733495595016 《深入JavaScript系列（一）：词法环境》]&lt;br /&gt;
# [https://juejin.cn/post/7118721446615973896 《JavaScript筑基（三）：环境记录》]&lt;br /&gt;
# [https://limeii.github.io/2019/05/js-lexical-environment/ 《JS：深入理解JavaScript-词法环境》] —— 案例不错&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6627</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6627"/>
		<updated>2023-04-17T23:16:30Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 状态组件（State Components） */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪ECMAScript实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 生成器（Generator） || 此执行上下文正在评估的 Generator 对象。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 10;&lt;br /&gt;
const b = 20;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(d, e) {&lt;br /&gt;
  var f = 50;&lt;br /&gt;
  return d * e * f * a;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(30, 40);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: 50&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 函数中使用了&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;&amp;lt;abbr title=&amp;quot;跨作用域的变量&amp;quot;&amp;gt;'''自由变量'''&amp;lt;/abbr&amp;gt;&amp;lt;/span&amp;gt;（“a”），将通过其“'''外部词法环境引用'''”（到“GlobalLexicalEnvironment”中）查找&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 600000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
注意：部分文章表述的是旧版本的 ES：&lt;br /&gt;
# [https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0 《Understanding Execution Context and Execution Stack in Javascript》]&lt;br /&gt;
#: [https://juejin.cn/post/7129510217863299102 《ES2018 最新 【译】理解Javascript中的执行上下文和执行栈》] —— 比较完善，列出了 ES 不同版本的变化&lt;br /&gt;
#: [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》] —— 不太准确&lt;br /&gt;
# [https://juejin.cn/post/6844903733495595016 《深入JavaScript系列（一）：词法环境》]&lt;br /&gt;
# [https://juejin.cn/post/7118721446615973896 《JavaScript筑基（三）：环境记录》]&lt;br /&gt;
# [https://limeii.github.io/2019/05/js-lexical-environment/ 《JS：深入理解JavaScript-词法环境》] —— 案例不错&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6626</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6626"/>
		<updated>2023-04-17T23:12:50Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 案例分析 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪ECMAScript实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 10;&lt;br /&gt;
const b = 20;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(d, e) {&lt;br /&gt;
  var f = 50;&lt;br /&gt;
  return d * e * f * a;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(30, 40);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境”、“变量环境”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 30, 1: 40, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            f: 50&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* 函数中使用了&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;&amp;lt;abbr title=&amp;quot;跨作用域的变量&amp;quot;&amp;gt;'''自由变量'''&amp;lt;/abbr&amp;gt;&amp;lt;/span&amp;gt;（“a”），将通过其“'''外部词法环境引用'''”（到“GlobalLexicalEnvironment”中）查找&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 10,&lt;br /&gt;
            b: 20,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 600000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
注意：部分文章表述的是旧版本的 ES：&lt;br /&gt;
# [https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0 《Understanding Execution Context and Execution Stack in Javascript》]&lt;br /&gt;
#: [https://juejin.cn/post/7129510217863299102 《ES2018 最新 【译】理解Javascript中的执行上下文和执行栈》] —— 比较完善，列出了 ES 不同版本的变化&lt;br /&gt;
#: [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》] —— 不太准确&lt;br /&gt;
# [https://juejin.cn/post/6844903733495595016 《深入JavaScript系列（一）：词法环境》]&lt;br /&gt;
# [https://juejin.cn/post/7118721446615973896 《JavaScript筑基（三）：环境记录》]&lt;br /&gt;
# [https://limeii.github.io/2019/05/js-lexical-environment/ 《JS：深入理解JavaScript-词法环境》] —— 案例不错&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6625</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6625"/>
		<updated>2023-04-17T22:56:09Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 网络文章 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪ECMAScript实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 20;&lt;br /&gt;
const b = 30;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(e, f) {&lt;br /&gt;
  var g = 20;&lt;br /&gt;
  return e * f * g;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(20, 30);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: 20&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 12000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
注意：部分文章表述的是旧版本的 ES：&lt;br /&gt;
# [https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0 《Understanding Execution Context and Execution Stack in Javascript》]&lt;br /&gt;
#: [https://juejin.cn/post/7129510217863299102 《ES2018 最新 【译】理解Javascript中的执行上下文和执行栈》] —— 比较完善，列出了 ES 不同版本的变化&lt;br /&gt;
#: [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》] —— 不太准确&lt;br /&gt;
# [https://juejin.cn/post/6844903733495595016 《深入JavaScript系列（一）：词法环境》]&lt;br /&gt;
# [https://juejin.cn/post/7118721446615973896 《JavaScript筑基（三）：环境记录》]&lt;br /&gt;
# [https://limeii.github.io/2019/05/js-lexical-environment/ 《JS：深入理解JavaScript-词法环境》] —— 案例不错&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6624</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6624"/>
		<updated>2023-04-17T22:51:51Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 网络文章 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪ECMAScript实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 20;&lt;br /&gt;
const b = 30;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(e, f) {&lt;br /&gt;
  var g = 20;&lt;br /&gt;
  return e * f * g;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(20, 30);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: 20&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 12000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
注意：部分文章表述的是旧版本的 ES：&lt;br /&gt;
# [https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0 《Understanding Execution Context and Execution Stack in Javascript》]&lt;br /&gt;
#: [https://juejin.cn/post/7129510217863299102 《ES2018 最新 【译】理解Javascript中的执行上下文和执行栈》] —— 比较完善，列出了 ES 不同版本的变化&lt;br /&gt;
#: [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》] —— 不太准确&lt;br /&gt;
# [https://juejin.cn/post/6844903733495595016 《深入JavaScript系列（一）：词法环境》]&lt;br /&gt;
# [https://juejin.cn/post/7118721446615973896 《JavaScript筑基（三）：环境记录》]&lt;br /&gt;
# [https://limeii.github.io/2019/05/js-lexical-environment/ 《JS：深入理解JavaScript-词法环境》]&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6623</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6623"/>
		<updated>2023-04-17T22:40:21Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* ECMAScript */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪ECMAScript实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 20;&lt;br /&gt;
const b = 30;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(e, f) {&lt;br /&gt;
  var g = 20;&lt;br /&gt;
  return e * f * g;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(20, 30);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: 20&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 12000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function declarations'''。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
# [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》]&lt;br /&gt;
# [https://juejin.cn/post/6945240902625394718 《你真的了解执行上下文吗？》]&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6622</id>
		<title>JS 执行过程：执行上下文、词法环境</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=JS_%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%9A%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%81%E8%AF%8D%E6%B3%95%E7%8E%AF%E5%A2%83&amp;diff=6622"/>
		<updated>2023-04-17T22:39:11Z</updated>

		<summary type="html">&lt;p&gt;Eijux：​/* 环境记录（Environment Record） */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:JavaScript]]&lt;br /&gt;
&lt;br /&gt;
== 执行上下文（Execution Contexts） ==&lt;br /&gt;
''' &amp;lt;big&amp;gt;执行上下文&amp;lt;/big&amp;gt;（Execution Contexts）'''：是一种规范设备，用于跟踪ECMAScript实现对代码的运行时评估 —— JavaScript 代码都需要运行在相应的“执行上下文”中&lt;br /&gt;
&lt;br /&gt;
执行上下文一共有三种类型：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局执行上下文'''&amp;lt;/span&amp;gt;：基础的上下文，任何不在函数内部的代码都在其中。&lt;br /&gt;
#: 它会执行两件事：创建一个全局的 window 对象（浏览器的情况下），并且设置 this 的值等于这个全局对象。&lt;br /&gt;
#* 程序首次允许时创建 —— '''一个程序中只会有一个全局执行上下文'''。&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''函数执行上下文'''&amp;lt;/span&amp;gt;：函数内部的代码所在的上下文。&lt;br /&gt;
#* 每次函数被调用都会创建一个新的执行上下文 —— '''同一函数的多次执行，会多个上下文'''&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''eval执行上下文'''&amp;lt;/span&amp;gt;：eval() 内部的代码所在的执行上下文&lt;br /&gt;
#* 使用“eval方法”时创建&lt;br /&gt;
&lt;br /&gt;
 在任何时间点，最多有一个“执行上下文”在实际执行代码，这被称为“正在运行的执行上下文”（running execution context）。&lt;br /&gt;
&lt;br /&gt;
=== 执行上下文栈 ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;执行上下文栈&amp;lt;/big&amp;gt;（Execution context stack，ECS）'''：又称“调用栈 / 执行栈”（call stack），用于跟踪“执行上下文” —— “正在运行的执行上下文”就是这个其的栈顶元素&lt;br /&gt;
&lt;br /&gt;
函数的“执行过程”就是：对应的“执行上下文”（栈帧）在“调用栈”中的“'''入栈'''”（开始执行）、“'''出栈'''”（执行完毕）操作。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 'Hello World!';&lt;br /&gt;
function first() {&lt;br /&gt;
  console.log('Inside first function');&lt;br /&gt;
  second();&lt;br /&gt;
  console.log('Again inside first function');&lt;br /&gt;
}&lt;br /&gt;
function second() {&lt;br /&gt;
  console.log('Inside second function');&lt;br /&gt;
}&lt;br /&gt;
first();&lt;br /&gt;
console.log('Inside Global Execution Context');&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: [[File:JavaScript：执行上下文栈（Execution context stack，ECS）：示例.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== 状态组件（State Components） ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|+ 执行上下文的状态组件&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | &amp;lt;big&amp;gt;组件（Component）&amp;lt;/big&amp;gt;&lt;br /&gt;
! style=&amp;quot;width:80%;&amp;quot; | &amp;lt;big&amp;gt;用途（Purpose）&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “所有执行上下文”的状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 代码评估状态（code evaluation state） || 对“与执行上下文关联的代码的执行、挂起和恢复”进行评估所需的任何状态。&lt;br /&gt;
|-&lt;br /&gt;
| 函数（Function） || 如果这个执行上下文正在评估函数对象的代码，那么这个组件的值就是那个函数对象。如果上下文正在评估脚本或模块的代码，则该值为null。&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Function 组件的值也被称为“活动函数对象（active function object）”&lt;br /&gt;
|-&lt;br /&gt;
| 领域（Realm） || “关联代码”访问“ECMAScript 资源”的领域&lt;br /&gt;
* “正在运行的执行上下文（running execution context）”的 Realm 组件的值也被称为“当前 Realm（current Realm）”。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “ECMAScript代码执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|-&lt;br /&gt;
| 变量环境（VariableEnvironment） || 标识“词法环境”，其 EnvironmentRecord 保存由 VariableStatements 在此执行上下文中创建的绑定。&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | “生成器执行上下文”的附加状态组件&lt;br /&gt;
|-&lt;br /&gt;
| 词法环境（LexicalEnvironment） || 标识“词法环境”，用于解析代码在此执行上下文中造成的标识符引用。&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是“词法环境（Lexical Environments）”。&lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
&lt;br /&gt;
=== 生命周期 ===&lt;br /&gt;
可以分为 2 个主要阶段：&lt;br /&gt;
# '''创建阶段（Creation Phase）'''：（“预编译阶段”）JavaScript 引擎会做以下几件事情：&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''词法环境（Lexical Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
## 创建&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;“'''变量环境（Variable Environment）'''”&amp;lt;/span&amp;gt;组件&lt;br /&gt;
# '''执行阶段（Code Execution Phase）'''：（“执行阶段”）JavaScript 引擎会按照代码的顺序逐行执行，并且根据需要更新变量和函数的值&lt;br /&gt;
#* 在执行阶段，如果 JavaScript 引擎不能在源码中声明的实际位置找到 '''let''' 变量的值，它会被赋值为 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
== 词法环境（Lexical Environment） ==&lt;br /&gt;
 '''&amp;lt;big&amp;gt;词法环境&amp;lt;/big&amp;gt;（Lexical Environment）'''：是一种规范类型，基于 ECMAScript 代码的“词法嵌套结构”来&amp;lt;span style=&amp;quot;color: green; font-size: 120%&amp;quot;&amp;gt;定义“'''标识符'''”和具体“'''变量 / 函数'''”的关联&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 —— '''标识符'''：变量 / 函数的名字&lt;br /&gt;
 —— '''标识符'''：对“原始数据”或“实际对象”（包含函数类型对象）的引用&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 即：&amp;lt;span style=&amp;quot;color: blue; font-size: 120%&amp;quot;&amp;gt;词法环境，是一种持有'''“标识符-变量”映射'''的结构&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 通常，词汇环境与 ECMAScript 代码的某些特定语法结构相关联，如 FunctionDeclaration、BlockStatement、Try 语句的 Catch 子句，'''每次评估此类代码时都会创建一个新的词汇环境'''。&lt;br /&gt;
&lt;br /&gt;
特殊的“词法环境”：&lt;br /&gt;
# '''全局环境（global environment）'''：是一个没有外部环境的词汇环境（“外部词法环境引用”为 null）。&lt;br /&gt;
#* 全局环境的 EnvironmentRecord 可以预先填充标识符绑定，并包含关联的“全局对象”，该对象的属性提供了一些全局环境的标识符绑定；&lt;br /&gt;
#* 这个“全局对象”是全局环境的 This 绑定的值；&lt;br /&gt;
#* 在执行 ECMAScript 代码时，可以向“全局对象”添加其他属性，并修改初始属性；&lt;br /&gt;
# '''模块环境（module environment）'''：是一个包含模块的顶级声明的绑定的词法环境。&lt;br /&gt;
#* 它还包含由模块显式导入的绑定；&lt;br /&gt;
#* 其“外部词法环境引用”是一个“全局环境”；&lt;br /&gt;
# '''函数环境（function environment）'''：是一个“对应于ECMAScript函数对象的调用”的词汇环境。&lt;br /&gt;
#* 它可以建立一个新的 this 绑定；&lt;br /&gt;
#* 它还将捕获支持 super 方法调用所需的状态；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; 词法环境，三个部分组成：&lt;br /&gt;
# 一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境记录（Environment Record）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 一个“'''（可能为空值的）'''&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''外部词法环境引用（Outer Lexical Environment）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
# 以及“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This 绑定（This Binding）'''&amp;lt;/span&amp;gt;”&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其伪代码如下：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,     // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,           // 外部词法环境引用: null&lt;br /&gt;
        this: &amp;lt;global object&amp;gt;    // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,    // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            // 在这里绑定标识符&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,    // 外部词法环境引用: 外部&amp;quot;词法环境&amp;quot;&lt;br /&gt;
        this: &amp;lt;depends on how function is called&amp;gt;   // this 绑定: 取决于函数调用方式&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;环境记录（Environment Record）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;环境记录&amp;lt;/big&amp;gt;（Environment Record）'''：记录&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''在其关联的“词法环境”的范围内创建的“标识符”绑定'''&amp;lt;/span&amp;gt; —— 任何在“环境记录”中的标识符都可以在当前“词法环境”直接以标识符形式访问&lt;br /&gt;
&lt;br /&gt;
两种主要的“环境记录”：&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''声明式环境记录（Declarative Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''范围内的声明'''&lt;br /&gt;
#* 主要用于“'''函数'''”和“'''catch'''”词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''对象式环境记录（Object Environment Record）'''&amp;lt;/span&amp;gt;：记录 '''绑定对象的属性'''&lt;br /&gt;
#* 主要用于“'''with'''”和 '''global''' 的词法环境&lt;br /&gt;
# &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;'''全局环境记录（Global Environment Record）'''&amp;lt;/span&amp;gt;：一个对“对象式环境记录”和“声明式环境记录”组件的封装&lt;br /&gt;
&lt;br /&gt;
==== 声明式环境记录（Declarative Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''声明式环境记录'''：与&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''ECMAScript 程序范围'''&amp;lt;/span&amp;gt;相关联，将绑定其范围内包含的&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''声明（declarations）'''&amp;lt;/span&amp;gt;所定义的标识符集&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''ECMAScript 程序范围'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''variable'''、'''constant'''、'''let'''、'''class'''、'''module'''、'''import'''、'''function declarations'''&amp;lt;/span&amp;gt; 等所定义的标识符集&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding、CreateImmutableBinding）：&lt;br /&gt;
*# 要求该 binding 在创建前必须不存在 —— 【let 无法重定义？】&lt;br /&gt;
*# 会将该 binding 标记为 '''uninitialized''' ——【let 的暂时性死区？】&lt;br /&gt;
* 其方法（GetBindingValue）：如果该 binding 是一个 uninitialized binding，将引发 ReferenceError &lt;br /&gt;
&lt;br /&gt;
==== 对象式环境记录（Object Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''对象式环境记录'''：与一个&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''绑定对象（binding object）'''&amp;lt;/span&amp;gt;相关联，将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;big&amp;gt;💡&amp;lt;/big&amp;gt;“'''绑定对象（binding object）'''”包括：&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''全局对象'''&amp;lt;/span&amp;gt;（即浏览器环境的“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;Window 对象&amp;lt;/span&amp;gt;”）、&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''With 语句关联的对象'''&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：&lt;br /&gt;
* 其方法（CreateMutableBinding）：&lt;br /&gt;
*# 并不要求该 binding 在创建前必须不存在 ——【var 可重定义？】&lt;br /&gt;
*# 会将该 binding 初始化为 '''undefined''' ——【var 提升？】&lt;br /&gt;
* “标识符”将与“binding object”的属性一一对应：&lt;br /&gt;
*: 示例：&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 定义的标识符&lt;br /&gt;
var x = 1000&lt;br /&gt;
&lt;br /&gt;
// 可以通过如下方式获取&lt;br /&gt;
console.log(window.x)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// binding object 中的属性&lt;br /&gt;
window.y = 999&lt;br /&gt;
&lt;br /&gt;
// 也可以通过标识符直接获取&lt;br /&gt;
console.log(y)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 无论&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;属性的设置如何，集合中始终包含了“'''自身的'''”和“'''继承的'''”属性&lt;br /&gt;
* 因为对象可以动态添加和删除属性，所以绑定的“标识符”集一定是'''可变的'''&lt;br /&gt;
&lt;br /&gt;
==== 全局环境记录（Global Environment Record）&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;/&amp;gt; ====&lt;br /&gt;
 '''全局环境记录'''：在逻辑上是单个记录，但被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合 —— 专门用于脚本全局声明&lt;br /&gt;
&lt;br /&gt;
其中：&lt;br /&gt;
# “'''对象环境记录'''”：将关联领域（Realm）的全局对象作为其基础对象，包括：&lt;br /&gt;
## 所有 built-in globals（内置全局变量）的绑定，&lt;br /&gt;
## 全局代码中 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定&lt;br /&gt;
# “'''声明性环境记录'''”：全局代码中所有其他 ECMAScript 声明的绑定&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;外部词法环境引用（Outer Lexical Environment）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
 '''&amp;lt;big&amp;gt;外部词法环境引用&amp;lt;/big&amp;gt;（Outer Lexical Environment）'''：用于&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''对词法环境值的“逻辑嵌套”进行建模'''&amp;lt;/span&amp;gt; —— 意味着通过它可以'''访问其“外部词法环境”'''&lt;br /&gt;
&lt;br /&gt;
如果在当前的“词法环境”中找不到变量，JavaScript 引擎可以在外部环境中查找这些变量：&lt;br /&gt;
*（内部）词汇环境的外部引用是指在逻辑上围绕内部词汇环境的词汇环境&lt;br /&gt;
* 外部词汇环境可能有自己的外部词汇环境&lt;br /&gt;
* 一个词汇环境可以作为多个内部词汇环境的外部环境&lt;br /&gt;
&lt;br /&gt;
 每个“词法环境”都使用“外部词法环境引用”与其“外部词法环境”链接，如此将形成一个“&amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''环境链'''&amp;lt;/span&amp;gt;”（ES 3 中的'''作用域链'''） —— 用于“'''标识符的解析'''”（变量的查找）&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;span style=&amp;quot;color: Teal&amp;quot;&amp;gt;This 绑定（This Binding）&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-code&amp;quot; style=&amp;quot;white-space: normal; line-height: 1.6;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;⭐ &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;'''This Binding'''&amp;lt;/span&amp;gt;：&amp;lt;/big&amp;gt;&lt;br /&gt;
# 在“'''全局执行上下文'''”中：this 的值指向“'''全局对象'''”&lt;br /&gt;
#* 浏览器中，“全局对象”即 &amp;lt;code&amp;gt;'''Window'''&amp;lt;/code&amp;gt; 对象&lt;br /&gt;
# 在“'''函数执行上下文'''”中：this 的值'''取决于函数调用方式'''：&lt;br /&gt;
## 若函数被一个引用对象调用，this 将指向对象，&lt;br /&gt;
## 否则，this 的值被设置为“'''全局对象'''”（非严格模式）或者 &amp;lt;code&amp;gt;'''undefined'''&amp;lt;/code&amp;gt;（严格模式）&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 补充内容 ==&lt;br /&gt;
 “执行上下文”、“词汇环境”和“环境记录”纯粹是规范机制，不需要与 ECMAScript 实现的任何特定内容相对应。 ECMAScript 程序不可能直接访问或操作这些值。&lt;br /&gt;
&lt;br /&gt;
=== LexicalEnvironment 与 VariableEnvironment ===&lt;br /&gt;
 '''LexicalEnvironment''' 和 '''VariableEnvironment'''：都是'''执行上下文的组件'''，且同是“词法环境（Lexical Environments）” &lt;br /&gt;
 &lt;br /&gt;
 创建执行上下文时，其 LexicalEnvironment 和 VariableEnvironment 组件最初具有相同的值。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 —— 【注意：“Lexical Environments”指是“词法环境”这一规范机制，而“LexicalEnvironment”才指执行上下文的“词法环境”组件】&lt;br /&gt;
&lt;br /&gt;
# “'''词法环境（LexicalEnvironment）'''”：用于记录范围内的“函数声明”和“变量声明”（let 和 const）的绑定&lt;br /&gt;
#* 有“全局作用域”、“函数作用域”及“块作用域”&lt;br /&gt;
# “'''变量环境（VariableEnvironment）'''”：仅记录“'''var''' 变量”的绑定&lt;br /&gt;
#* 只有“全局作用域”和“函数作用域”&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;big&amp;gt;⭐&amp;lt;/big&amp;gt; “变量环境（VariableEnvironment）”的概念是为 ES6 服务的：'''为了实现 var 的变量提升'''&lt;br /&gt;
 &lt;br /&gt;
 “变量环境（VariableEnvironment）”：其 EnvironmentRecord 保存由 VariableStatements（var 变量）在此“执行上下文”中创建的绑定&lt;br /&gt;
&lt;br /&gt;
=== '''完整总结''' ===&lt;br /&gt;
# '''全局执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
### “'''外部词法环境引用'''”：为 '''null'''&lt;br /&gt;
### “'''This 绑定'''”：为“全局对象”（浏览器环境，即 '''Window 对象'''）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''对象式环境记录'''”：记录全局的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 全局执行上下文&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;对象式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        }&lt;br /&gt;
        // 外部词法环境引用: null&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        // this 绑定: &amp;quot;全局对象&amp;quot;&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''函数执行上下文'''：&lt;br /&gt;
## “'''词法环境'''”：&lt;br /&gt;
### “'''声明式环境记录'''”：包含：&lt;br /&gt;
###* 函数的“'''函数、变量（let, const）'''”等声明&lt;br /&gt;
###* 传递给函数的“'''arguments 对象'''” —— （对象存储索引与参数的映射、参数的 length）&lt;br /&gt;
### “'''外部词法环境引用'''”：为“'''外部词法环境 / 全局词法环境'''”&lt;br /&gt;
### “'''This 绑定'''”：'''取决于函数调用方式'''（及是否严格模式）&lt;br /&gt;
## “'''变量环境'''”:&lt;br /&gt;
### “'''声明式环境记录'''”：记录函数的“'''变量 var'''”的声明&lt;br /&gt;
###  ...&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
// 函数执行上下文&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    // 词法环境&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 包括: &amp;quot;函数声明&amp;quot;和&amp;quot;变量声明&amp;quot;(let, const)的绑定&lt;br /&gt;
             * 以及: 传递给函数的 arguments 对象&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    // 变量环境&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            // 环境记录: &amp;quot;声明式环境记录&amp;quot;&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            /**&lt;br /&gt;
             * 在此处绑定标识符&lt;br /&gt;
             * 仅: &amp;quot;变量声明&amp;quot;(var)的绑定&lt;br /&gt;
             * */ &lt;br /&gt;
        },&lt;br /&gt;
        // 外部词法环境引用: &amp;quot;外部词法环境&amp;quot;或&amp;quot;全局词法环境&amp;quot;&lt;br /&gt;
        outer: &amp;lt;Global or outer function environment reference&amp;gt;,&lt;br /&gt;
        // this 绑定: 取决于函数调用方式&lt;br /&gt;
        ThisBinding: &amp;lt;depends on how function is called&amp;gt;,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 案例分析 ==&lt;br /&gt;
以如下代码为例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
let a = 20;&lt;br /&gt;
const b = 30;&lt;br /&gt;
var c;&lt;br /&gt;
function multiply(e, f) {&lt;br /&gt;
  var g = 20;&lt;br /&gt;
  return e * f * g;&lt;br /&gt;
}&lt;br /&gt;
c = multiply(20, 30);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
分析 JavaScript 引擎执行过程：&lt;br /&gt;
# “'''全局执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            b: &amp;lt;uninitialized&amp;gt; ,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt; ,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: undefined,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''函数执行上下文'''”的“'''创建阶段'''”：&lt;br /&gt;
#: 创建“词法环境（Lexical Environment）”、“变量环境（Variable Environment）”组件&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: undefined&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#* ThisBinding：“非严格模式”为“Global Object”，“严格模式”为“undefined”&lt;br /&gt;
# “'''函数执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
FunctionExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            Arguments: {0: 20, 1: 30, length: 2},&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;,&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Declarative&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            g: 20&lt;br /&gt;
        },&lt;br /&gt;
        outer: &amp;lt;GlobalLexicalEnvironment&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object or undefined&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# “'''全局执行上下文'''”的“'''执行阶段'''”：&lt;br /&gt;
#: 按照代码顺序逐行执行，并按需更新变量和函数的值&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;JavaScript&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
GlobalExectionContext = {&lt;br /&gt;
    LexicalEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            a: 20,&lt;br /&gt;
            b: 30,&lt;br /&gt;
            multiply: &amp;lt;func&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    },&lt;br /&gt;
    VariableEnvironment: {&lt;br /&gt;
        EnvironmentRecord: {&lt;br /&gt;
            Type: &amp;quot;Object&amp;quot;,&lt;br /&gt;
            // Identifier bindings go here&lt;br /&gt;
            c: 12000,&lt;br /&gt;
        }&lt;br /&gt;
        outer: &amp;lt;null&amp;gt;,&lt;br /&gt;
        ThisBinding: &amp;lt;Global Object&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 参考 ==&lt;br /&gt;
=== ECMAScript ===&lt;br /&gt;
  以下内容来自：《ECMAScript® 2015 Language Specification》的 [https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts 《Executable Code and Execution Contexts》]&lt;br /&gt;
&amp;lt;references group=&amp;quot;ECMAScript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;声明式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;声明式环境记录（Declarative Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
声明性环境记录用于定义 ECMAScript 语言语法元素的效果，如 FunctionDeclarations、VariableDeclarations 和 Catch 子句，这些子句将“标识符绑定”与“ECMAScript 语言值”直接关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
::* “ECMAScript 语言值（ECMAScript language values）”：由“ECMAScript语言类型（ECMAScript Language Types）”表征的值&lt;br /&gt;
::* “ECMAScript语言类型（ECMAScript Language Types）”：包括 '''Undefined'''、'''Null'''、'''Boolean'''、'''String'''、'''Symbol'''、'''Number''' 和 '''Object'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个声明性环境记录都与 ECMAScript 程序范围相关联，该程序范围包含的 '''variable'''（变量）, '''constant'''（常量）, '''let''', '''class''', '''module''', '''import''', and/or '''function''' 等内容的声明。声明性环境记录绑定其范围内包含的声明所定义的标识符集。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;对象式环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;对象式环境记录（Object Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
对象环境记录用于定义 ECMAScript 元素（如 WithStatement）的效果，这些元素将“标识符绑定”与“某些对象的属性”相关联。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
每个对象“环境记录”都与一个称为其“绑定对象（binding object）”的对象相关联。对象环境记录将绑定与其“绑定对象”的属性名称直接对应的字符串标识符名称集。不是 IdentifierName 形式的字符串的属性键不包括在绑定标识符集中。无论 &amp;lt;nowiki&amp;gt;[[Enumerable]]&amp;lt;/nowiki&amp;gt; 属性的设置如何，集合中都包含了自己的和继承的属性。因为可以从对象中动态添加和删除属性，所以由对象 Environment Record 绑定的标识符集可能会发生更改，这可能是任何添加或删除财产的操作的副作用。由于这种副作用而创建的任何绑定都被认为是可变绑定，即使相应属性的 Writable 属性的值为 false。对象“环境记录”不存在不可变绑定。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref group=&amp;quot;ECMAScript&amp;quot; name=&amp;quot;全局环境记录&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;全局环境记录（Global Environment Record）&amp;lt;/span&amp;gt;，定义/描述：&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录和函数环境记录是专门用于脚本全局声明和函数中的顶级声明的专门化。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
全局环境记录用于表示在 common Realm（公共领域）中处理的所有 ECMAScript 脚本元素共享的最外部作用域。全局环境记录为 built-in globals（内置全局变量）、properties of the global object（全局对象的属性）以及脚本中出现的所有顶级声明提供绑定。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
全局环境记录在逻辑上是单个记录，但它被指定为封装“对象环境记录（Declarative Environment Record）”和“声明性环境记录（Object Environment Record）”的组合。“对象环境记录”将关联 Realm（领域）的全局对象作为其基础对象。这个全局对象是全局环境记录的 GetThisBinding 具体方法返回的值。全局环境记录的对象环境记录组件包含所有 built-in globals（内置全局变量）的绑定，以及全局代码中包含的 FunctionDeclaration、GeneratorDeclaration 或 VariableStatement 引入的所有绑定。全局代码中所有其他 ECMAScript 声明的绑定都包含在全局环境记录的“声明性环境记录”组件中。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以直接在全局对象上创建属性。因此，全局环境记录的对象环境记录组件可能既包含由 FunctionDeclaration、GeneratorDeclassion 或 VariableDeclassing 声明显式创建的绑定，也包含作为全局对象的属性隐式创建的链接。为了识别哪些绑定是使用声明显式创建的，全局环境记录会维护一个使用其 CreateGlobalVarBindings 和 CreateGlobalFunctionBindings 具体方法绑定的名称列表。&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 网络文章 ===&lt;br /&gt;
# [https://juejin.cn/post/6844903682283143181 《&amp;lt;nowiki&amp;gt;[译]&amp;lt;/nowiki&amp;gt; 理解 JavaScript 中的执行上下文和执行栈》]&lt;br /&gt;
# [https://juejin.cn/post/6945240902625394718 《你真的了解执行上下文吗？》]&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
</feed>