js基础之闭包

闭包

闭包是一种实现方式(俺是这样想的),可以是一个可执行函数,js的每个对象其实都是闭包的实现方式。

闭包的特性

  • 闭包可以访问外部作用域,即使这个外部作用域已经执行结束。
  • 当你定义一个函数时候,实际就是一种闭包的实现方式。只有当这个函数不被其他任何地方调用的时候,闭包就结束了。
  • 闭包可以让作用域里的 变量,在函数执行完之后依旧保持没有被垃圾回收处理掉

使用示例

举个栗子:

	"use strict";
	var myClosure = (function outerFunction() {
  	var hidden = 1;
	return {
	    inc: function innerFunction() {
	      return hidden++;
	    }
	  };
	}());
	console.log(myClosure.inc()); // 1
	console.log(myClosure.inc()); // 2
	console.log(myClosure.inc()); // 3

我们可以看到,当我们运用了外部作用域的变量的时候,闭包并没有结束,而是当不在有调用的时候,才将闭包销毁。

经典面试题

上题!

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
}

console.log(new Date, i);

会怎么输出呢?正确答案是:5, 5, 5,5,5,5。
他们之间的输出时间是怎么样的呢?
用箭头表示其前后的两次输出之间有 1 秒的时间间隔,而逗号表示其前后的两次输出之间的时间间隔可以忽略。则结果是这样的:
5 -> 5,5,5,5,5。因为循环过程中,几乎是同时设置了5个定时器。

那么应该怎么修改代码,让期望结果变成:5 -> 0,1,2,3,4。走着:

for (var i = 0; i < 5; i++) {
    (function(j) {  // j = i
        setTimeout(function() {
            console.log(new Date, j);
        }, 1000);
    })(i);
}

console.log(new Date, i);

我们 “创建了一个匿名函数并立刻执行”。达到了期望的效果。那么还有没别的办法呢?我们知道setTimeOut方法第三个参数是可选的。当定时器到期,它们会作为参数传递给function 。所以可以这样写:

for (var i = 0; i < 5; i++) {
    setTimeout(function(j) {
        console.log(new Date, j);
    }, 1000, i);
}

console.log(new Date, i);

或者我们可以将i重新赋值:

var output = function (j) {
    setTimeout(function() {
        console.log(new Date, j);
    }, 1000);
};

for (var i = 0; i < 5; i++) {
    output(i); 
}
console.log(new Date, i);

或者使用let声明变量i:

for (let i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
}

// console.log(new Date, i); // 会报错。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值