填坑-十万个为什么?(13)

简介:很多概念不清或忘记,重新构建自己的知识体系。每天问自己1~多个问题。我是菜鸟 成为大神之路!

1. 经典面试题 for(var i=0;i<=3;i++){ setTimeout(function() { console.log(i) }, 10);}打印结果?分析?

for(var i = 0; i < 10; i++) {console.log(new Date(),i);setTimeout(() => {console.log(new Date(),i)}, 1000);//一秒
}
答案:打印1010这道题涉及了异步、作用域、闭包?settimeout是异步执行,1ms后往任务队列里面添加一个任务,只有主线上的全部执行完,才会执行任务队列里的任务,
当主线执行完成后,i是10,所以此时再去执行任务队列里的任务时,i全部是10了。?对于打印10次是:每一次for循环的时候,settimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,
等待执行,for循环了10次,就放了10次,当主线程执行完成后,才进入任务队列里面执行。
(注意:for循环从开始到结束的过程,需要维持几微秒或几毫秒。)
复制代码

① 若要输出从0到9,将 var 改为 let
for(let i = 0; i < 10; i++) {console.log(new Date(),i);setTimeout(() => {console.log(new Date(),i)}, 1000);//一秒
}当我把var 变成let 时
?打印出的是:0~10当解决变量作用域,因为for循环头部的let不仅将i绑定到for循环快中,
事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。?setTimeout里面的function()属于一个新的域,通过 var 定义的变量是无法传入到这个函数执行域中的,
通过使用 let 来声明【块变量】,这时候变量就能作用于这个块,所以 function就能使用 i 这个变量了;?这个匿名函数的参数作用域 和 for参数的作用域不一样,是利用了这一点来完成的。
这个匿名函数的作用域有点类似类的属性,是可以被内层方法使用的。
复制代码
② 若要输出从0到9,改写为闭包

闭包相关解释下一问。

// 使用闭包
for(var i = 0; i < 10; i++) {console.log(new Date(),i);(function (i) {setTimeout(() => {console.log(new Date(),i);}, 1000);})(i);
}
复制代码

2.闭包的作用域?代码执行过程?

经常遇到闭包的相关问题

代码一:
// 以1问中例子为例
for(var i = 0; i < 10; i++) {console.log(new Date(),i);(function (i) {setTimeout(() => {console.log(new Date(),i);}, 1000);})(i);
}
代码一是闭包,写为代码二不为闭包的形式,(function(i){})(i) '理解为自执行函数' 自执行函数的相关参考在12天和参考文章中,之后我会对着一块内容进行学习?。代码二:
var fun = function(x){setTimeout(() => {console.log(new Date(),x);}, 1000);}for(var i = 0; i < 10; i++) {console.log(new Date(),i);fun(i);
}
复制代码
JavaScript 变量可以是局部变量或全局变量。
私有变量可以用到闭包。什么是闭包:
> 就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
> 就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配
> 当在一个函数内定义另外一个函数就会产生闭包
> "注:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。"注意:通常人们对闭包的理解是不完全的,认为在 JavaScript 中只有嵌入的函数才是闭包。但其实任何拥有 free variable(自由变量)
的函数都是以闭包的形式存在的。因为本质上,闭包是 free variable 问题的一种解决方案。http://liximomo.github.io/javascript-closure闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),
把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
复制代码

闭包需要注意的两种情况----函数作为返回值,函数作为参数传递。

例子:函数作为返回值

1. function greeting(name) {
2. 		var text = 'Hello '; // local variable// 每次调用时,产生闭包,并返回内部函数对象给调用者
3. 		return function() {return text += name; }}4. 	var sayHello=greeting("Closure");5. 	document.write(sayHello());
6. 	document.write("<br>");
7. 	document.write(sayHello());
8. 	document.write("<br>");
9. 	document.write(sayHello());
10. document.write("<br>");
11. document.write(sayHello());
12. document.write("<br>");
13. document.write(sayHello());// 通过闭包访问到了局部变量text代码解析:
> 执行第4行时第一行的函数运行一次,返回内嵌函数引用作为第4行sayHello变量的值。
> 之后的第5到13行执行的函数操作其实只是执行sayHello指向的函数(即返回的内嵌函数)。
> 解释text为什么能自增,闭包的概念。复制代码

例子:函数作为参数传递

1. var num = 10;2. var fun = function(var num){
3.    console.log(num);}
4. !function(f){
5.     var num = 100;
6.     f(num);
7. }(fun)代码解析:
> 第四行'!'表示高优先级,被'!'标注的先执行。
> 第7行将fun指向的引用2行函数传给参数f在函数中执行f(?)函数,此时log出来的值是10。
> 解释看js作用域
复制代码

3.var let const的区别?

