闭包
标准话术:函数内部定义一个函数,内部函数能够使用外部变量,这个变量不会被清除
- demo
let yasso = {
q: function () {
let count = 0
return function () {
count ++
console.log( count)
if (count == 3) {
alert('hasaki')
count = 0
} else {
alert('hasai')
}
}
}
}
let q = yasso.q()
q();
q();
q();
当定义q时,JS去找到yasso.q方法的执行结果,这个结果返回一个function,q就暂时绑定到这个function上,这个function 又使用到了他外部的变量count,所以这个count的值就被保存(没有被清除)。
如果 我们 yasso.q() 三次 发现每次count都是1 因为每次count都被重新定义赋值0
垃圾回收机制
- 标记清除 当变量进入环境时,例如,在一个函数中声明一个变量,就将这个变量标记为"进入环境",从逻辑上讲,永远不能释放进入环境变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为"离开环境"。
- 引用计数 一个值被引用一次,他的计数就+1,一个值被覆盖或者删除一次,他的计数就-1,当他的计数到达0的时候就被清除出去
作用域与作用域链
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2; foo();
}
bar();
闭包的应用 curry函数
function add (x,y) {
return x + y
}
function curry(fn, args) {
let len = fn.length
let oldargs = args || []
return function () {
let newargs = arguments
let allargs = [...oldargs, ...newargs]
if (allargs.length < len) {
return curry(fn, allargs)
} else {
return fn.apply(this, allargs)
}
}
}
let curryAdd = curry(add)
// curryAdd(1)(2) == add(1,2)