JavaScript之----匿名函数、闭包

2024-08-23 13:32
文章标签 java 函数 script 匿名 闭包

本文主要是介绍JavaScript之----匿名函数、闭包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

匿名函数

匿名函数就是没有名字的函数
(function () {
alert("匿名函数()");
} )

//匿名函数的调用

(function () {
alert("匿名函数()");
} )();


(function (name) {
alert(name);
} )("lisi");

var s =  ( function (name) {
     return name;
} )("zhangsan");
alert(s);   //zhangsan

alert(
  ( function (name) {
     return name;
} )("zhangsan")
);

//把匿名函数赋值给一个变量
var m = function(){
        alert("ha");
};
m();  //ha

var b = function(name){
        alert(name);
};
b("xiaoli");  

var a = function(name){
        return name;
};
alert(a("xiaoli"));  

闭包
1定义:在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

function show(){
var name = "lisi";
 return function(){
                return name;
            };                                           //闭包  这个函数是个引用类型的对象,所以可以用一个变量接收一下 如①
}
var fun = show();       ①
fun();  //就是在调用紫色部分那个函数

或者:show()();     这也是在调用紫色部分函数

2好处:
例:实现一个变量的累加
function add(){
    var age = 10;
    age++;
    return age;
}
alert(add());//11
alert(add());//11
解释:每次调用add函数时会给age开辟内存,结束时释放内存,函数每次调用时,局部变量开辟内存,函数调用结束时,局部变量释放内存。

局部变量不能实现每次调用age++,解决这个问题可用全局变量,但是全局变量是公共的,任何函数都可以使用,容易出现问题,所以尽量少用全局变量,为了解决这个问题,让age的值逐渐递增 使用闭包。

function add1(){
    var age = 10;
    return function(){
        age++;
        return age;
    };
}
var func = add1();
alert( func());//11
alert( func() );//12而
alert(func());//13    
解释:反复调用的是func(),add1()只调用了一次;闭包使用的局部变量,不会立刻释放内存,会在内存驻留一段时间。
注意:尽量少使用闭包,在必要时再使用闭包

3在循环中使用闭包:

function fun(){
    var arr =[];
    for(var i = 0;i<3 ; i++){
        arr[i] =function (){
                return i;
        };
    }
    return arr;
}
var a = fun();
for(var j = 0; j<a.length; j++){
    alert(a[j]());          //a[j]  代表的是一个函数  调用这个函数a[j]()  运行后显示是 3 3 3 
}


function fun(){
    var arr =[];
    for(var i = 0;i<3 ; i++){
        arr[i] =(function (num){
                return num;
        })(i);              //改成了函数调用,当i= 0 时,num = 0,返回0放在arr[0]中
    }
    return arr;
}
var a = fun();
for(var j = 0; j<a.length; j++){
    alert(a[j]);          //012
}

//用闭包实现如下:
function fun(){
    var arr =[];
    for(var i = 0;i<3 ; i++){
        arr[i] =(function (num){
                return frunction(){
                            return num;
                        };
        })(i);       
    }
    return arr;
}
var a = fun();
for(var j = 0; j<a.length; j++){
    alert(a[j]());          //012    闭包中的局部变量会长时间驻留,所以 012都不会立刻消失
}

4闭包中this的特点
闭包中的this在运行时指向windw,因为闭包并不属于这个对象的属性或方法。

var obj ={
    name:"lisi",
    fun:function(){
        return function(){
                return this;
        };
    }
};
var a = obj.fun();
a();    //返回的this指向的是window

var name = "window";
var obj2 ={
    name:"object",
    fun:function(){
        return function(){
                return this.name;
        };
    }
};
alert( obj2.fun ()() );         //window

alert(obj2.fun().call(obj2) );  //对象 冒充   显示  object   

var name = "window";
var obj2 ={
    name:"object",
    fun:function(){
            var t = this;   //obj2
        return function(){
                return t.name;    //引用之间的赋值
        };
    }
};
alert( obj2.fun ()() );         //object

5块级作用域
js中不存在块级作用域   if(){}   for(){}
实现for循环结束时,变量i的作用域结束,i在内存中消失
//模拟块级作用域(私有作用域)
(function () {
        //作用域
})();
//在之后做项目中会经常用到, 在项目中,尽量少使用全局的变量和函数,多用块级作用域

function fun(){
(function(){
         for(var i = 1; i<=3;i++){
alert(i);
}
})();    //匿名函数执行完时(i相当于其中的局部变量,)i的作用域结束,从内存中释放了
alert(i);        //访问不到了
}
fun();

6私有变量、静态私有变量
(1)私有变量

function show(){
    var num = 5;                           //私有变量(局部变量)
    function test(){                        //私有函数(局部函数)
        return "我是局部函数";
    }
    this.test = function(){
        return num + test();
    }
}
var s = new show();
s.test();                                           //可以通过公共的访问私有的

function Test(){
        this.name ="lisi";                //公共属性
        this.fun = function(){         //公共函数
            alert(this.name);
        }
}                                                    (这是一个构造函数)
var t1 = new Test();
alert(t1.name);
t1.fun();


//使用构造函数的传参访问私有变量

function Person(value){
var user = value; //私有变量
  this.getUser = function(){        //公共的
        return user;
    }
this.setUser = function(v){
        user = v;
    }
}

var person = new Person("hello");
alert(person.getUset());
person.setUser("hai");
alert(person.getUset());

(2)静态私有变量:所有对象共享的局部变量(在内存中只有一块)

//让一个私有变量,被所有对象共享

//块级作用域
(function(){
var country = '';         //静态私有变量
//这是一个全局的Person    
    Person = function(value){
 country = value;
            }
Person.prototype.setCountry = function(c){            //提到共享应想到原型
country = c;
}          
Person.prototype.getCountry = function(){          
return country;
}          
                      
})();

var ren = new Person("usa");

var ren2 = new Person("china");
alert(ren2.getCountry()); //china
alert(ren.getCountry());  //china   因为只有一个country

7访问私有变量和私有函数的其他方式

(1)块级作用域+字面量 方式访问私有变量,私有函数
var objs =   ( function(){
var name = "zhang";     //私有变量
function show(){              //私有函数
return “我爱编程”; 
}
   return  {
        go:function(){
                    return  name+show();
                }
    }                    //字面量对象
} )();
alert( objs.go()) ;     // zhang我爱编程

细节:如果块级作用域赋给一个变量,绿色小括号可以省略 ()

var objs =   function(){
var name = "zhang";     //私有变量
function show(){              //私有函数
return “我爱编程”; 
}
    var o =  {
        go:function(){
                    return  name+show();
                }
    };
        return o;        //这个o是个引用,指向的是这个字面量对象,最后返回的这个字面量对象
}();

(2)块级作用域+构造函数 方式访问私有变量,私有函数
function Test(){}

var oo =   function(){
var name = "zhang";     //私有变量
function show(){              //私有函数
return “我爱编程”; 
}
var t = new Test();
t.go=function(){
return  name+show();
}
 return  t;              
}();
alert(oo.go());




这篇关于JavaScript之----匿名函数、闭包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099513

相关文章

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

SpringBoot中配置Redis连接池的完整指南

《SpringBoot中配置Redis连接池的完整指南》这篇文章主要为大家详细介绍了SpringBoot中配置Redis连接池的完整指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以... 目录一、添加依赖二、配置 Redis 连接池三、测试 Redis 操作四、完整示例代码(一)pom.

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析