理解js中的闭包
闭包 我的理解是 能够有权访问另一个函数作用域中变量的函数
通常我们知道 普通的函数在调用完成之后,活动对象不会从内存中销毁,其执行环境的作用域链会被销毁,造成资源的浪费 而闭包的好处就在于执行完就会被回收 不会造成资源的极大的浪费 性能也会相应的提升~
闭包的几种写法
- //当只有一个返回的内部函数时候
- //第一种写法
- function test1(a,b){
- return function(c){
- console.log(a + b + c);
- }
- }
- var m1 = test1(2,4);
- m1(5);
- //输出 11
- //第二种写法
- function test2(a,b){
- var name = 'xsdsfsfsdxcxcx';
- function xx(c){
- console.log(a + b + c);
- }
- return xx;
- }
- var m2 = test2(2,4);
- m2(5);
- //输出 11
若有多个需要返回的内部函数 可使用对象的方法一一列举出来 又称模块模式
- // 多个返回的内部函数
- function test2(a,b){
- var name = 'xsdsfsfsdxcxcx';
- function xx(c){
- console.log(a + b + c);
- }
- function ss(){
- // js中replace默认只替换查找到的第一个值 若要替换多个值需要使用正则
- var _replace = name.replace('x','aa');
- console.log(_replace);
- }
- function allReplace(){
- var re = /x/g;
- var _replace = name.replace(re,'X');
- console.log(_replace);
- }
- return {
- xx : xx,
- ss : ss,
- allReplace: allReplace
- }
- }
- var m2 = test2(2,4);
- m2.ss(); //输出 aasdsfsfsdxcxcx
- m2.xx(3); //输出 9
- m2.allReplace(); //输出 XsdsfsfsdXcXcX
简单的案例看下 静态方法和实例方法的区别
- 1 var test1 = function(){
- 2
- 3 }
- 4 test1.Show = function(){
- 5 alert('静态方法!');
- 6 }
- 7 test1.prototype.Display = function(){
- 8 alert('实例方法!');
- 9 }
- 10
- 11 test1.Show(); //静态方法 只能直接用类名进行调用 不能使用this
- //函数才有prototype属性 对象是没有的
- 12 test1.Display(); //报错 这是一个是实例方法 必须先实例化后才能进行调用
- 13
- 14
- 15 var Demo = new test1();
- 16 Demo.Display(); //实例方法
再来看一段代码
- var dom = function(){
- var Name = "Default";
- this.Sex = "Boy";
- this.success = function(){
- alert("Success");
- };
- };
- alert(dom.Name); //undefined 这是因为每个function都会形成一个作用域 而这些变量声明在函数中 所以就处于这个函数的作用域中 外部是无法访问的 必须new一个实例
- alert(dom.Sex); //undefined
再来一段代码
- var html = {
- Name:'Object',
- Success:function(){
- this.Say = function(){
- alert("Hello,world");
- };
- alert("Obj Success");
- }
- };
- //html是一个对象,不是函数,所以没有Prototype属性,其方法也都是公有方法,html不能被实例化。
- //我们可以这样使用它 html.Name 和 html.Success()
- //当然我们也可以将这个对象作为一个值赋给其他变量 比如 var a = html
那么问题来了 我们该如何访问Success方法中的Say方法呢 难道是html.Success.Say()吗? 当然这样式错误的啦 因为在Say方法中又开始了一个新的function形成新的作用域 肯定是访问不到里面的内容啦
得做点修改 比如
- 1 var s = new html.Success();
- 2 s.Say(); //Hello,world
- 3
- 4
- 5 //或者写在外面
- 6 html.Success.prototype.Show = function(){
- 7 alert("HaHa");
- 8 };
- 9 var s = new html.Success();
- 10 s.Show();
说了这么多 那么闭包的用途到底是什么呢?
事实上通过使用闭包 我们可以做很多事情 比如模拟面向对象的代码风格 更优雅 更简洁的表达出代码 这是一个有点追求美感的程序员应该做的 而且在某些方面可以提升代码的执行效率
1 匿名自执行函数
- var data = {
- arr : [2,5,2,4,333],
- tree : {}
- }
- (function(x){
- var row,
- new_arr = [];
- for(var i = 0; i < x.arr.length; i ++){
- row = x.arr[i];
- new_arr.push(row);
- }
- return new_arr;
- })(data) //输出 [2,5,2,4,333]
创建了一个匿名函数 并立即执行 由于外部无法直接访问内部的变量 因此在函数执行完成后会立刻释放资源 还不会污染全局变量
2 缓存作用
将计算结果缓存在内部 之后再调用的话就可以直接使用
3 封装
- var package = function(){
- var name = '张三';
- return {
- getName : function(){
- return name;
- },
- setName : function(names){
- name = names;
- return name;
- }
- }
- }();
- package.getName(); //张三
- package.setName('李四'); // 李四
- package.name; //undefined
4 类和继承
- function Mother(){
- var eye = 'default';
- return {
- getName : function(){
- return eye;
- },
- setName : function(newName){
- name = newName;
- return name;
- }
- }
- }
- var M = new Mother();
- M.getName();
- M.setName('beautiful!');
- var Person = function(){
- }
- //继承
- Person.prototype = M;
- Person.prototype.Say = function(){
- console.log('这是私有方法!');
- }
- var p = new Person();
- p.getName();
- p.setName('hah');
- p.Say();
理解js中的闭包的更多相关文章
- java程序员理解js中的闭包
1.闭包概念: 就是函数内部通过某种方式访问一个函数内部的局部变量 再次理解: 闭包产生原因: 1.内部函数引用了外部函数的变量 作用:延长局部变量的生命周期 让函数外部可以调用到函数内部的数据 利用 ...
- 彻底理解js中的闭包
闭包是js的一个难点也是它的一个特色,是我们必须掌握的js高级特性,那么什么是闭包呢?它又有什么用呢? 我们都知道,js的作用域分两种,全局和局部,基于我们所熟悉的作用域链相关知识,我们知道在js作用 ...
- javascript理解js中的闭包
在javascript中变量有其作用域,如果在函数内部var一个变量,那么在函数外部一般情况下是不能被引用的. function outerFun() { ; alert(a); } ; outerF ...
- js中的闭包之我理解
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- js中的闭包理解一
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- js中的闭包理解
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 详解js中的闭包
前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
随机推荐
- AS:加载新版本的SWF文件。
方案一: 文件名+版本号,区别对待不同的版本控制,有设定值后会加上_v_x的后缀名.如:加载主文件 main.swf, 被命名为:Main_v_60.swf . 方案二: loader.load(ne ...
- Android中全局Application的onCreate多次调用问题
String processName = OsUtils.getProcessName(this, android.os.Process.myPid()); if (processName != nu ...
- intval()和(int)转换使用与区别
<?php echo "<br/>数值强制转换:"; $string="2a"; $string1=intval($string); echo ...
- icacls备份与还原ACL列表(NTFS权限)--Robocopy
icacls c:\windows\* /save AclFile /T- 将 c:\windows 及其子目录下所有文件的 ACL 保存到 AclFile. icacls c:\windows\ / ...
- ARM&Linux 下驱动开发第三节
后台驱动代码如下:比较昨天的,添加了读写指针位置移动操作 #include<linux/init.h> #include<linux/module.h> #include< ...
- 使用GLSL实现的海洋效果 【转】
http://bbs.osgchina.org/viewthread.php?tid=342&extra=page%3D3 虽说自己原创的部分并不算多,不过总算是调试通过了,中间有多次严重的死 ...
- jq获取表单值与赋值代码
jq获取表单值与赋值代码 jq获取表单值与赋值代码 $("#keyword")[0].value = ""; /*获得TEXT.AREATEXT的值*/ var ...
- Ubuntu 14.04 Android 使用Maven二 创建自己的Mavenproject
依据https://code.google.com/p/maven-android-plugin/wiki/GettingStarted 介绍,有两种方法能够创建Mavenproject. 第一种方法 ...
- codeblocks中添加-std=c99
早上用codeblocks编译一个c文件,出现这样一个编译错误: +'for'+loop+initial+declarations+are+only+allowed+in+C99+mode 原来cod ...
- 终端I/O之stty命令
所有的终端选项标志,在程序中都可用tcgetattr和tcsetattr函数(http://www.cnblogs.com/nufangrensheng/p/3576682.html)进行检查和更改. ...