<p>Go语言是一种静态类型、强类型的编程语言,它在变量声明和使用方面有着自己独特的规则和特点。以下是关于Go语言变量的详细介绍及相关代码示例。</p><p>变量声明</p><p>在Go语言中,变量声明使用关键字<span style="color: #ce9178;">"var"</span>。语法格式为:<span style="color: #569cd6;">var</span> 变量名 类型。变量名必须以字母或下划线开头,可以由字母、数字或下划线组成。例如:</p><pre class="brush:as3;toolbar:false">var age int var name string var flag bool</pre><p>还可以使用短变量声明的方式进行变量声明和初始化:</p><pre class="brush:as3;toolbar:false">age := 18 name := "Tom" flag := true</pre><p>变量类型</p><p>Go语言的基本数据类型有bool、<span style="color: #569cd6;">string</span>、<span style="color: #569cd6;">int</span>、float等。在Go语言中,变量类型可以在变量名之后指定,也可以通过编译器自动推导得出。例如:</p><pre class="brush:as3;toolbar:false">var age int var name string var flag bool a := 1 b := "Hello" c := true</pre><p>变量赋值</p><p>在Go语言中,变量赋值使用等号<span style="color: #ce9178;">"="</span>。例如:</p><pre class="brush:as3;toolbar:false">age := 18 name := "Tom" flag := true age = 20 name = "Jerry" flag = false</pre><p>多重赋值</p><p>在Go语言中,可以使用多重赋值的方式同时给多个变量赋值。例如:</p><pre class="brush:as3;toolbar:false">a, b := 1, 2 a, b = b, a</pre><p>常量声明</p><p>在Go语言中,常量使用关键字<span style="color: #ce9178;">"const"</span>进行声明。常量必须在声明时进行初始化,且初始化后不可更改。例如:</p><pre class="brush:as3;toolbar:false">const PI float64 = 3.1415926 const age int = 18 const name string = "Tom"</pre><p><br/></p>
文章列表
<p>Go语言是一种开源的静态类型编程语言,它的设计目标是提供一种优雅简洁的语法,同时保证高效性和可维护性。以下是Go语言基础语法的介绍和示例代码。</p><p>变量声明</p><p>Go语言中的变量声明方式有两种:</p><p>声明变量并初始化</p><pre class="brush:as3;toolbar:false">var name string = "Alice"</pre><p>根据初始值自动推导变量类型</p><pre class="brush:as3;toolbar:false">age := 30</pre><p>数据类型</p><p>Go语言中的基本数据类型有:</p><ul class=" list-paddingleft-2" style="list-style-type: disc;"><li><p>整型:<span style="color: #569cd6;">int8</span>、<span style="color: #569cd6;">int16</span>、<span style="color: #569cd6;">int32</span>、<span style="color: #569cd6;">int64</span>、<span style="color: #569cd6;">uint8</span>、<span style="color: #569cd6;">uint16</span>、<span style="color: #569cd6;">uint32</span>、<span style="color: #569cd6;">uint64</span>。</p></li><li><p>浮点型:<span style="color: #569cd6;">float32</span>、<span style="color: #569cd6;">float64</span>。</p></li><li><p>字符串:<span style="color: #569cd6;">string</span>。</p></li><li><p>布尔型:<span style="color: #569cd6;">bool</span>。</p></li><li><p>指针类型:指向变量在内存中的地址。</p></li><li><p>复合类型:数组、切片、字典、结构体、接口、函数。</p></li></ul><p>以下是示例代码:</p><pre class="brush:as3;toolbar:false">package main import ( "fmt" ) func main() { var a int = 10 var b float32 = 3.14 var c string = "Hello, World!" var d bool = true fmt.Printf("%d\n", a) fmt.Printf("%f\n", b) fmt.Printf("%s\n", c) fmt.Printf("%t\n", d) var ptr *int ptr = &a fmt.Printf("%p\n", ptr) arr := [3]int{1, 2, 3} fmt.Printf("%v\n", arr) slice := []int{4, 5, 6} fmt.Printf("%v\n", slice) dict := map[string]int{"one": 1, "two": 2, "three": 3} fmt.Printf("%v\n", dict) type Person struct { name string age int } var person1 Person = Person{"Alice", 20} fmt.Printf("%v\n", person1) var person2 Person person2.name = "Bob" person2.age = 30 fmt.Printf("%v\n", person2) }</pre><p><br/></p>
<p>Vue 3的模板指令可以用于在模板中添加动态行为,包括条件渲染、循环渲染、属性绑定等。以下是Vue 3的常用模板指令及示例代码:</p><p><strong>v-if / v-else-if / v-else</strong></p><p>v-if指令用于条件渲染,根据表达式的真假值来决定是否渲染某个元素。v-else-if和v-else指令则可以用于在v-if指令的基础上添加更多条件分支。</p><pre class="brush:as3;toolbar:false"><template> <div> <div v-if="isShow">Hello World</div> <div v-else-if="isLoading">Loading...</div> <div v-else>Nothing to show</div> </div> </template> <script> export default { data() { return { isShow: true, isLoading: false } } } </script></pre><p>在上面的示例中,根据isShow和isLoading的值来渲染不同的元素。</p><p><strong>v-for</strong></p><p>v-for指令用于循环渲染,根据指定的数据数组或对象来渲染每个元素。</p><pre class="brush:as3;toolbar:false"><template> <ul> <li v-for="(item, index) in items" :key="index">{{ item }}</li> </ul> </template> <script> export default { data() { return { items: ['apple', 'banana', 'orange'] } } } </script></pre><p>在上面的示例中,根据items数组循环渲染每个元素,并使用:key绑定每个元素的唯一标识。</p><p><strong>v-bind</strong></p><p>v-bind指令用于动态地绑定HTML元素的属性或组件的props属性。</p><pre class="brush:as3;toolbar:false"><template> <div> <img v-bind:src="imageUrl" alt=""> <MyComponent v-bind:prop1="value1" :prop2="value2" /> </div> </template> <script> import MyComponent from './MyComponent.vue' export default { data() { return { imageUrl: 'https://example.com/image.jpg', value1: 'foo', value2: 'bar' } }, components: { MyComponent } } </script></pre><p>在上面的示例中,根据imageUrl、value1和value2的值动态地绑定img元素的src属性和MyComponent组件的prop1和prop2属性。</p><p><strong>v-on</strong></p><p>v-on指令用于绑定DOM事件处理程序。</p><pre class="brush:as3;toolbar:false"><template> <button v-on:click="handleClick">Click me</button> </template> <script> export default { methods: { handleClick() { console.log('button clicked') } } } </script></pre><p>在上面的示例中,当按钮被点击时会调用handleClick方法。</p><p><br/></p>
<p>Vue 3的模板语法基础可以分为模板插值、指令、事件绑定和计算属性四个部分。</p><p><strong>模板插值</strong></p><p>模板插值用于在模板中插入数据。在Vue 3中,使用双花括号将JavaScript表达式包裹起来,即可将其插入到模板中。例如:</p><pre class="brush:html;toolbar:false"><div> {{ message }} </div></pre><p>在上面的示例中,message是Vue实例中的一个数据属性,使用双花括号将其插入到模板中。</p><p>指令</p><p>指令用于在模板中添加动态行为。在Vue 3中,指令以v-开头,后面跟着指令名称。例如:</p><pre class="brush:css;toolbar:false"><button v-on:click="handleClick">Click me</button></pre><p>在上面的示例中,v-on是一个指令,用于绑定事件。click是指令的参数,表示要监听的事件类型。handleClick是Vue实例中的一个方法,当按钮被点击时会被调用。</p><p>事件绑定</p><p>事件绑定用于在模板中绑定事件处理程序。在Vue 3中,可以使用v-on指令或简写的@符号来绑定事件处理程序。例如:</p><pre class="brush:html;toolbar:false"><button v-on:click="handleClick">Click me</button> <button @click="handleClick">Click me</button></pre><p>在上面的示例中,click是要绑定的事件类型,handleClick是Vue实例中的一个方法,当按钮被点击时会被调用。</p><p>计算属性</p><p>计算属性用于在模板中计算衍生属性。在Vue 3中,可以使用computed选项来定义计算属性。例如:</p><pre class="brush:as3;toolbar:false"><template> <div> {{ fullName }} </div> </template> <script> export default { data() { return { firstName: 'John', lastName: 'Doe' } }, computed: { fullName() { return this.firstName + ' ' + this.lastName } } } </script></pre><p>在上面的示例中,定义了一个计算属性fullName,它将firstName和lastName拼接起来返回。在模板中使用fullName,而不是firstName和lastName的组合,可以使模板更加简洁和可读。</p><p><br/></p>
<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>Magento 2的对象管理器是一个依赖注入容器,用于创建和管理对象实例。它是Magento 2的核心组件之一,用于解决类之间的依赖关系。</p><p>Magento 2的对象管理器实现了PSR-11容器接口,因此它可以与其他符合该标准的容器库无缝集成。在Magento 2中,对象管理器可以通过以下方式进行访问:</p><pre class="brush:as3;toolbar:false">$objectManager = \Magento\Framework\App\ObjectManager::getInstance();</pre><p>通过这种方式获取对象管理器的实例后,可以使用它来创建对象实例、获取已经创建的对象实例、注入依赖项等操作。下面是一些使用Magento 2对象管理器的示例代码:<br/></p><p><strong>创建对象实例</strong></p><p>使用对象管理器可以方便地创建对象实例,而无需手动实例化类并处理类之间的依赖关系。以下示例代码演示如何使用对象管理器创建Magento\Catalog\Api\ProductRepositoryInterface接口的实例:</p><pre class="brush:as3;toolbar:false">$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);</pre><p>获取已经创建的对象实例<br/></p><p>Magento 2对象管理器是单例模式的,因此一旦创建了对象实例,就可以在后续的代码中使用相同的实例。以下示例代码演示如何使用对象管理器获取已经创建的Magento\Catalog\Model\Product实例:</p><pre class="brush:as3;toolbar:false">$product = $objectManager->get(\Magento\Catalog\Model\Product::class);</pre><p>注入依赖项<br/></p><p>使用对象管理器可以方便地注入类之间的依赖项,而无需手动解决依赖关系。以下示例代码演示如何使用对象管理器注入Magento\Catalog\Api\ProductRepositoryInterface接口作为构造函数的依赖项:</p><pre class="brush:as3;toolbar:false">class MyCustomClass { protected $productRepository; public function __construct(\Magento\Catalog\Api\ProductRepositoryInterface $productRepository) { $this->productRepository = $productRepository; } } $myCustomClass = $objectManager->create(MyCustomClass::class);</pre><p>在上面的示例中,我们使用对象管理器创建了一个MyCustomClass实例,并将Magento\Catalog\Api\ProductRepositoryInterface作为构造函数的依赖项注入到该实例中。</p><p>需要注意的是,虽然对象管理器在某些情况下非常方便,但是过度使用它可能会导致代码变得难以维护。在实现依赖注入时,最好尽可能地使用构造函数注入,以提高代码的可读性和可维护性。</p><p><br/></p>
<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>Magento 2有两种类型的API:公共API和Web API。公共API提供了一组用于开发Magento 2扩展的PHP接口。而Web API则允许外部应用程序与Magento 2进行通信。</p><p><strong>公共API</strong></p><p>公共API是Magento 2的一组PHP接口,允许开发人员访问Magento 2的内部功能和数据。这些接口使用Magento\Framework\Api接口进行定义。下面是一个简单的示例代码,演示如何使用Magento 2的公共API获取产品数据:</p><pre class="brush:as3;toolbar:false"><?php use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Catalog\Api\ProductRepositoryInterface; class Product { protected $productRepository; protected $searchCriteriaBuilder; public function __construct( ProductRepositoryInterface $productRepository, SearchCriteriaBuilder $searchCriteriaBuilder ) { $this->productRepository = $productRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; } public function getProductById($productId) { $searchCriteria = $this->searchCriteriaBuilder->addFilter('entity_id', $productId)->create(); $product = $this->productRepository->getList($searchCriteria)->getFirstItem(); return $product; } }</pre><p><strong>Web API</strong></p><p>Web API允许外部应用程序与Magento 2进行通信。这些API使用REST或SOAP协议,通过HTTP请求和响应进行通信。Web API中的所有请求和响应都是XML或JSON格式的。下面是一个简单的示例代码,演示如何使用Magento 2的Web API创建一个产品:</p><pre class="brush:as3;toolbar:false"><?php $token = 'YOUR_API_TOKEN'; $url = 'http://magento2.local/rest/V1/products'; $productData = [ 'product' => [ 'sku' => 'test-product', 'name' => 'Test Product', 'price' => 10.00, 'status' => 1, 'visibility' => 4, 'type_id' => 'simple', 'attribute_set_id' => 4, 'weight' => 1 ] ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($productData)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: Bearer '.$token ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 200) { $productId = json_decode($response, true)['id']; }</pre><p>在上面的示例中,我们使用cURL库向Magento 2的Web API发送一个创建产品的请求。请求中包含了产品的名称、价格、SKU等信息。请求中还包含了一个授权令牌,用于验证请求的身份。如果请求成功,我们将能够从响应中获取新创建产品的ID。</p><p><br/></p>
<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>Magento 2是一个基于PHP的现代化电子商务平台,它包含了许多不同类型的组件,以满足各种不同的商业需求。下面是几种常见的Magento 2组件类型及其相关代码示例。</p><p>模块(Module)</p><p>模块是Magento 2中的基本组件,它们是按功能划分的、可重用的代码块。每个模块都包含了自己的视图、控制器、模型、布局等组件。下面是一个简单的示例代码,演示如何创建一个Magento 2模块:</p><p></p><pre class="brush:as3;toolbar:false"><?php use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register( ComponentRegistrar::MODULE, 'Vendor_Module', __DIR__ ); 控制器(Controller)</pre><p>控制器是Magento 2中处理用户请求的组件。它们接收HTTP请求并响应HTTP响应。下面是一个简单的示例代码,演示如何创建一个Magento 2控制器:</p><pre class="brush:as3;toolbar:false"><?php namespace Vendor\Module\Controller\Index; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\View\Result\PageFactory; class Index extends Action { protected $resultPageFactory; public function __construct( Context $context, PageFactory $resultPageFactory ) { $this->resultPageFactory = $resultPageFactory; parent::__construct($context); } public function execute() { return $this->resultPageFactory->create(); } }</pre><p>模型(Model)</p><p>模型是Magento 2中的数据模型,它们负责与数据库交互并提供业务逻辑。下面是一个简单的示例代码,演示如何创建一个Magento 2模型:</p><pre class="brush:as3;toolbar:false"><?php namespace Vendor\Module\Model; use Magento\Framework\Model\AbstractModel; class Product extends AbstractModel { protected function _construct() { $this->_init('Vendor\Module\Model\ResourceModel\Product'); } }</pre><p>布局(Layout)</p><p>布局是Magento 2中的视图组件,它们定义了页面的结构和内容。每个布局都包含了多个块(Block)组件,这些块可以是HTML、XML、PHP等代码片段。下面是一个简单的示例代码,演示如何创建一个Magento 2布局:</p><pre class="brush:as3;toolbar:false"><?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="Vendor\Module\Block\Product" name="product" template="Vendor_Module::product.phtml" /> </referenceContainer> </body> </page></pre><p><br/></p>
<p>Date 对象是 JavaScript 中用于操作日期和时间的内置对象。下面介绍一些常用的 Date 对象的方法和示例: 创建 Date 对象 可以使用 new Date() 构造函数来创建一个 Date 对象,它默认使用当前时间。</p><pre class="brush:js;toolbar:false">let date = new Date(); console.log(date); // 输出当前时间</pre><p>可以使用字符串参数来指定特定的日期和时间。</p><pre class="brush:js;toolbar:false">let date = new Date('2022-02-22T22:22:22'); console.log(date); // 输出指定的日期和时间</pre><p>获取时间信息 Date 对象提供了多种方法来获取时间信息,例如获取年、月、日、时、分、秒、毫秒等信息。</p><pre class="brush:js;toolbar:false">let date = new Date(); console.log(date.getFullYear()); // 获取当前年份 console.log(date.getMonth()); // 获取当前月份(0-11) console.log(date.getDate()); // 获取当前日期(1-31) console.log(date.getHours()); // 获取当前小时(0-23) console.log(date.getMinutes()); // 获取当前分钟(0-59) console.log(date.getSeconds()); // 获取当前秒数(0-59) console.log(date.getMilliseconds()); // 获取当前毫秒数(0-999) console.log(date.getTime()); // 获取当前时间戳(自 1970 年 1 月 1 日 00:00:00 UTC 起的毫秒数)</pre><p>格式化日期和时间 可以使用 toLocaleString() 方法将日期和时间格式化为本地字符串。</p><pre class="brush:js;toolbar:false">let date = new Date(); console.log(date.toLocaleString()); // 输出本地日期和时间字符串</pre><p>也可以使用 toLocaleDateString() 和 toLocaleTimeString() 方法将日期和时间分别格式化为本地日期字符串和时间字符串。</p><pre class="brush:js;toolbar:false">let date = new Date(); console.log(date.toLocaleDateString()); // 输出本地日期字符串 console.log(date.toLocaleTimeString()); // 输出本地时间字符串</pre><p>操作日期和时间 Date 对象还提供了多种方法来操作日期和时间,例如设置年、月、日、时、分、秒、毫秒等信息。</p><pre class="brush:js;toolbar:false">let date = new Date(); date.setFullYear(2023); // 设置年份为 2023 date.setMonth(1); // 设置月份为 2(因为月份从 0 开始) date.setDate(22); // 设置日期为 22 date.setHours(22); // 设置小时为 22 date.setMinutes(22); // 设置分钟为 22 date.setSeconds(22); // 设置秒数为 22 date.setMilliseconds(222); // 设置毫秒数为 222 console.log(date); // 输出设置后的日期和时间</pre><p>计算时间差 可以使用 Date 对象的方法来计算两个时间之间的时间差,例如计算两个日期之间的天数。</p><pre class="brush:js;toolbar:false">let date1 = new Date('2022-02-22'); let date2 = new Date('2023-02-22'); let diffTime = date2.getTime() - date1.getTime(); let diffDays = diffTime / (1000 * 60 * 60 * 24); console.log(diffDays); // 输出两个日期之间的天数</pre><p>以上是 Date 对象的一些常用方法和示例</p>
<p>JavaScript 是一种动态类型的语言,具有自动垃圾回收机制,它会自动释放不再使用的内存。JavaScript 的垃圾回收机制会周期性地检查内存中的对象,如果某个对象没有被引用,即没有任何变量或对象引用它,那么这个对象就会被自动回收,释放其占用的内存。 下面是一个简单的 JavaScript 垃圾回收机制的示例:</p><pre class="brush:js;toolbar:false">let a = { prop: 1 }; // 创建一个对象 let b = a; // 变量 b 引用同一个对象 a = null; // 取消 a 对对象的引用 // 此时对象仍然被变量 b 引用,不会被回收 // 只有当变量 b 也被取消引用时,对象才会被回收</pre><p>在这个示例中,创建了一个对象 a,然后让变量 b 引用同一个对象。当取消变量 a 对对象的引用时,对象仍然被变量 b 引用,因此不会被回收。只有当变量 b 也被取消引用时,对象才会被回收。 JavaScript 的垃圾回收机制采用的是标记清除算法。当对象不再被引用时,垃圾回收器会标记这个对象,然后清除所有指向该对象的引用,并将其内存释放回系统。 需要注意的是,在使用 JavaScript 时,应该尽量避免创建不必要的对象和引用,以减少内存占用和垃圾回收的频率,提高应用的性能。 另外,JavaScript 中还提供了手动管理内存的方法,例如使用 delete 关键字删除对象属性、使用 clearInterval() 和 clearTimeout() 方法停止定时器等。但是这些方法并不会立即回收内存,仅仅是取消引用,由垃圾回收机制来决定是否回收内存。 小结,在开发 JavaScript 应用时,了解垃圾回收机制的原理和如何优化内存使用,对提高应用的性能和稳定性非常重要。</p>
<p>在 JavaScript 中,执行上下文和作用域是非常重要的概念。执行上下文是代码被执行时所处的环境,包括变量对象、作用域链、this 等信息。作用域是指在代码中定义变量的区域,决定了变量的可见性和生命周期。 下面是一些 JavaScript 中执行上下文和作用域的示例: 执行上下文</p><pre class="brush:js;toolbar:false">function sayHello(name) { console.log(`Hello, ${name}!`); } sayHello("Alice"); // 输出:Hello, Alice! // 执行上下文: // - 变量对象:包括 arguments 对象和函数中定义的变量 // - 作用域链:指向函数的父级作用域,即全局作用域 // - this:指向全局对象,因为该函数不是作为对象的方法调用的</pre><p>作用域</p><pre class="brush:js;toolbar:false">let a = 10; function foo() { let b = 20; console.log(a, b); } foo(); // 输出:10 20 console.log(a, b); // 报错,b 不在当前作用域中 // 作用域: // - 全局作用域:包含全局变量 a 和函数 foo // - 函数作用域:包含函数内部定义的变量 b</pre><p>作用域链</p><pre class="brush:js;toolbar:false">let a = 10; function foo() { let b = 20; function bar() { let c = 30; console.log(a, b, c); } bar(); } foo(); // 输出:10 20 30 // 作用域链: // - bar 函数的变量对象 // - foo 函数的变量对象 // - 全局变量对象</pre><p>需要注意的是,在 JavaScript 中,函数可以访问其外部作用域中的变量。这个特性被称为闭包,它允许函数在执行完后仍然可以访问其外部作用域中的变量。下面是一个闭包的示例:</p><pre class="brush:js;toolbar:false">function outer() { let a = 10; function inner() { console.log(a); } return inner; } let fn = outer(); fn(); // 输出:10</pre><p>在上面的示例中,inner 函数访问了其外部作用域中的变量 a,由于返回了 inner 函数,所以 fn 变量也可以访问变量 a。这种特性被称为函数的闭包。</p>