做用域是静态的,在你写代码的时候就肯定了。javascript
执行上下文能够理解为当前代码的执行环境,执行上下文是动态的,在执行调用的时候才会产生。java
function fn1() {
//函数提高,内部函数已经建立。请看图片1
var a = 1
function fn2() {
a++ ////代码执行到这的时候,请看图片3
console.log(a)
}
return fn2 //代码执行到这的时候,请看图片2
}
let fn3 = fn1()
fn3() //代码执行到这的时候,请看图片2
fn3 = null //闭包死亡
复制代码
图片1面试
function Pay(value) { //Pay是一个闭包
let money = value
this.getMoney = function() {
return money
}
this.setMoney = function(value) {
money = value
}
}
let pay = new Pay(8000)
console.log(pay.money) //undefined 在外面没法访问到私有变量money
console.log(pay.getMoney()) //8000 //getMoney这个特权方法能够经过对象访问,getMoney能够访问money
pay.setMoney(10000)
console.log(pay.getMoney()) //1000
复制代码
function myModule() {
let msg = 'hello world' //私有数据
function doSomething() { //操做数据的函数
console.log('dosomething'+msg.toUpperCase())
}
function doOtherthing() {
console.log('doOtherthing'+msg.toLocaleLowerCase())
}
return{
doSomething:doSomething,
doOtherthing:doOtherthing
}
}
//模块的使用者
let module = myModule()
module.doSomething()
module.doOtherthing()
复制代码
for(var i=0;i<lis.length;i++) {
(function(i) {
setTimeout(() => {
alert(i)
}, 1000);
})(i)
}
复制代码
function count() {
let num = 0
return function() { //函数做为返回值
num++
return num
}
}
let fn = count()
fn() //1
复制代码
function demo() {
let name = 'Eileen'
console.log('name')
}
demo() //demo函数执行完,demo函数的做用域没有被外部引用,则该函数的做用域及其变量都会在函数执行完后被销毁
复制代码
function foo() {
let name = 'Eileen'
return function() {
name = 'John'
return name
}
}
let fn = foo()
console.log(fn()
fn = null //在全局做用域中执行fn函数,fn函数的环境依赖于foo函数环境,因此foo函数内的做用域及其变量不会被销毁。fn = null释放对闭包的引用,foo函数做用域被销毁
复制代码
function fun(n,o) {
console.log(o)
return {
fun: function(m) {
return fun(m,n)
}
}
}
var a = fun(0) //undefined
a.fun(1) //0
a.fun(2) //0
a.fun(3) //0
var b = fun(0).fun(1).fun(2).fun(3) //undefined,0,1,2
var c = fun(0).fun(1) //undefined,0
c.fun(2) //1
c.fun(3) //1
复制代码
好啦,以上就是我对闭包的理解和解释啦,若是有不对的地方,欢迎各位大牛指导一下😁bash