闭包与循环的尝试
来源:互联网 发布:股票交易软件 策略 编辑:程序博客网 时间:2024/05/18 03:22
闭包与循环的尝试
for(var i =0; i <= 5; i++) { var old = new Date().getTime(); setTimeout(function timer() { let newT = new Date().getTime(); console.log("time", newT - old); console.log(i); }, i * 1000);}
输出结果:
time 6
6
time 1001
6
time 2002
6
time 3002
6
time 4001
6
time 5001
6
在上面的代码中,setTimeout对timer函数进行了引用,而timer函数对i进行了引用,回掉函数与i的变化是不同步的,i已经变到6的时候,可能timer函数还没有开始运行
for (var i=1; i<=5; i++) { (function() { setTimeout( function timer() { console.log( i ); }, i*1000 ); })();}
输出结果为:
6
6
6
6
6
6
虽然这里用到了自执行函数,但是和上面的原因是一样的
for(var i = 0; i < 5; i++) { (function() { var j = i; setTimeout(function timeer() { console.log(j); }, j*1000); })();}
或是这样
for(var i = 0; i < 5; i++) { (function(j) { setTimeout(function timeer() { console.log(j); }, j*1000); })(i);}
结果:
0
1
2
3
4
在第一个中,由于自执行函数的存在,形成了一个块级作用域,在每次执行这个自执行函数的时候,j每次都是需要重新声明的,所以对于每一次的setTimeout中的j都是不一样的。
在第二种,给自执行函数传递了参数i,timeer函数中拥有自己的形参变量,所以每次的执行结果会不相同,虽然这两种的实现方式不太一样,但是基本的思路都是一致的,借助自执行函数,让每个timeer拥有不同的j或者是形参
for(var i = 0; i < 5; i++) { let j = i; setTimeout(function timer() { console.log(j); }, j*1000);}
运行结果同上,对于let而言形成了一个块级作用域,所以每次的j也就是不同的了
for(let i = 0; i < 5; i++) { setTimeout(function timer() { console.log(i); }, i*1000);}
for 循环头部的let声明有一个特殊的行为,这个行为指出变量在循环过程中不止被声明一次,每次迭代都会声明,随后的每个迭代都会使用上一个迭代结束的值来初始化这个变量
this
this
是一个语言中的关键字,this
这个对象是谁取决于函数被调用的方式,简单来说,就是“谁调用的,就是谁”
var obj = { id : 'awesome', cool: function foolCool() { console.log(this.id); }}var id = "not awesome";obj.cool(); //awesomesetTimeout(obj.cool, 100); //not awesome
对于obj.cool()
,由于是obj
调用的cool
,则在cool
的内部,this
指代的就是obj
这个对象,所以this.id
输出的就是obj
的id
,也就是awesome
在setTimeout(obj.cool)
中由于setTimeout
对obj.cool
这个函数存在引用,形成了闭包,所以此时cool函数中的this也就是调用setTimeout的对象,就是window,所以输出的结果就是not swesome
保存this
var obj = { count: 0, cool: function coolFn() { var self = this; //保存当前的this对象 if (self.count < 1) { setTimeout( function timer(){ self.count++; console.log( "awesome?" ); }, 100 ); } }};obj.cool(); // 酷吧?
var obj = { count: 0, cool: function coolFn() { if (this.count < 1) { setTimeout( () => { // 箭头函数 this.count++; console.log("this: ", this, "count: " , this.count); }, 100 ); } }};var count = -1;obj.cool(); setTimeout(obj.cool, 100);
用当前的词法作用域覆盖了 this 本来的值
执行结果:
this: Object {count: 1, cool: function} count: 1
this: Window {stop: function, open: function, alert: function, confirm: function, prompt: function…} count: 0
var obj = { count: 0, cool: function coolFn() { if (this.count < 1) { setTimeout( function timer(){ this.count++; // this 是安全的, 因为 bind(..) console.log(this.count); }.bind( this ), 100 ); // look, bind()! } }};var count = -100;obj.cool(); setTimeout(obj.cool, 100);
执行结果:
1
-99
- 闭包与循环的尝试
- 闭包与for循环
- javascript循环与闭包
- for循环与闭包
- 关于for循环与闭包的一点点点笔记
- 闭包的循环引用
- for循环的闭包
- for循环的闭包
- 闭包的循环引用
- for循环绑定事件与闭包
- for 循环 addEventListener 与闭包实现
- js闭包与for循环
- 从零开始—尝试java的for循环
- 循环与闭包 之 for循环经典问题解释 / 结合《你不知道的JS》与《高程》案例
- vc++ 尝试类型无关的属性包
- Swift3.0 -- 闭包的循环引用与OC的对比
- 闭包的循环引用问题
- 闭包的循环引用解决
- Pandas 数据结构Series、DataFrame分析
- 驼峰命名法
- PyQT安装和部署
- bzoj1926: [Sdoi2010]粟粟的书架
- java类加载
- 闭包与循环的尝试
- eclipse+gdbserver调试嵌入式linux应用程序
- python类的继承和多态,获取对象信息
- slam应用及应用
- [可持久化Trie] BZOJ3261: 最大异或和
- Spark Streaming 自定义接收器
- Linux Swap 解读
- STM32F103跳过停止模式,不能进入停止模式
- 算法笔记二分治法