JavaScript之闭包、定时器

2023-12-18 23:32
文章标签 java script 定时器 之闭

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

谈谈闭包

对于JavaScript而言,虽然没有块作用域的概念,但是有函数作用域的概念,若是想从全局环境下去访问一个函数内的局部变量,是办不到的;但是根据JavaScript中的链式作用域的概念,它是可以访问外面的全局变量的,所以,针对一个被定义在函数内的函数,它的父函数中的所有变量也是能够被它访问到的。

  1. 什么是闭包
    闭包(Closure)是让内部函数能够访问外部函数中的变量。
    一个最简单的闭包栗子:

    function Closure{var a = 1;// 在最父函数环境中定义了areturn function(){a = 2;   // 给a赋值,但是在当前作用域中并没有声明a这个变量}
    }
    func = Closure(); // 这时的返回值即是一个函数
    func() // 对里面的函数进行调用,这时a的值发生了改变
  2. 闭包的作用
    闭包的作用就是让内部函数能够访问到外部变量,就像上面例子中所演示的样子。
    闭包的另一个作用就是让一些变量始终保存在内存中,看下面:

    function func(){var a = 1;function add(){a++;}function ret(){return a;}return {ret:ret,add:add}
    }
    var f1 = func();
    f1.add();
    f1.add();
    console.log(f1.ret());

    在这个栗子中,函数中的子函数add一共运行了两次,将a的值从1改变到了3,由于父函数被赋给了一个全局变量,所以它就一直在内存中,而不是在调用之后被自动清除了。

  3. 使用闭包的注意点
    上文中已经说过,闭包的特点之一,也是最主要的特点就是函数的所有变量都会被保存在内存中,那么这些变量当然也会占用内存,如果闭包使用过度甚至滥用,就会给内存造成很大的负担,可能会造成性能问题甚至造成内存泄漏,所以在使用完成闭包之后一定要手动去清除这块内存,避免内存问题的出现。

    setTimeout 0 有什么作用

    但从字面上的意思来看,这样设置就是让函数延迟0s执行,但是其实不然,它的作用是让函数放到最后去执行,比如:
    setTimeout(function(){console.log(1);},0); (function(){console.log(12);}());
    以上两个函数的执行顺序并不是按照顺序上的先打印1,再打印12;由于给前面的函数设置了0s的延时,执行到此处的时候它就被放进了循环队列,遵循队列后进后出的原理,在执行完成其它代码后再对队列中的代码依次执行。

    下面代码的输出是什么,对其进行修改让fnArr()输出i,使用2种以上的方式

     var fnArr = [];for (var i = 0; i < 10; i ++) {fnArr[i] =  function(){return i;};}console.log( fnArr[3]() );  // 10

    修改1:

     var fnArr = [];for (var i = 0; i < 10; i ++) {fnArr[i] =  function(){return i;}(i);}console.log( fnArr[3] );  //

    修改二:

     for(var i=0;i<5;i++){(function(){var n = i;setTimeout(function(){console.log('delayer:' + n );}, 0);})();console.log(i);}

使用闭包封装汽车对象,并获取状态

    var Car = carSet();function carSet(){var speed = 0;function setSpeed(spe){speed = spe;}function getSpeed(){console.log(speed);return speed;}function accelerate(){speed += 10;}function decelerate(){speed -= 10;}function getStatus(){if(speed === 0){console.log("stop");return "stop";}else{console.log("running");return "running";}}return{setSpeed:setSpeed,getSpeed:getSpeed,decelerate:decelerate,getStatus:getStatus,accelerate:accelerate}}Car.setSpeed(30);Car.getSpeed(); //30Car.accelerate();Car.getSpeed(); //40;Car.decelerate();Car.decelerate();Car.getSpeed(); //20Car.getStatus(); // 'running';Car.decelerate(); Car.decelerate();Car.getStatus();  //'stop';//Car.speed;  //error

使用setTimeot模拟setInterval的功能。

    function getsec(){setTimeout(function(){console.log(new Date().getSeconds());getsec();},1000)}

计算setTimeout的最小时间粒度

    function cTime(){var i = 0;var sta = Date.now();var clo = setTimeout(function a(){i++;if(i === 1000){var end = Date.now();clearTimeout(clo);console.log((end - sta)/i);}clo = setTimeout(a,0);},0);}cTime();

下列代码的输出

// 由于被设置延时的函数会被移动到队列中,等待所有正常执行完成之后再进行执行,所以执行的实际顺序为:
var a = 1;
var a;
console.log(a);   // 1
a = 3;
console.log(a);  // 3
setTimeout(function(){a = 2;console.log(a);
},0)

以下代码的输出

    var flag = true;setTimeout(function(){ // 设置延时后,这段代码被放进队列中,等待所有执行完成之后再执行flag = false;},0)while(flag){}  // 到这里的时候,判断flag一直会使true,无法往下执行,形成死循环console.log(flag);

以上代码在模拟控制台上会输出true,但实际只是假象

使用闭包来让下面这段函数输出delayer: 0, delayer:1...

for(var i=0;i<5;i++){(function(){var n = i;setTimeout(function(){console.log('delayer:' + n );}, 0);})();console.log(i);
}

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


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/510152

相关文章

SpringCloud中的@FeignClient注解使用详解

《SpringCloud中的@FeignClient注解使用详解》在SpringCloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解来标记Feign客户端接口,这篇文章... 在Spring Cloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解

Java Spring 中的监听器Listener详解与实战教程

《JavaSpring中的监听器Listener详解与实战教程》Spring提供了多种监听器机制,可以用于监听应用生命周期、会话生命周期和请求处理过程中的事件,:本文主要介绍JavaSprin... 目录一、监听器的作用1.1 应用生命周期管理1.2 会话管理1.3 请求处理监控二、创建监听器2.1 Ser

JVisualVM之Java性能监控与调优利器详解

《JVisualVM之Java性能监控与调优利器详解》本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1. JVisualVM简介2. JVisualVM的安装与启动2.1 启动JVisualVM2

Java如何从Redis中批量读取数据

《Java如何从Redis中批量读取数据》:本文主要介绍Java如何从Redis中批量读取数据的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一.背景概述二.分析与实现三.发现问题与屡次改进3.1.QPS过高而且波动很大3.2.程序中断,抛异常3.3.内存消

SpringBoot使用ffmpeg实现视频压缩

《SpringBoot使用ffmpeg实现视频压缩》FFmpeg是一个开源的跨平台多媒体处理工具集,用于录制,转换,编辑和流式传输音频和视频,本文将使用ffmpeg实现视频压缩功能,有需要的可以参考... 目录核心功能1.格式转换2.编解码3.音视频处理4.流媒体支持5.滤镜(Filter)安装配置linu

在Spring Boot中实现HTTPS加密通信及常见问题排查

《在SpringBoot中实现HTTPS加密通信及常见问题排查》HTTPS是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护,下面通过本文给大家介绍在SpringB... 目录一、HTTPS核心原理1.加密流程概述2.加密技术组合二、证书体系详解1、证书类型对比2. 证书获

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

eclipse如何运行springboot项目

《eclipse如何运行springboot项目》:本文主要介绍eclipse如何运行springboot项目问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目js录当在eclipse启动spring boot项目时出现问题解决办法1.通过cmd命令行2.在ecl