理解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的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
随机推荐
- Mailbox and Mail
#ifndef __MAILBOX_H__ #define __MAILBOX_H__ #include <stdint.h> #include <stdlib.h> #inc ...
- ST10 Bootstrap Loader
Bootstrap Loader The built-in bootstrap loader (BSL) of the ST10F269 provides a mechanism to load th ...
- php safe mode bypass all <转>
PHP safe mode bypass from 4.x to 5.x all. Functions: * mb_send_mail* curl_init* imap_open* mail* ion ...
- 关闭IE窗口
$a=(New-Object -comObject Shell.Application).Windows() ($a|?{$_.locationname -eq "人力与人才信息管理系统&q ...
- ICPC-CAMP day1 D.Around the world
Around the world 题目连接: 无 Description 给你一个n*n的矩阵,然后a[i][j]表示i,j是否有一条边 然后让你构造一个序列,使得i到(i+1)%n这两个点之间最多经 ...
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树/半回文串
E. Ann and Half-Palindrome Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contes ...
- 关于ORACLE DUAL表
1.DUAL表的用途 Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中--查看当前连接用户 SQL> select user from d ...
- char.js专门用来做数据统计图
<canvas id="cashback" width="930" height="460"></canvas>&l ...
- impdp的一些实际问题解决方法
之前在http://blog.csdn.net/bisal/article/details/19067515写过一篇关于expdp和impdp的实践的帖子.今天碰到个问题,有些内容没有介绍全,这里再补 ...
- IOS编程之通讯录
// // ViewController.m // LearnAddressBook0 // // Created by Mac on 14-7-28. // Copyright (c) 20 ...