深入理解闭包

想要理解闭包,首先,要先理解变量的作用域

1.变量的作用域

变量的作用域有两种:全局作用域和局部作用域。

在 javascript 中,声明的函数内部可以获取到声明的全局变量,另一种,从外部无法直接获取到函数内部所声明的变量。 

var n = 10;
function fn(){
    var m = 20;//注意是在函数内部声明
    console.log(n);  
}
fn();//10
console.log(m);//error

这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

function fn(){
  n=999;
}
fn();
alert(n); // 999

2.什么是闭包

一般的来说,想要从一个函数的外部获取到函数内所声明的变量,直接获取是不可能的!

还有一种就是,让一个变量持续的存在一个函数内部。(在 javascript 中有一个垃圾回收机制,当一个函数被调用时,会创建一个当前调用函数的执行环境,当这个函数内的代码执行完毕时,这个执行环境会被销毁,同时内部所含有的变量一并被销毁。)

由于在 Javascript 语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

闭包的定义:

  1.闭包是指可以访问其所在作用域的函数

  2.闭包是指有权访问另一个函数作用域中的变量的函数

  3.闭包是指在函数声明时的作用域以外的地方被调用的函数

var name = "The Window";
 var object = {
   name : "My Object",
   getNameFunc : function(){
     return function(){
       return this.name;
     };
   }
 };
 alert(object.getNameFunc()());//The Window

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
    var that = this;
    return function(){
      return that.name;
    };
  }
};
alert(object.getNameFunc()());//My Object

使用闭包注意:

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

3.IIFE(立即执行函数)

严格来讲,IIFE并不是闭包,因为它并不满足函数成为闭包的三个条件。但一般地,人们认为IIFE就是闭包,毕竟闭包有多个定义。

//函数声明语句写法
function test(){};
test();

//函数表达式写法
var test = function(){};
test();

但有时需要在定义函数之后,立即调用该函数。这种函数就叫做立即执行函数,全称为立即调用的函数表达式IIFE(Imdiately Invoked Function Expression)

[注意] javascript 引擎规定,如果 function 关键字出现在行首,一律解释成函数声明语句。

(function(){ /* code */ }()); 
(function(){ /* code */ })(); 
其他写法
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();

!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

new function(){ /* code */ };
new function(){ /* code */ }(); 

 

posted @ 2017-10-10 15:13  安慕希  阅读(261)  评论(0编辑  收藏  举报