0

0

javascript闭包函数的基本使用以及会遇到的问题解决

不言

不言

发布时间:2018-10-23 15:17:32

|

2481人浏览过

|

来源于segmentfault思否

转载

本篇文章给大家带来的内容是关于javascript闭包函数的基本使用以及会遇到的问题解决,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

面试的时候一直会被问到什么是闭包,以前也不是很在意,更没有去总结和归纳.

编程语言Perl性能优化的三大技巧总结 中文WORD版
编程语言Perl性能优化的三大技巧总结 中文WORD版

本文和大家重点讨论一下Perl性能优化技巧,利用Perl开发一些服务应用时,有时会遇到Perl性能或资源占用的问题,可以巧用require装载模块,使用系统函数及XS化模块,自写低开销模块等来优化Perl性能。 Perl是强大的语言,是强大的工具,也是一道非常有味道的菜:-)利用很多perl的特性,可以实现一些非常有趣而实用的功能。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载

闭包就是能够读取其他函数内部变量的函数。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

(一)闭包最基本的应用:

少废话,上代码

还是<>的栗子,
function createComparisonFunction(propertyName) {
    return function(object1, object2) {
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];

        if(value1 < value2) {
            return -1;
        } else if(value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    };
}
var compare = createComparisonFunction("name"); 

var result = compare({ name: "Nicholas" }, { name: "Greg" });

分析:
(1)闭包函数可以访问其外部函数
  return出来的这个匿名函数就是一个闭包函数,这个匿名函数中的访问了外部函数的活动对象,就是这个propertyName参数。因为外部的作用域链被这个匿名函数所包含(也可以理解为:compare函数包含
createComparisonFunction()函数的活动对象和全局变量对象),所以返回的这个匿名函数可以一直访问他外部的这个propertyName以及全局变量。
(2)闭包所引用的外部变量不会因为所在作用域销毁而销毁
  因为在返回的闭包函数中,引用了外部函数的活动对象,所以createComparisonFunction()内的活动对象(即propertyName)在createComparisonFunction()执行完后不会被销毁。因为虽然createComparisonFunction执行完后,会把其执行环境中的作用域链销毁,但是他的活动对象仍然被闭包函数引用,放入了匿名函数的执行环境的作用域中

立即学习Java免费学习笔记(深入)”;

(二)闭包的副作用

(1).闭包只能取得包含函数中任何变量的最后一个值

        function createFunctions(){ 
            var result = new Array(); 
            for (var i=0; i < 10; i++){ 
                result[i] = function(){ 
                return i; 
                }; 
            } 
            return result; 
        }
        
        var res = createFunctions();
        console.log(res[0]());  //10
        console.log(res[1]());  //10

原理:
因为每个函数的作用域链中都保存着 createFunctions() 函数的活动对象,所以它们引用的都是同一个变量 i 。 当createFunctions()函数返回后,变量 i 的值是 10,此时每个函数都引用着保存变量 i 的同一个变量对象,所以在每个函数内部 i 的值都是 10

解决方法:

获取内部函数的对象result[i]时,使用匿名函数,并在匿名函数中再使用闭包函数,使得当前环境下的num被闭包函数函数调用,存储在作用域中不会被释放.
        function  createFunctions2(){
            var result  = new Array();
            for(var i = 0 ; i <10 ; i++){
                result[i] = (function(num){
                    return function(){
                        return num
                    }
                })(i)
            }
            return result;
        }
        
        var res2 =  createFunctions2();
        console.log(res2[0]());  // 0 
        console.log(res2[1]());  // 1

原理:
定义了一个匿名函数,并将立即执行该匿名函数的结果赋给数组。这里的匿名函数有一个参数 num,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量 i。由于函数参数是按值传递的,所以就会将变量 i 的当前值复制给参数 num。而在这个匿名函数内部,又创建并返回了一个访问 num 的闭包。这样一来,result 数组中的每个函数都有自己num 变量的一个副本,因此就可以返回各自不同的数值了。

(2).当闭包函数外部包含了一个匿名函数,this指向全局

        var name = "The Window";
        var object = {
            name: "My Object",
            getNameFunc: function () {   
                return function () {        //匿名函数执行具有全局性
                    return this.name;       //this指向window
                };
            }
        };

        console.log(object.getNameFunc()())  //  The Window

原理:
每个函数在被调用时都会自动取得两个特殊变量:this 和 arguments。内部函
数在搜索这两个变量时,只会搜索到其活动对象为止,所以无法获取到外部的this,此时getNameFunc()返回的是一个匿名函数,并且匿名函数具有全局性,因此this指向全局的window

解决方案:
把外部作用域中的 this 对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了

    var name2 =  "The  Window";
    var object2 = {
        name:"My Object",
        getNameFunc:function(){
            var that =  this; //将外部函数的this保存在外部函数的活动对象中(函数中申明的变量中)
            return function (){
                return that.name
            }
        }
    }
    
    console.log(object2.getNameFunc()())   //My Object

