php企业网站建设论文,网站建设登录界面代码,冬青街 做网站,精准营销数据作用链域闭包 闭包的特性#xff1a;说说你对闭包的理解使用闭包的注意点总结 扩展 循环中使用闭包解决 var 定义函数的问题 解决办法有三种 作用链域
JavaScript 的作用域链#xff08;Scope Chain#xff09;是指在代码中访问变量时的查找路径。
当 JavaScript 引擎在执…作用链域闭包 闭包的特性说说你对闭包的理解使用闭包的注意点总结 扩展 循环中使用闭包解决 var 定义函数的问题 解决办法有三种 作用链域
JavaScript 的作用域链Scope Chain是指在代码中访问变量时的查找路径。
当 JavaScript 引擎在执行代码时会根据作用域链来确定变量的可访问范围。
作用域链由多个执行上下文Execution Context组成每个执行上下文都有一个关联的变量对象Variable Object变量对象保存了当前执行环境中定义的所有变量和函数。
当需要访问一个变量时引擎会从当前执行上下文的变量对象开始查找如果找不到则沿着作用域链继续向上查找直到全局执行上下文的变量对象。
如果在作用域链的任何级别上找不到该变量则会抛出 ReferenceError。
作用域链的形成是由变量的作用域规则决定的。
在 JavaScript 中有三种类型的作用域
全局作用域、函数作用域块级作用域。
每个作用域都会创建一个新的执行上下文并将其添加到当前的作用域链中。
作用域链是 JavaScript 用来管理变量访问权限的一种机制它决定了变量在代码中的可见性和可访问性。
通过理解作用域链我们能更好地理解 JavaScript 中的作用域和变量的生命周期。
JavaScript 的作用域链是指在代码中访问变量时的查找路径。我将通过一个例子来说明作用域链的概念。
更多详细内容请微信搜索“前端爱好者“ 戳我 查看 。
var globalVariable Global; // 全局变量function outerFunction() {var outerVariable Outer; // 外部函数变量function innerFunction() {var innerVariable Inner; // 内部函数变量console.log(innerVariable); // 在内部函数中访问内部变量console.log(outerVariable); // 在内部函数中访问外部函数变量console.log(globalVariable); // 在内部函数中访问全局变量}innerFunction(); // 调用内部函数
}outerFunction(); // 调用外部函数在上面的例子中我们定义了三个不同级别的变量
全局变量 globalVariable、外部函数变量 outerVariable内部函数变量 innerVariable。
当执行 outerFunction() 后会创建一个包含 outerVariable 和 innerFunction 的函数执行上下文即外部函数的执行上下文。
然后在 outerFunction() 中调用 innerFunction() 时会再次创建一个包含 innerVariable 的函数执行上下文即内部函数的执行上下文。
当内部函数访问变量时JavaScript 引擎会按照作用域链的顺序进行查找。
首先它会在当前执行上下文的变量对象中查找变量即在内部函数的执行上下文中查找 innerVariable。 如果找到了该变量则直接使用。如果没有找到则会继续向上一级的执行上下文即外部函数的执行上下文中查找即在外部函数的执行上下文中查找 outerVariable。如果还是找不到则继续向上一级的执行上下文即全局执行上下文中查找即在全局执行上下文中查找 globalVariable。
在这个例子中当 innerFunction() 执行时会按照作用域链的顺序找到并访问到 innerVariable、outerVariable 和 globalVariable。
如果在作用域链的任何级别上找不到变量就会抛出 ReferenceError。
这就是作用域链的工作原理它决定了变量在代码中的可见性和可访问性。
闭包
闭包就是 能够读取其他函数内部变量的函数
闭包是指 有权访问另⼀个函数作用域中变量的函数创建闭包的最常⻅的方式就是: 在⼀个函数内创建另⼀个函数 通过另⼀个函数访问这个函数的局部变量,利用闭包可以突破作用链域
闭包的特性
函数内再嵌套函数内部函数可以引用外层的参数和变量参数和变量不会被垃圾回收机制回收
说说你对闭包的理解
使用闭包主要是为了设计私有的方法和变量 。 闭包的优点是可以避免全局变量的污染缺点是闭包会常驻内存会增大内存使用量使用不当很容易造成内存泄露。
在js中 函数即闭包 只有函数才会产生作用域的概念 闭包 的最大用处有两个 ⼀个是可以读取函数内部的变量另⼀个就是让这些变量始终保持在内存中 闭包的另⼀个用处 是封装对象的私有属性和私有方法 好处能够实现封装和缓存等坏处就是消耗内存 、不正当使用会造成内存溢出的问题
使用闭包的注意点
由于闭包会使得函数中的变量都被保存在内存中 内存消耗很大所以不能滥用闭包 否则会造成网页的性能问题在IE中可能导致内存泄露 解决方法是在退出函数之前将不使用的局部变量全部删除
总结
闭包的定义其实很简单 函数A内部有⼀个函数B 函数 就是闭包B 可以访问到函数 A 中的变量那么函数B就是闭包
function A ( ) {let a 1window .B function ( ) {console . log( a)}
}
A ( )
B ( ) // 1闭包存在的意义就是让我们可以间接访问函数内部的变量
扩展 循环中使用闭包解决 var 定义函数的问题
for (var i 1; i 5; i) {setTimeout(function timer() {console.log(i)}, i * 1000)
}首先因为 setTimeout 是个异步函数所以会先把循环全部执行完毕 这时候 i 就是 6 了所以会输出⼀堆 6
解决办法有三种
第⼀种是使用闭包的方式
for (var i 1; i 5; i) {;(function(j) {setTimeout(function timer() {console.log(j)}, j * 1000)})(i)
}在上述代码中 我们首先使用了立即执行函数将 i 传入函数内部 这个时候值就被固定在了参数 j 上面不会改变 当下次执行 timer 这个闭包的时候就可以使用外部函数的变量 j 从而达到目的
第⼆种就是使用 setTimeout 的第三个参数
这个参数会被当成 timer 函数的参数传入
for (var i 1; i 5; i) {setTimeout(function timer(j) {console.log(j)},i * 1000,i)
}setTimeout 的第三个参数
在 JavaScript 中setTimeout 函数是用于延迟执行一个函数或一段代码。它的语法如下
setTimeout(callback, delay, arg1, arg2, ...);其中
callback 是要执行的函数或代码块。delay 是延迟的时间以毫秒为单位。arg1, arg2, … 是可选的参数在延迟结束后会作为参数传递给回调函数。
现在来看第三个参数它表示延迟结束后作为参数传递给回调函数的值。这个参数可以是任意类型的数据。
让我们通过一个例子来说明第三个参数的使用
function greet(name) {console.log(Hello, name !);
}setTimeout(greet, 2000, John);在上面的例子中setTimeout 函数将延迟 2000 毫秒后执行 greet 函数并且将字符串 John 作为参数传递给 greet 函数。当延迟结束后greet 函数会被调用并输出 Hello, John!。
这里的 John 就是 setTimeout 的第三个参数它会在延迟结束后作为参数传递给回调函数 greet。
需要注意的是setTimeout 的第三个参数是可选的如果不提供则回调函数不会接收任何参数。如果提供了多个参数它们会按照顺序传递给回调函数。
第三种就是使用 let 定义 i 了来解决问题了
这个也是最为推荐的方式
for (let i 1; i 5; i) {setTimeout(function timer() {console.log(i)}, i * 1000)
}