JavaScript闭包-闭包定义与应用

简介: 一、闭包定义一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。(1)作为一个函数变量的一个引用,当函数返回时,其处于激活状态。

一、闭包定义

一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

(1)作为一个函数变量的一个引用,当函数返回时,其处于激活状态。

(2)一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

二、闭包应用

看了闭包的定义,也许您还觉得云里雾里,下面我们通过一个示例子闭包的应用。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript闭包</title>
</head>
<body>

<script type="text/javascript">   
    function init() {   
        var arrays = document.getElementsByTagName("p");   
        for( var i=1; i<=arrays.length; i++ ) {   
            arrays[i].onclick = function() {   
                alert(i);   
            }   
        }   
    }   
</script>   
</head>   
<body onload="init();">   
    <p>产品一</p>
    <p>产品二</p>
    <p>产品三</p>
    <p>产品四</p>
    <p>产品五</p>
</body>
</html>

上述代码,运行效果是,不管点击任何一个P元素,输出的结果都是5。
如何实现点击产品一 输出1、点击产品二 输出2、点击产品三 输出3 以此类推?

方案1 将变量保存在每个P元素对象上

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ) {   
        arrays[i-1].i = i;   
        arrays[i-1].onclick = function() {   
            alert(this.i);   
        }
    }   
}  

方案2 使用闭包,以参数的方式传递

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ) {   
        (function(arg){     
            arrays[i-1].onclick = function() {     
                alert(arg);   
            };   
        })(i);
    }   
}   

方案3 使用闭包,返回一个函数作为响应事件(与方案2有细微差别)

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ) {   
        (function(arg){     
            arrays[i-1].onclick = function() {     
                return function(){
                    alert(arg)
                };   
            };   
        })(i);
    }   
}

方案4 使用闭包,以调用时局部变量

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ) {   
        (function(){   
            var temp = i;  
            arrays[i-1].onclick = function() {     
                alert(temp);   
            };   
        })();
    }   
} 

方案5 使用匿名函数保存在函数自身

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ){
        (arrays[i-1].onclick = function() {   
            //arguments.callee 表示函数对象自身的引用
            alert(arguments.callee.i);   
        }).i = i;   
    }   
}

方案6 使用Function实现,实际上是产生一个闭包

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ) {   
        arrays[i-1].onclick = new Function("alert(" + i + ");");
    }   
}

方案7 使用Function (与6有细微差别一个new 一个没)

function init() {   
    var arrays = document.getElementsByTagName("p");   
    for( var i=1; i<=arrays.length; i++ ) {   
        arrays[i-1].onclick = Function("alert(" + i + ");");
    }   
}
相关文章
|
16天前
|
监控 JavaScript 算法
如何使用内存监控工具来定位和解决Node.js应用中的性能问题?
总之,利用内存监控工具结合代码分析和业务理解,能够逐步定位和解决 Node.js 应用中的性能问题,提高应用的运行效率和稳定性。需要耐心和细致地进行排查和优化,不断提升应用的性能表现。
166 77
|
14天前
|
存储 缓存 监控
如何使用内存监控工具来优化 Node.js 应用的性能
需要注意的是,不同的内存监控工具可能具有不同的功能和特点,在使用时需要根据具体工具的要求和操作指南进行正确使用和分析。
59 31
|
14天前
|
JavaScript 前端开发 API
深入理解Node.js事件循环及其在后端开发中的应用
本文旨在揭示Node.js的核心特性之一——事件循环,并探讨其对后端开发实践的深远影响。通过剖析事件循环的工作原理和关键组件,我们不仅能够更好地理解Node.js的非阻塞I/O模型,还能学会如何优化我们的后端应用以提高性能和响应能力。文章将结合实例分析事件循环在处理大量并发请求时的优势,以及如何避免常见的编程陷阱,从而为读者提供从理论到实践的全面指导。
|
14天前
|
JavaScript
如何使用内存快照分析工具来分析Node.js应用的内存问题?
需要注意的是,不同的内存快照分析工具可能具有不同的功能和操作方式,在使用时需要根据具体工具的说明和特点进行灵活运用。
35 3
|
17天前
|
JavaScript 前端开发 安全
JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择
本文深入探讨了JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择。JavaScript以其灵活性和广泛的生态支持著称,而TypeScript通过引入静态类型系统,提高了代码的可靠性和可维护性,特别适合大型项目。文章还讨论了结合使用两种语言的优势,以及如何根据项目需求和技术背景做出最佳选择。
38 4
|
17天前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
31 4
|
16天前
|
前端开发 JavaScript 关系型数据库
基于 Vue2.0 + Nest.js 全栈开发的后台应用
Vue2 Admin 是一个基于 Vue2 和 Ant Design Pro 开发的前端项目,配合 Nest.js 构建的后端,提供了一个完整的全栈后台应用解决方案。该项目支持动态国际化、用户权限管理、操作日志记录等功能,适合全栈开发者学习参考。线上预览地址:https://vue2.baiwumm.com/,用户名:Admin,密码:abc123456。
|
17天前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
22 2
|
17天前
|
JavaScript 前端开发 API
Vue.js 3:深入探索组合式API的实践与应用
Vue.js 3:深入探索组合式API的实践与应用
|
17天前
|
Web App开发 JSON JavaScript
Node.js 中的中间件机制与 Express 应用
Node.js 中的中间件机制与 Express 应用