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

 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. Linux中执行shell脚本命令的4种方法总结

    bash shell 脚本的方法有多种,现在作个小结.假设我们编写好的shell脚本的文件名为hello.sh,文件位置在/data/shell目录中并已有执行权限. 方法一:切换到shell脚本所在 ...

  2. 九度oj 题目1385:重建二叉树

    题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...

  3. bzoj3211 花神游历各国 线段树,势能分析

    [bzoj3211]花神游历各国 2014年3月17日2,7230 Description   Input   Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input ...

  4. 蒲公英(bzoj 2724)

    Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 Output Sample Input ...

  5. 巴蜀1088 Antiprime数

    Description 如果一个自然数n(n>=1),满足所有小于n的自然数(>=1)的约数个数都小于n的约数个数,则n是一个Antiprime数.譬如:1, 2, 4, 6, 12, 2 ...

  6. 自定义Navigation按钮及Title

    导航栏自带的按钮,时常不能满足要求,所以深深需要进行各种定制. 写一个UINavigationItem的category // UINavigationItem+CB_ChangeButton.h 
 ...

  7. 在ScrollView添加一个ListView造成的滚动问题的简单解决办法()

    正常来说,在ScrollView添加一个ListView后在真机上只会显示ListView的一行多一点,我也不理解为什么会这样,后来我把ListView的layout_height改成400dip,而 ...

  8. Golang中的panic和recover(捕获异常)

    func panic(interface{})和func recover() interface{}是Golang中用于错误处理的两个函数. panic的作用就是抛出一条错误信息,从它的参数类型可以看 ...

  9. Container With Most Water 双指针法

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). ...

  10. codeforces #472(div 1)

    B(two point) 题意: 给出长度为n的非递减数组E[1..n],对于所有三元组(i,j,k),1<=i<j<k<=n且Ek-Ei<=U,我们需要计算出最大的(E ...