前文已经简单的介绍了函数的闭包。函数的闭包就是有权访问另一个函数作用域的函数,也就是函数内部又定义了一个函数。

 var Super=function(num){
var count=num;
return function(){
console.log(count);
}
}
var result=Super(3);//此时result是一个函数
result();//输出3

  上面的代码定义了一个函数Super,同时在Super函数内部又定义了一个匿名函数作为返回值。第七行调用Super函数,此时result是一个函数。第8行执行了result函数,输出为3。这就是闭包的体现,因为上面的Super函数已经执行结束,但是它的内部变量count的值依然没有被释放,count的还在被匿名函数引用,所以没有办法释放。如果要释放count,我们需要 result=null ,将null赋值给result。

  在前文已经介绍了函数的作用域链,当函数第一次被调用时会创建一个作用域链,并作用域链赋值给一个特殊的内部属性。在作用域链中,函数的外部函数的活动对象位于第二位,外部函数的外部函数的活动对象位于第三位,以此类推,全局变量的作用域链位于最底部。

 var count=2;
console.log(count);//
count=3;
console.log(count);//
var Super=function(num){
var count=num;//作用域链第二位
console.log(count);//
return function(){
var count=5;//作用域链第一位
console.log(count);
}
}
var result= new Super(1);
result();//输出5

  上面的代码中,能够清晰地了解到变量的作用域。闭包函数的内部变量位于最顶端,全局变量位于最底部。

  在闭包中使用this对象也可能会导致一些问题,this对象是在函数运行时,基于函数的执行环境绑定的。在全局函数中,this指向window对象。而函数作为某个对象的方式调用时,this等于那个对象。不过匿名函数的执行环境具有全局性,因此this指向window

 var obj={
name:"heh",
getName:function(){
var that=this;
return function(){
return that.name;
}
}
};
var one=obj.getName();
var name=one();//heh

  上面的代码中,通过字面量的方式创建了对象obj,定义了对象的属性name和方法getName。但是在getName内部,我们定义了闭包函数。如果想在闭包函数中访问name,通过this是访问不到的。所以需要在闭包函数的外部定义一个变量that,指向this。在getName中定义的变量,在闭包函数中仍然可以继续使用。

  JavaScript中没有块级作用域的概念,这意味着块级中定义的变量,实际在函数内部都是可以使用的。

 for(var i=0;i<10;i++){
console.log(i);
}
console.log(i);//输出10

  上面的代码中,我们在for循环中定义了变量i,但是我们在for循环外部依然可以使用i。for循环结束后,i变量并没有被销毁。

  JavaScript可以使用匿名函数来模仿块级作用域,从而避免该类问题的发生。

  

 (function(){
for(var i=0;i<10;i++){
console.log(i);
}
})();
console.log(i);

  上面的代码中,我们将块级作用域放在了一个匿名函数中,同时将匿名函数放在一对括号中,这表示一个函数表达式。在函数表达式外部的括号,表示立即调用该函数。在第六行调用该函数的时候,会发生报错,因为i并没有定义。

  

 var testFunc=function(){
for(var i=0;i<10;i++){
console.log(i);
}
};
testFunc();
console.log(i);

  这个代码,和我们上面的代码是一样的,都是通过函数表达式来定义函数。

  

 function(){
for(var i=0;i<10;i++){
console.log(i);
}
}();

  上面的代码是错误的。我们知道函数的定义方法,可以通过function和函数表达式。通过function声明函数的时候,function后面不能跟圆括号。函数表达式的后面可以跟圆括号。

  

 var testFunc=function(){
for(var i=0;i<10;i++){
console.log(i);
}
}();

  一般来说在开发过程中,应该尽量少向全局对象中添加函数和变量。太多的全局函数和变量容易导致命名的冲突以及内存的泄露。我们可以在块级函数中完成所有的操作。

  

 (function(){
var now = new Date();
console.log(now.getFullYear()+"-"+(now.getMonth()+1)+"-"+now.getDate()+" "+now.getHours()+":"+now.getMinutes()+":"+now.getSeconds());
})();

  通过上面的代码,我们能够当前的日期和时间。

  

浅谈JavaScript的函数表达式(闭包)的更多相关文章

  1. 浅谈JavaScript的函数表达式(递归)

    递归函数,在前面的博客中已经简单的介绍了.递归函数是一个通过函数名称在函数内部调用自身的函数.如下: function fac(num){ if(num<1){ return 1; } else ...

  2. 浅谈JavaScript匿名函数与闭包

    一. 匿名函数   //普通函数定义: //单独的匿名函数是无法运行的.就算运行了,也无法调用,因为没有名称. 如: function(){             alert('123');    ...

  3. 浅谈javascript的函数节流

    什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在 ...

  4. 浅谈JavaScript eval() 函数

    用js的人都应该知道eval()函数吧,虽然该函数用的极少,但它却功能强大,那么问题来了,为什么不常用呢?原因很简单,因为eval()函数是动态的执行其中的字符串,里面有可能是脚本,那么这样的话就有可 ...

  5. 浅谈JavaScript的函数的call以及apply

    我爱撸码,撸码使我感到快乐!大家好,我是Counter.今天就来谈谈js函数的call以及apply,具体以代码举例来讲解吧,例如有函数: function func(a, b) { return a ...

  6. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  7. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  8. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

  9. 浅谈 JavaScript 编程语言的编码规范

    对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...

随机推荐

  1. C/C++的类型安全

    类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域.“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制:有的时候也用“类型安全”形容 ...

  2. 【java基础 11】java集合框架学习

    导读:本篇博客主要是从整体上了解java的集合框架,然后主要介绍几个自己在项目中用到的结构,比如说:hashtable.hashmap.hashset.arraylist等! 一.宏观预览 从宏观上看 ...

  3. 【EF 1】EF实体框架 原理+实例

    一.知识回顾 到目前为止,自己学到的链接数据库操作已经经历了几个阶段,分别是:学生信息管理和(第一次)机房收费时的直接连接数据库操作表格,然后是机房个人重构中应用的操作实体,在其中还利用了一个很重要的 ...

  4. 如何部署 sources and javadoc jars

    mvn org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy-file -Durl=file:///home/me/m2-repo \ - ...

  5. SPOJ GSS2 Can you answer these queries II ——线段树

    [题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...

  6. response.setHeader参数、用法的介绍

    response.setHeader 是用来设置返回页面的头 meta 信息, 使用时 response.setHeader( name, contect ); meta是用来在HTML文档中模拟HT ...

  7. 在 Linux 实例上自动安装并运行 VNC Server

    原文网址:https://help.aliyun.com/knowledge_detail/41181.html?spm=5176.8208715.110.11.4c184ae8mlC7Yy 您可以使 ...

  8. 垃圾收集器与内存分配策略 (深入理解JVM二)

    1.概述 垃圾收集(Garbage Collection,GC). 当需要排查各种内存溢出.内存泄露问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调 ...

  9. ActivityGroup中监听返回按键

    如果你想使用ActivityGroup来统一管理Activity的话,当然首先这是一种很好的方法,但是如果你想在ActivityGroup里面拦截返回按键来进行统一管理的话,直接覆写onKeyDown ...

  10. qu de hanzi 首字母

    Function hztopy(hzpy As String) As StringDim hzstring As String, pystring As StringDim hzpysum As In ...