闭包

本文详细解析了JavaScript中的闭包概念,包括其定义、词法作用域、作用域链等核心知识点,并通过实例展示了闭包在封装数据和暂存数据方面的应用。同时,文章提供了多个代码示例,帮助读者理解闭包的工作原理。

#闭包

闭包的定义

一个函数和它的词法作用域的结合

词法作用域

作用域链

  • 函数在执行的过程中,先从自己内部找变量
  • 如果找不到,再从创建当前函数所在的作用域去找,以此往上
  • 注意找的是变量的当前的状态

闭包

函数连同它作用域链上的要找的这个变量,共同构成闭包

一般情况下使用闭包主要是为了

  1. 封装数据
  2. 暂存数据
function car(){
  var speed = 0
  function fn(){
    speed++
    console.log(speed)
  }
  return fn
}

var speedUp = car()
speedUp()   //1
speedUp()   //2
var fnArr = []
for (var i = 0; i < 2; i ++) {
  fnArr[i] =  (function(j){
    return function(){
      return j
    } 
  })(i)
}
console.log( fnArr[1]() ) // 3

a = (function(j)){
	return function(){
		return j
	}
}(i)

function fn2(){
	var j = argument[0]
	function f(){
		return j
	}
	return f
}
b = fn(1)
// b = (function fn(j)){
// 	return function(){
// 		return j
// 	}
// }(i)

function car(speed){
  return function(){
    speed++
    console.log(speed)
  }
}

var speedUp = (function (speed){
  return function(){
    speed++
    console.log(speed)
  }
})(3)

作用域链

  • 执行上下文
  • 活动对象
  • Scope属性

案例

var x = 10
bar()
function foo(){}
function bar(){}

globalContext = {
	AO: {
		x: 10
		foo: function
		bar: function
	}
	Scopr: null
}
//声明foo时,得到下面
foo.[[scope]] = globalContext.AO
//声明bar时,得到下面
bar.[[scope]] = globalContext.AO

在当前执行的上下文内声明的函数,这个函数的[[scope]]就执行当前执行上下文的AO

找一个函数的时候,先从AO中找,找不到的时候,再从创建这个函数所在的作用域Scope中找

封装一个Car对象

如下代码输出多少?如果想输出3,那如何改造代码?

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

封装一个 Car 对象。

var Car = (function(){
   var speed = 0;
   //补充
   return {
      setSpeed: setSpeed,
      getSpeed: getSpeed,
      speedUp: speedUp,
      speedDown: speedDown
   }
})()
Car.setSpeed(30)
Car.getSpeed() //30
Car.speedUp()
Car.getSpeed() //31
Car.speedDown()
Car.getSpeed()  //30
var Car = (function(){
	var speed = 0
	function setSpeed(s){
		speed = s
	}
	function getSpeed(){
		return speed
	}
	function speedUp(){
		speed++
	}
	function speedDown(){
		speed--
	}
	return {
		setSpeed: setSpeed,
		getSpeed: getSpeed,
		speedUp: speedUp,
		speedDown: speedDown
	}
})()

如下代码输出多少?如何连续输出 0,1,2,3,4?

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

补全代码,实现数组按姓名、年纪、任意字段排序。

var users = [
  { name: "John", age: 20, company: "Baidu" },
  { name: "Pete", age: 18, company: "Alibaba" },
  { name: "Ann", age: 19, company: "Tecent" }
]

users.sort(byField('age'))
users.sort(byField('company'))
function byFiled(filed){
	return function(user1,user2){
		return user1[filed]>user2[filed]
	}
}

写一个 sum 函数,实现如下调用方式。

console.log( sum(1)(2) ) // 3
console.log( sum(5)(-1) ) // 4

function sum(a){
	return function(b){
		return a + b
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值