Open Reaper622 opened 4 years ago
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
function fn1() { let name = 'reaper' function fn2() { console.log(name) } return fn2 } let fn3 = fn1() fn3()
根据引用的关系,fn3和fn2都指向的是堆中同一个函数,执行fn3能够输出name 证明fn2成功记住并访问了它所在的词法作用域,并且此时fn3在全局环境下执行,已经在fn2函数运行的词法作用域之外。
闭包的一些应用
for 循环 与 setTimeout 问题(输出多次最后的结果) 可以通过闭包解决「也可以通过let解决」,即每次都在内部生成一个私有作用域
for(var i = 1; i <= 10; i++) { (function (j) { setTimeout(function () { console.log(j) }, 1000) })(i) }
闭包的作用:
let singleton = (function () { let age = 22 let speak = function () { console.log('speaking') } return { name: 'reaper', getAge: function () { return age; } } })() singleton.age //undefined singleton.getAge() // 22
或者直接在参数中定义私有变量
function Person(name) { this.getName = function () { return name; } this.setName = function (value) { name = value; } } let person = new Person('reaper'); person.name; // undefined 此处无法获取name属性 person.getName(); //'reaper' person.setName('changed'); person.getName(); // 'changed'
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
根据引用的关系,fn3和fn2都指向的是堆中同一个函数,执行fn3能够输出name 证明fn2成功记住并访问了它所在的词法作用域,并且此时fn3在全局环境下执行,已经在fn2函数运行的词法作用域之外。
闭包的一些应用
for 循环 与 setTimeout 问题(输出多次最后的结果) 可以通过闭包解决「也可以通过let解决」,即每次都在内部生成一个私有作用域
闭包的作用:
或者直接在参数中定义私有变量