江湖上都说要了解闭包,得先了解做用域链,因此,先从做用域链开始吧。javascript
咱们来看一个栗子html
var word = " the window" function sayWord(){ var word = "sayWord" function sayHello(){ var word = "sayHello" alert(word) } return sayHello } sayWord()();
上例的做用域链就是:
sayHello[word="sayHello"]
——sayWord[word="sayWord"]
——window[word="the window"];
当执行sayHello函数时,会沿着这个做用域链一级一级往上找word这个变量,直到找到为止。前端
javacript高级程序设计上说“有很多开发人员老是搞不清匿名函数和闭包这两个概念”。很遗憾,本人就是。java
闭包是指有权访问另外一个函数做用域中的变量的函数。github
@xiaotie闭包
闭包是从用户角度考虑的一种设计概念,它基于对上下文的分析,把龌龊的事情、复杂的事情和外部环境交互的事情都本身作了,留给用户一个很天然的接口。函数
@javacript权威指南this
函数对象经过做用域链相互关联起来,函数体内部的变量均可以保存在函数做用域内设计
上栗子
var word = " the window" function sayWord(){ var word = "sayWord" function sayHello(){ alert(word) } return sayHello } sayWord()();
sayHello函数在sayWord函数内部,它能访问sayWord函数内部的变量。sayHello函数就是闭包,
function createCounter() { var counter = 0; function increment() { counter = counter + 1; console.log("Number of events: " + counter); } return increment; } var counter1 = createCounter(); var counter2 = createCounter(); counter1(); // Number of events: 1 counter1(); // Number of events: 2 counter2(); // Number of events: 1 counter1(); // Number of events: 3
每次调用函数都会建立变量绑定对象添加到做用域链中,因此每次调用外部函数的时候,做用域链都是不一样的。而对于嵌套函数,每次调用外部函数时,内部函数又会从新定义一遍。
this对象的指向问题
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var name = "The v"; return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //"The Window"(在非严格模式下)
每一个函数在被调用时都会自动取得两个特殊变量:this
和arguments
。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,所以永远不可能直接访问外部函数中的这两个变量。
这里
object.getNameFunc()()==(function(){return this.name;})()
因此其活动对象为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"
内存泄露问题
function sayWord(){ var word = "hello" add = function(){ word = word + " world" } function sayHello(){ alert(word) } return sayHello; word = null; } var say = sayWord(); say(); //hello add(); say(); //hello world
注意:由于闭包的这个特性,因此外部函数的变量是其内部全部闭包的共享值,所以,不能在闭包中随意的改变外部函数的变量值,牵一发而动全身。
若是以为本文不错的话,帮忙点击下面的推荐哦
>>>>点击阅读原文