标签:
在javascript中,作用域是执行代码的上下文,作用域有三种类型:
1) 全局作用域
2) 局部作用域(函数作用域)
3) eval作用域
var foo = 0; //全局作用域 console.log(foo);//输出0 var myFunction = function() { var foo = 1; //局部作用域 console.log(foo); //输出1 var myNestedFunction = function() { var foo = 2; console.log(foo); //输出2 }(); } (); eval("var foo=3;console.log(foo);");//eval()作用域
javascript中,函数内部的可以直接读取全局的变量:
取内部的局部变量,例如:
还有需要注意的,在函数内部声明变量的时候,一定要用var命令,如果不用的话,实际声明的是一个全局变量哈
由于逻辑语句无法创建作用域,因此变量可以互相覆盖,例如:代码执行时,foo是变化的,因为javascript没有块作用域,只有函数,全局和eval作用域
当javascript查找与变量关联的值时,会遵循一个查找链。这个链是基于作用域的层次结构的。
例如:查找 sayHiText变量的顺序为;Func2中--àfunc1中 ---》全局变量中
有时候我们需要得到函数内的局部变量,但是,在正常情况下是办不到的,只有通过变通方法实现,那就是在函数的内部,再定义一个函数。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们就可以在 f1外部读取内部变量了,即f2函数就是闭包。
闭包就是能够读取其他函数内部变量的函数。由于在javascript中,只有函数内部的子函数才能够读取局部变量,
因此可以把闭包简单理解成“定义在一个函数内部的函数”。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包最大的两个用途是: 1) 可以读取函数内部的变量
2)让这些变量的值始终保持在内存中
例如以下代码:
在这段代码中,result实际上就是闭包f2函数, 它一共运行两次,第一次是99,第二次是100。
这就证明了函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
因为f1是f2的父函数,而f2被赋给了一个全局变量,这就导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会再调用结束后,被垃圾回收机制回收。
1) 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包。
2) 闭包会在父函数外部,改变父函数内部变量的值。
如上,为什么输出的结果是the window 了?
主要有两个知识点:
1) 内部函数可以访问定义它们的外部函数的参数和变量(除了this和arguments之外)
2) 如果需要访问对象的name属性,就需要显示的定义一个变量that来引用this,而这个变量此时就指向了object对象了
getNameFunc的第一个()是属于方法的调用,所以this绑定到了object对象上,自然this.name为the object,但是闭包函数无法访问这个this,它只能访问到全局的this,因此输出的是”the window”
例如:
闭包中的this指向的是全局对象,而getNameFunc中的this指向的是调用者,所以输出的结果如上。例如:
为对象显示定义了that来引用this,因此输出的是 “the object”
标签:
原文地址:http://www.cnblogs.com/alice626/p/4956239.html