ife task0003学习笔记(三):JavaScript闭包
一、this易错分析
在学习闭包的时候,有一个概念this很重要,关于this的理解,下面3种情况:this指向谁?
fn.call(obj1);
obj2.fn()
fn()
答案是obj1 obj2 window
判断this的指向有3条规则:
执行函数的过程中肯定存在两方,一方是调用函数的人caller,一方是被调用的人callee,callee永远是函数fn,caller遵循以下的规范:
- fn.call(xxx) fn.apply(xxx)的时候,this永远指向xxx
- ooo.fn()或者ooo['fn']()的时候,this永远指向ooo
- fn()的时候this指向window
所以针对上面代码:
call/apply的作用是改变函数的调用者,或者说是改成this,改变this为 call /apply的第一个参数
一个函数没人调用的时候,相当于window调用了他
函数中除去this和arguments的其它变量,均遵守闭包规则,闭包的位置永远是函数定义的位置。
二、闭包易错代码分析
下面看两个代码实例,它们来源于阮一峰的文章闭包讲解。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
返回结果是:
the window
分析:
alert(object.getNameFunc()());
这个里面有2个括号,要分析两次,把语句拆开:
第一步:var fn = object.getNameFunc();这时执行getNameFunc的时候,this是object,第一次return返回:function(){return this.name;}
第二步fn(),这时候函数由于没有调用者,根据规则3,函数的this ->window,这个函数里面的this.name实际上是window.name
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc());
返回结果:My Object
分析
同样分成两步执行:
第一步执行:var fn = object.getNameFunc();这个时候,this指向object,同时在函数执行的过程中,在getNameFunc所在的闭包内创建了变量that,that = this 所以that指向object,然后第二步执行fn(),这个时候由于没有作用对象,fn里面的this指向window,但是我们在这访问的是that.name,在fn里面没有找到叫that的东西,然后根据闭包规则找到fn的上一级闭包getNameFunc,我们发现在这有一个变量that,它指向object,所以that,name就是object.name,是my object
由此可见,闭包的概念更好理解了:
- 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
- 闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配
- 当在一个函数内定义另外一个函数就会产生闭包
简单来说,闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁。周爱民说得更清楚,闭包就是“属性表”,闭包就是一个数据块,闭包就是一个存放着“Name=Value”的对照表。就这么简单。但是,必须强调,闭包是一个运行期概念。有两个主要特点:
- 作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
- 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
三、闭包的作用
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中。
四、闭包的缺点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
参考资料:
学习Javascript闭包:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
javascript的闭包:http://www.cnblogs.com/rubylouvre/archive/2009/07/24/1530074.html
JavaScript 闭包深入理解:http://www.jb51.net/article/18303.htm
理解 Javascript 的闭包:http://www.oschina.net/question/28_41112
ife task0003学习笔记(三):JavaScript闭包的更多相关文章
- ife task0003学习笔记(一):JavaScript作用域
在学习JavaScript作用域概念之前,首先要明白几个概念:执行环境.变量对象.作用域链. 一.JavaScript执行环境(execution context): 在<Professiona ...
- ife task0003学习笔记(五):JavaScript面向对象
JavaScript 支持函数式编程.闭包.基于原型的继承等高级功能.在 Java 等面向对象的语言中,this 关键字的含义是明确且具体的,即指代当前对象.而在 JavaScript 中,this ...
- ife task0003学习笔记(四):JavaScript构造函数
JavaScript创建对象主要是3种方法:工厂模式.构造函数模式.原型模式.其实对于构造函数的概念,我们并不陌生.在之前学习c++语言的时候,也有提到过构造函数的概念.除了创建对象,构造函数(con ...
- ife task0003学习笔记(二):JavaScript原型
function aaa(){} aaa.prototype.bbb=function(){} var obj1=new aaa() var obj2=new aaa() obj1和obj2都有一个属 ...
- 【学习笔记】JavaScript的基础学习
[学习笔记]JavaScript的基础学习 一 变量 1 变量命名规则 Camel 标记法 首字母是小写的,接下来的字母都以大写字符开头.例如: var myTestValue = 0, mySeco ...
- amazeui学习笔记三(你来我往1)--常见问题FAQs
amazeui学习笔记三(你来我往1)--常见问题FAQs 一.总结 1.DOM事件失败:记得加上初始化代码,例如 图片轮播 $('#my-slider').flexslider(); 2.jquer ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- RX学习笔记:JavaScript数组操作
RX学习笔记:JavaScript数组操作 2016-07-03 增删元素 unshift() 在数组开关添加元素 array.unshift("value"); array.un ...
随机推荐
- C# -- 泛型(3)
简介: 前两篇文章讲了关于泛型的一些基础,下面笔者通过这篇文章来给刚刚接触泛型的朋友介绍一下 <1>.原理性的东西----” 泛型的协变和逆变 “ <2>.以及常用的接口--- ...
- db2中临时表在存储过程中的使用
DROP PROCEDURE ADMINISTRATOR.SP_TEST (INTEGER, CHARACTER ()); CREATE PROCEDURE administrator.sp_test ...
- 系统架构一:snmp+mrtg服务器监控
//@author:yuan<turing_zhy@163.com> 码字不易,转载请注明出处 #================================== 开始,服务器准备 ...
- WebApi跨域问题解决
因为第一次用webapi,并且还是前后台分离,所以设置到了跨域,在百度上找了很多解决办法,但是基本都存在缺陷,我这里分享一下我自己的经验 1.首先配置Web.config 这样配置发布到服务器就可以跨 ...
- thedao
TheDao 简化版解释 the Dao 合约 contract f1{ function transfer() { if (acccount[m]>=100) { m.send(100) ac ...
- Selenium辅助工具
下载Firefox39.0版本浏览器,安装firebug和FirePath.最新版的Firefox在扩展组件中无法找到firebug,可以使用旧的版本的Firefox浏览器. FirePath插件的使 ...
- React + Dva + Antd + Umi 概况
Dva 由阿里架构师 sorrycc 带领 team 完成的一套前端框架,在作者的 github 里是这么描述它的:"dva 是 react 和 redux 的最佳实践". Ant ...
- 【转载】Java资源大全中文版
Java资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-java 就是 akullpp 发起维护的 Java 资源列表,内容 ...
- 题解 P1436 【棋盘分割】
题目链接 其实呢大致思路和下面的大佬们都很像.发这篇题解的目的就是加了一点~~优化~~骗分技巧. 转移方程: 设$dp[i][j][x][y][k]$表示左上$(i,j)$,右下$(x,y)$,第$k ...
- logback&slf4j学习笔记
1.Slf4j 1.1.Slf4j简介 SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.实际上,SLF ...