① 什么是var的变量提升补充2019年1月5日23:31:41 来源网易课堂
'代码1'
var a = 10;
function foo(){console.log(a);//打印:10
}
'代码2'
var a = 10;
function foo(){console.log(a);//打印:undefinedvar a = 5;
}
'问代码2为什么输出的是undefined这里变量提前了,实际代码相当于如下'
'代码3'
var a = 10;
function foo(){var a;console.log(a);//打印:undefineda = 5;
}
复制代码
② let 声明的变量只在它所在的代码块有效
function demo(){{var a = 12;let c = 10;console.log(a);//这里会打印出12;console.log(c);//这里会打印出10;}console.log(a);//这里会打印出12console.log(c);//这里打印出的内容为 "c is not defined";//说明声明的c变量只在{}代码块中能够访问,其他地方都访问不到;
}
demo();
复制代码
③ let不存在变量提升

let 不像var 那样会发生 '变量提升' 现象,因此,变量需要先声明然后再使用,否则报错;

// var 的情况
console.log(vardata);  // undefined
var vardata = 2;// let的情况;
console.log(letdata);  // letdata is not defined 报错
let letdata = 2;
复制代码
④ let暂时性死区

快级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部影响;

var tmp = 123;
if (true) {tmp = 'abc';let tmp;console.log(tmp); // tmp is not defined
}
复制代码
⑤ let不允许重复声明

let 不允许在相同作用域内,重复声明同一个变量。

function foo() {let v = 10;var v = 1;//Identifier 'v' has already been declaredconsole.log(v);
}
foo();function foo1() {let v1 = 10;let v1 = 1;//Identifier 'v1' has already been declaredconsole.log(v1);
}
foo1();
复制代码
⑥ const 声明一个只读的常量,一旦声明,常量的值就不允许改变
⑦ const 一旦声明了变量,就必须初始化,不能留到以后赋值。如果使用const声明一个变量,但是不赋值,也会报错
⑧ const 的作用域与let命令相同;只在声明所在的块级作用域内有效。
⑨ const 不可重复声明 (和let一样)

参考文章:
① let的含义及let与var的区别
② 闭包文档
③ 博客-深入理解javascript原型和闭包
④ JS关于闭包
⑤ 函数 + 函数创建时的环境 = 闭包

转载于:https://juejin.im/post/5c26e9cbe51d450cfe737dae

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WordPress分类列表函数:wp_list_categories用法及参数详解举例

http://www.511yj.com/wordpress-wp-categories.html 注意&#xff1a; 1、 wp_list_categories() 和 list_cats() 以及 wp_list_cats() 的使用类似&#xff0c;但是后面 2 个已经弃用。 2、如果你希望不格式化输出分类&#xff0c;请使用 get_categories() 3、因为 WordPress …

DVP,LVDS和MIPI

Mipi 接口 和 LVDS 接口区别 主要区别&#xff1a; 1. LVDS接口只用于传输视频数据&#xff0c;MIPI DSI不仅能够传输视频数据&#xff0c;还能传输控制指令&#xff1b; 2. LVDS接口主要是将RGB TTL信号按照SPWG/JEIDA格式转换成LVDS信号进行传输&#xff0c;MIPI DSI接口则…

安装Cornerstone3.1注意点

mac在升级之后就不能社会做任何来源安装,需要在终端运行 sudo spctl --master-disable//添加任何来源的,再次安装就可以的转载于:https://www.cnblogs.com/chengenyan/p/6835970.html

2019我的目标

1 能考上自己理想的高中 2 至少学会一直种语言&#xff08;英语&#xff09; 3 坚持记录每一天&#xff0c;每个星期至少写一遍文章 4 坚持到底 转载于:https://www.cnblogs.com/ta20/p/10203974.html

nodejs开发——require与exports的使用

nodejs开发——require与exports的使用 另一片文章总结&#xff1a;http://www.cnblogs.com/hfultrastrong/p/8036682.html require require函数用于在当前模块中加载和使用别的模块&#xff0c;传入一个模块名&#xff0c;返回一个模块导出对象。模块名可使用相对路径&#x…

jvm 内存溢出问题排查方法

如果你做TCP通讯或者map集合操作&#xff0c;并发处理等功能时&#xff0c;很容易出现 Java 内存溢出的问题。本篇文章&#xff0c;带领大家深入jvm&#xff0c;分析并找出jvm内存溢出的代码。 jvm中除了程序计数器&#xff0c;其他的区域都有可能会发生内存溢出 内存溢出是什么…

一个go1.9.x 编译器内联引起的栈信息错乱的问题分析

2019独角兽企业重金招聘Python工程师标准>>> 背景是在写个日志库&#xff0c;日志库有个很重要的功能就是要打印出调用栈&#xff0c;知道具体是哪个文件&#xff0c;哪个函数调用的Info 等。 然后在测试中发现了一种写法&#xff0c;我自己本机测试一直ok&#xff…

CMOS Sensor的调试经验分享

转自&#xff1a;http://bbs.52rd.com/forum.php?modviewthread&tid276351 CMOS Sensor的调试经验分享      我这里要介绍的就是CMOS摄像头的一些调试经验。   首先&#xff0c;要认识CMOS摄像头的结构。我们通常拿到的是集成封装好的模组&#xff0c;一般由三个部…

Learn Python—表达式、数据类型、流程控制

表达式 在 Python 中&#xff0c;2 2 称为“表达式”&#xff0c;它是语言中最基本的编程结构。表达式包含“值”&#xff08;例如2&#xff09;和“操作符”&#xff08;例如&#xff09;&#xff0c;并且总是可以求值&#xff08;也就是归约&#xff09;为单个值。这意味着在…

监控工具之zabbix server3.4 部署配置

[rootlocalhost src]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [rootlocalhost src]# pwd /usr/local/src 配置zabbix的yum源 [rootlocalhost src]# rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm …

CMOS Sensor基础知识

CMOS Sensor基础知识 曝光时间以行长为单位&#xff1b; PCLK以Hz为单位&#xff1b; 行长以周期数为单位&#xff0c;帧长以行长数为单位&#xff1b;其中周期数就是频率 T 周期以ms为单位&#xff1b; f 频率以Hz为单位&#xff1b; f 1 / T&#xff1b; Vsync Dummy Line…

java获取mp3的时长和播放mp3文件

所需包为jaudiotagger-2.2.6-SNAPSHOT.jar和jl1.0.1.jar。 import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream;import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.audio.mp3.MP3AudioHeader; import org.jaudiotag…

Redis 优缺点

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 Redis 与其他 key - value 缓存产品…

Python并发编程之concurrent.futures

2019独角兽企业重金招聘Python工程师标准>>> concurrent.futures模块提供了一个异步执行callables的高级接口。 可以使用ThreadPoolExecutor和ProcessPoolExecutor。 两者都继承了相同的接口&#xff0c;该接口由抽象的Executor类定义。 一个抽象类&#xff0c;提供…

1.3链表

链表的物理存储结构是用一组地址任意的存储单元存储数据的。不像顺序表占据连续的一段内存空间&#xff0c;而是将存储单元分散在内存的任意地址上。 链表结构中&#xff0c;每个数据元素记录都存放到链表的一个节点&#xff08;node&#xff09;中&#xff0c;而每个节点之间由…

移植opencv3.20到3556AV100

1.移植环境&#xff1a; Ubuntu14.04 arm-hisiv200-linux-opencv3.20 下载地址 2.移植步骤&#xff1a; 1&#xff09;安装cmake-gui 2&#xff09;新建一个opencv目录存放opencv-3.2.0.zip&#xff0c;并解压 击Browse Source选择~/hisi/opencv/opencv-3.2.0 点击Brow…

ngnix 详解

4 Nginx的rpm软件包安装 4.1 安装包在位置 D:\讲课内容--\新巴巴运动网\nginx高并发解决\nginx安装包 4.2 此种安装方式不用安装gcc等编译工具 4.3 安装命令如下 rpm –ivh nginx 5 配置虚拟主机 5.1 什么是虚拟主机 虚拟主机是一种特殊的软硬件技术&#xff0c;它可以将网络上…

iscroll5制作上下拉刷新 tab出现的问题

1.iscoll5插件刷新后如果想改变现实位置如果向下几px可以用 myScroll.scrollBy(0,0);方法&#xff0c;该值是相对当前位置。 2.iscoll5用到tab的时候&#xff0c;用点击生成iscoll对象出现取消不了之前的对象的绑定事件&#xff0c;点击多次后刷新执行多次的问题&#xff0c;解…

初谈逻辑读、物理读、预读

前言&#xff1a; 该文并不全是本人原创&#xff0c;里面的某些原理来自于CareySon。 SQL SERVER数据存储的形式 要理解逻辑读、物理读、预读这三个概念&#xff0c;先要搞懂SQL Server的数据存储方式。 SQL Server数据库包括数据文件和日志文件&#xff0c;一个数据库可以有一…

Makefile常用万能模板(包括静态链接库、动态链接库、可执行文件)

1、生成可执行文件的makefile2、生成静态链接库的makefile3、生成动态链接库的makefile 本文把makefile 分成了三份&#xff1a;生成可执行文件的makefile&#xff0c;生成静态链接库的makefile&#xff0c;生成动态链接库的makefile。 这些makefile都很简单&#xff0c;一般都…