JavsScript 闭包 (Closure)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JavsScript 闭包 (Closure),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3661字,纯文字阅读大概需要6分钟。
内容图文
欢迎各位大佬指导!!!
前言:
? 要理解闭包首先需要了解javascript的变量作用域,JavaScript的变量作用域分为两种:
- 全局作用域
- 局部作用域
全局变量的作用域是全局性的,在整个javaScript程序中都在,而在函数内声明的变量作用域,只在函数内起作用。
eg: 在JavaScript中函数内部可以直接访问全局作用域的变量
var a = 123; // 定义全局变量 a
function fn(){
alert(a); // 在函数内部访问全局变量a
}
fn(); // 调用函数 fn() 弹框结果 123
但是函数内的局部变量,在外面不能访问到。
function fn(){
var a = 123; // 定义局部变量
}
alert(a); // a 未定义
注意:在函数内部定义局部变量时,如果没有用 var 声明,那这个变量就是全局变量。即外部就可以访问到这个变量。
如果想要获取函数内定义的局部变量,那么用闭包就可以获取到函数内部的局部变量。
闭包的概念 : 闭包是指有权访问一个函数作用域中的变量的函数。
? 那么闭包的作用就很明显了:
- 可以在函数外部访问到函数内部的局部变量。
- 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。
是否使用闭包要考虑这两点:隔离和数据保存。如果需要隔离数据并形成命名空间,可以使用匿名自执行函数 ;如果还需要在隔离状态下保存数据,保存之后后面还可以继续使用,那就可以使用闭包,如果及不需要隔离和数据保存,那就使用普通函数,在函数调用完后,数据就释放了。
来看下面的两端代码
代码一:
var name ="The Window";
var object = {
name : "My Object",
getNameFunc:function(){
return funcion(){
return this.name;
}
}
};
alert(object.getNameFunc() ());
运行结果: The Window
代码二:
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function(){
var that = this;
return function(){
return that.name;
}
}
};
alert(object.getNameFunc() ());
运行结果: My Object
思考一下,这是为何??
我们来分析一下,首先来看代码一:
// 首先在Javascript中 定义全局变量、全局对象、全局函数 都自动属于window对象的成员。也就是说它们都是window对象的属性,可以用window.出来。
var name = "The Window"; // 这是定义了一个name 的全局变量
var object = { // 这是定义了一个object 的全局对象
name: "My Obejct", // 局部变量 name
getNameFunc: function(){ // 局部函数 getNameFunc 返回的是一个匿名函数
return function(){
// 此处的this 指的是window对象,为什么这样说呢,是因为哪个对象调用this所在的函数,this指的就是哪个对象。
// alert(object.getNameFunc() ()) 首先调用了 object.getNameFunc的函数返回了一个匿名函数function(){return this.name} 此时这个匿名函数是全局函属于window对象,所以在调用匿名函数的时候,return this.name 的结果是 The Window
return this.name;
}
}
};
alert(object.getNameFunc() ());
我们再来分析一下 代码二:
var name = "The Window"; // 同样定义全局的name变量
var object = { // 定义全局的object全局对象
name: "My Object", // 定义局部变量
getNameFunc: function(){ // 定义局部函数 getNameFunc()
var that = this; // 此时当alert(object.getNameFunc()()) 调用时object调用getNameFunc函数,哪个对象调用this,this指的就是哪个对象,显然this指向的是object对象。然后 var that = this 将 object对象赋值给 that 然后返回匿名函数此时匿名函数中引用了that变量,所有当再次的调用匿名函数是return that.name 就等同于 return object.name 即输入结果为 My Object
return function(){
return that.name;
}
}
};
alert(object.getNameFunc() ());
OK,我们来看一道经典题
function fun(n,o){
console.log(o);
return {
fun:function(m){
return fun(m,n);
}
}
}
var a = fun(0);a.fun(1);a.fun(2);a.fun(3); //输入结果: undefined 0 0 0
var b = fun(0).fun(1).fun(2).fun(3); //输入结果: undefined 0 1 2
思考一下,OK ,我们来分析一下产生结果的原因。
var a = fun(0);a.fun(1);a.fun(2);a.fun(3); // 我们来拆分一下这段代码
var a= fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
// 当执行第一行代码时,调用最外面的fun(n,o)函数,传入0,所以console.log(o)的结果为undefined,因为只传了一个参数。然后返回一个对象
// {fun:function(m){return fun(m,n)}}
// 将这个对象赋值给了变量a 即 a = {fun:function(m){return fun(m,n)}}
// 执行第二行代码时,调用fun:function(m)函数,此时m为1;因为a是第一次的对象传入了0。 所以此时的 n 为0;即 return fun(1,0) 再次调用最外面的fun(n,o)函数,打印o为0;
// 当执行第三行代码时,还是调用fun:function(m)函数,此时m为2;因为a是第一次的对象传入了0。 所以此时的 n 为0;即 return fun(2,0) 再次调用最外面的fun(n,o)函数,打印o为0;
// 当执行第四代码时,同上;打印o为0;
Ok ,第一个分析完毕,我们再来分析一下第二个输入出结果。
var b = fun(0).fun(1).fun(2).fun(3); // 同样我们把这行代码拆分一下
var b = fun(0)
.fun(1)
.fun(2)
.fun(3);
// 当执行第一行代码时,依然是调用最外面的fun(n,o)函数,并且传入n=0; 即第一次打印的o为undefined,然后返回一个对象
// {fun:function(m){return fun(m,n)}}
// 当执行第二行代码时,调用fun:function(m)函数,因 .fun(1) 此时m为1;此时 n 为上一次的值 0 ,即 return fun(1,0),再次调用最外面的函数 fun(n,o)
// 此时n 为 1; 打印 o 为 0 ,然后 return 返回。
// 当执行第三行代码时,调用fun:function(m)函数,因 .fun(2) 此时m为2;此时 n 为第二行执行后的值, n=1; 即 return fun(2,1) ,再次调用最外面的函数 fun(n,o) 此时 n 为 2 , o 为 1 ,即 打印 1,然后返回。
// 当执行第四行代码时,调用fun:function(m)函数,因 .fun(3) 此时m为3;此时 n 为第三行执行后的值, n=2; 即 return fun(3,2) ,再次调用最外面的函数fun(n,o) 此时 n 为 3 , o 为 2,即 打印 2, 然后返回。
未完待续。。。。。
原文:https://www.cnblogs.com/1204it-ly/p/13903189.html
内容总结
以上是互联网集市为您收集整理的JavsScript 闭包 (Closure)全部内容,希望文章能够帮你解决JavsScript 闭包 (Closure)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。