闭包
作用域
某变量具有xx作用域意味着其在xx内都可以被调用
- 全局作用域:window
- 模块作用域
- 函数作用域:涉及闭包
- 块级作用域:for
作用域链
- 保证执行上下文有权访问的所有变量
- 保证函数的有序访问
- 作用域链是静态的,在声明时就已经确定
// 全局环境
var a = "全局环境";
function A() {
var a = "局部环境";
B();
}
function B() {
console.log(a);
}
A();
- 假如A()中调用B()
- 但A()在B()之前
- 但B()的外层只有window,并不能访问A()中B()前变量
闭包
- 函数A里包含了函数B
- 函数B使用了函数A的变量
- 那么函数B被称为闭包,即闭包就是能够读取函数A内部变量的函数。
- 闭包是内层函数对外层函数变量的不释放
需要B调用A中变量
应将B在A中声明,使B成为A内部声明的函数
var a = "全局环境";
function A() {
var a = "局部环境";
return {
B: function () {
console.log(a);
},
};
}
var obj = A();
obj.B(); // "局部环境"
注意不能变量污染
for(var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
回调函数
- 把A函数当作参数传入B函数中,然后B会回头调用A函数
- A可以是匿名函数
<script>
function add(num1, num2, callback) {
var sum = num1 + num2;
callback(sum);
}
function print(num) {
console.log(num);
}
add(1, 2, print); //3
</script>
因为不会A不会被立即执行,所以可以视为异步?
this问题
- 作为回调参数的A中若调用了this,会指向上级作用域(不是B)
解决方法
- 箭头函数:会指向最近的嵌套外层,而不是静态的作用域链
- 在调用回调函数前,为它找到自己的this,并起别名
function createData(callback){
callback(999);
}
var obj ={
data:100,
tool:function(){
var self = this; //这里的this指向obj,然后当一个变量取用
createData(function(n){
self.data = n;
})
}
}