(三)
闭包的缺点
(1).由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多
(2).闭包只能取得包含函数中任何变量的最后一个值,所以要注意写法







唧唧陆                                                                                                javascript闭包函数的基本使用以及会遇到的问题解决3                                                                                                                                                                                                

                                                   3 分钟前发布                                                                                            

闭包函数

  • javascript

                                               7 次阅读                                                 ·                                                 读完需要 12 分钟                                                                                    



                           0                        

                                                                                                                                           


面试的时候一直会被问到什么是闭包,以前也不是很在意,更没有去总结和归纳.

闭包就是能够读取其他函数内部变量的函数。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

(一)闭包最基本的应用:

少废话,上代码

还是<>的栗子,
function createComparisonFunction(propertyName) {
    return function(object1, object2) {
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];

        if(value1 < value2) {
            return -1;
        } else if(value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    };
}
var compare = createComparisonFunction("name"); 

var result = compare({ name: "Nicholas" }, { name: "Greg" });

分析:
(1)闭包函数可以访问其外部函数
  return出来的这个匿名函数就是一个闭包函数,这个匿名函数中的访问了外部函数的活动对象,就是这个propertyName参数。因为外部的作用域链被这个匿名函数所包含(也可以理解为:compare函数包含
createComparisonFunction()函数的活动对象和全局变量对象),所以返回的这个匿名函数可以一直访问他外部的这个propertyName以及全局变量。
(2)闭包所引用的外部变量不会因为所在作用域销毁而销毁
  因为在返回的闭包函数中,引用了外部函数的活动对象,所以createComparisonFunction()内的活动对象(即propertyName)在createComparisonFunction()执行完后不会被销毁。因为虽然createComparisonFunction执行完后,会把其执行环境中的作用域链销毁,但是他的活动对象仍然被闭包函数引用,放入了匿名函数的执行环境的作用域中

立即学习Java免费学习笔记(深入)”;


(二)闭包的副作用

(1).闭包只能取得包含函数中任何变量的最后一个值

        function createFunctions(){ 
            var result = new Array(); 
            for (var i=0; i < 10; i++){ 
                result[i] = function(){ 
                return i; 
                }; 
            } 
            return result; 
        }
        
        var res = createFunctions();
        console.log(res[0]());  //10
        console.log(res[1]());  //10

原理:
因为每个函数的作用域链中都保存着 createFunctions() 函数的活动对象,所以它们引用的都是同一个变量 i 。 当createFunctions()函数返回后,变量 i 的值是 10,此时每个函数都引用着保存变量 i 的同一个变量对象,所以在每个函数内部 i 的值都是 10

解决方法:

获取内部函数的对象result[i]时,使用匿名函数,并在匿名函数中再使用闭包函数,使得当前环境下的num被闭包函数函数调用,存储在作用域中不会被释放.
        function  createFunctions2(){
            var result  = new Array();
            for(var i = 0 ; i <10 ; i++){
                result[i] = (function(num){
                    return function(){
                        return num
                    }
                })(i)
            }
            return result;
        }
        
        var res2 =  createFunctions2();
        console.log(res2[0]());  // 0 
        console.log(res2[1]());  // 1

原理:
定义了一个匿名函数,并将立即执行该匿名函数的结果赋给数组。这里的匿名函数有一个参数 num,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量 i。由于函数参数是按值传递的,所以就会将变量 i 的当前值复制给参数 num。而在这个匿名函数内部,又创建并返回了一个访问 num 的闭包。这样一来,result 数组中的每个函数都有自己num 变量的一个副本,因此就可以返回各自不同的数值了。

(2).当闭包函数外部包含了一个匿名函数,this指向全局

        var name = "The Window";
        var object = {
            name: "My Object",
            getNameFunc: function () {   
                return function () {        //匿名函数执行具有全局性
                    return this.name;       //this指向window
                };
            }
        };

        console.log(object.getNameFunc()())  //  The Window

原理:
每个函数在被调用时都会自动取得两个特殊变量:this 和 arguments。内部函
数在搜索这两个变量时,只会搜索到其活动对象为止,所以无法获取到外部的this,此时getNameFunc()返回的是一个匿名函数,并且匿名函数具有全局性,因此this指向全局的window

解决方案:
把外部作用域中的 this 对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了

    var name2 =  "The  Window";
    var object2 = {
        name:"My Object",
        getNameFunc:function(){
            var that =  this; //将外部函数的this保存在外部函数的活动对象中(函数中申明的变量中)
            return function (){
                return that.name
            }
        }
    }
    
    console.log(object2.getNameFunc()())   //My Object

(三)
闭包的缺点
(1).由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多
(2).闭包只能取得包含函数中任何变量的最后一个值,所以要注意写法


  • javascript闭包函数的基本使用以及会遇到的问题解决



你可能感兴趣的



评论                                                    

默认排序                        时间排序



载入中...

显示更多评论



相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

43

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

35

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

41

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

204

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

9

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

8

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 1.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号