1.概念
一个具有封闭的对外不公开的,包裹结构或空间。在JavaScript中函数可以构成闭包,一般函数是一个代码结构的封闭结构,即包裹的特性,同时根据作用域规则,只允许函数访问外部的数据。外部无法访问函数内部的数据,即封闭的对外不公开的特性,因此说函数可以构成闭包。
2.闭包要解决什么问题
1.闭包内的数据不允许外界访问。
2.要解决的问题就是间接访问该数据。
函数就是封闭起来的,外部无法访问,可以用return这种方式。
<script>
function fn(){
var num = Math.floor(Math.random()*1000);
return num;
}
var reg1 = fn();
var reg2 = fn();
console.log(reg1);
console.log(reg2);
</script>
两个值肯定是不同的,调用了两次随机数函数。
怎么让两个值相同呢?
<script>
function fn(){
var num = Math.floor(Math.random()*1000);
function foo(){
return num;
}
return foo;
}
var f1 = fn();
console.log(f1());
console.log(f1());
console.log(f1());
</script>
调用fn函数会产生随机数,在这里只调用了一次fn。
3.闭包返回多个数据
用对象的形式
<script>
function fn(){
var num1 = Math.floor(Math.random()*1000);
var num2 = Math.floor(Math.random()*1000);
function getNum1(){
return num1;
}
function getNum2(){
return num2;
}
return {
getNum1:getNum1,
getNum2:getNum2
}
}
var obj = fn();
console.log(obj);
console.log(obj.getNum1());
console.log(obj.getNum1());
console.log(obj.getNum2());
console.log(obj.getNum2());
</script>
4.闭包设置数据
<script>
function fn(){
var name = "lucy";
var age = 19
return {
getAge:function(){
return age;
},
setAge:function(val){
if(val < 0 || val > 130){
console.log("年纪不符合逻辑");
return age;
}
return age = val;
}
}
}
var obj = fn();
console.log(obj);
console.log(obj.getAge());
console.log(obj.setAge(131));
console.log(obj.setAge(22));
</script>
5.上下文调用模式
<script>
function fn(){
console.log(this);
}
fn();
</script>
this指向的是window如果想要更改this,有两种方式,apply、call
apply(要改变的对象,[调用函数的时候的实参])
call(要改变的对象,参数1,参数2......)
1.基本数据类型,this指向该类型的对象。
2.空类型 null 和 undefined,this指向window
3.数组 对象 this 指向 数组 对象
<script>
function fn(){
console.log(this);
}
fn();
fn.apply(new Object,[3,4]);
fn.call(new Object,7,8);
fn.call("xxx")
fn.call(false);
fn.call(new Array());
</script>
6.举例
将函数 fn 的执行上下文改为 obj 对象
function speak(fn, obj) {
return fn.apply(obj);
}