简介:很多概念不清或忘记,重新构建自己的知识体系。每天问自己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);//一秒
}
答案:打印10个10这道题涉及了异步、作用域、闭包?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

填坑-十万个为什么?(13)相关推荐

  1. 填坑-十万个为什么?(24)

    简介:很多概念不清或忘记,重新构建自己的知识体系.每天问自己1~多个问题.我是菜鸟 成为大神之路! 1.Es6 Class通过extends关键字实现继承 Link Class & exten ...

  2. 填坑-十万个为什么?(22)

    简介:很多概念不清或忘记,重新构建自己的知识体系.每天问自己1~多个问题.我是菜鸟 成为大神之路! 1.认识exportLink export export语句用于在创建JavaScript模块时,从 ...

  3. 填坑-十万个为什么?(18)

    简介:很多概念不清或忘记,重新构建自己的知识体系.每天问自己1~多个问题.我是菜鸟 成为大神之路! 1.学习Promise? Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返 ...

  4. flink1.13.5编译,各种填坑

    系列文章目录 文章目录 系列文章目录 前言 一.源码准备 二. 修改pom 三.编译 1.编译失败 2. 填坑 2.1 填坑1 2.2 填坑2 仓库没有confluent.version>5.3 ...

  5. java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得

    该文章出自:http://www.cnblogs.com/hucn/p/3572384.html 分析工具:http://www.blogjava.net/jjshcc/archive/2014/03 ...

  6. 传统行业转型微服务的挖坑与填坑

    原文:传统行业转型微服务的挖坑与填坑 一.微服务落地是一个复杂问题,牵扯到IT架构,应用架构,组织架构多个方面 在多家传统行业的企业走访和落地了微服务之后,发现落地微服务是一个非常复杂的问题,甚至都不 ...

  7. 卷积神经网络「失陷」,CoordConv来填坑

    卷积神经网络「失陷」,CoordConv来填坑 作者:Rosanne Liu等 卷积神经网络拥有权重共享.局部连接和平移等变性等非常优秀的属性,使其在多种视觉任务上取得了极大成功.但在涉及坐标建模的任 ...

  8. 即将上线的flume服务器面临的一系列填坑笔记

      即将上线的flume服务器面临的一系列填坑笔记 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.flume缺少依赖包导致启动失败! 报错信息如下: 2018-10-17 ...

  9. 开发工具总结(2)之全面总结Android Studio2.X的填坑指南

    前言:好多 Android 开发者都在说Android Studio太坑了,老是出错,导致开发进度变慢,出错了又不知道怎么办,网上去查各种解决方案五花八门,有些可以解决问题,有些就是转来转去的写的很粗 ...

最新文章

  1. 业务方的一堆需求,被我一句话怼回去了!CTO笑而不语,晋升有望了
  2. mysql必知必会_《MySQL必知必会》学习小结
  3. 长方形与圆最近连线LISP_常见图形,圆形、长方形和正方形面积的计算
  4. centos安装nodejs
  5. Centos7特性——systemd
  6. mysql联表查询多记录显示_数据库:MySQL(多表的表记录的查询)(三)
  7. 【Interfacenavigation】风格和主题(21)
  8. C# 如何获取屏幕分辨率缩放比例
  9. a标签连接空标签的方法
  10. 任达华遇袭是效仿“宏颜获水”事件?百度回应:严惩肇事者 以儆效尤
  11. 用自己的数据集训练Mask-RCNN实现过程中的坑
  12. 基础知识及命令(1)
  13. c 语言tcp实现电子词典项目
  14. java 视频截图_获取视频截图
  15. 注意力机制attention和Transformer
  16. 学术论文的标准格式是什么?写论文有哪些小技巧?
  17. 最新《择善教育》C/C++黑客编程项目实战教程
  18. ABP中的数据过滤器
  19. 第七章·【第一次上岗:核桃编程】
  20. windows10多桌面创建 切换 和分屏

热门文章

  1. sqlserver 查询中文查询不到 查询英文可以查到_估值数据和财报数据查询方法
  2. python输出矩阵的转置_Python 矩阵转置的几种方法小结
  3. python类有什么用_python 定制类 有什么用
  4. python if name main 的作用_Python中if __name__ == __main__: 的作用
  5. linux离线安装redmine_Linux 下一款非常好用的翻译软件
  6. 属于服务器操作系统的是,属于服务器操作系统的是
  7. sublime-text-3设置输入中文方法
  8. WIX(20121031) 应用设置默认变量
  9. 嵌入式系统UBOOT
  10. Java数据类型(基本数据类型)学习