JavaScript 作用域
1.[[scope]]属性
函数是全局的对象,每个对象都有属性,有一些属性可以被访问,有一些则不行,例如[[scope]]属性,属于隐式属性。 所说的作用域,存储着我们执行期上下文的集合。
2.运行期上下文
当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行器上下文定义了一个函数执行时的环境,函数每次调用时都会新建一个执行期上下文,是独一无二的,多次调用创建多个,执行完即销毁。
function a(){ //... } //a defined a[[scope]]--> 0 : GO(全局对象) //a doing a[[scope]]--> 0 : A0 // 1 : GO
3.查找变量
从作用域链的顶部开始依次向下执行。
4.闭包
当内部函数被保存到外部函数时,将会产生闭包。闭包导致原有的作用域链不释放,造成内存泄露。
1 function a(){ 2 var aa=123; 3 function b(){ 4 a--; 5 console.log(a); 6 } 7 return b; 8 } 9 var demo=a(); //a执行完的return b函数给 demo; 10 demo(); // b执行 11 // a defined a[[scope]] --> 0 : GO 12 13 // b defined b[[scope]] --> 0 : AO 14 // 1 : GO 15 16 //a doing a[[scope]] --> 0 : AO 17 // 1 : GO
b[[scope]]如下:
//输出结果 10 10 10 10 10 10 10 10 10 10 //要想输出 0 1 2 3 4 5... function test(){ var arr=[]; for(var i=0;i<10;i++){ //闭包 (function (j){ //j= i; var arr[i] = function (){ document.write(j+' '); } }(i)); //立即执行函数, } return arr; } var myArr = test(); for(var j = 0;j < 10; j++){ myArr[i](); } //10个立即执行函数 分别指向不同的 --> AO;
5.闭包的作用
-
实现公有变量 eg:累加器
function a(){ var count=0; function b(){ count++; console.log(count); } return b; } var demo=a(); demo(); // 1 demo(); // 2
-
可以做缓存(存储结构) eg:eater
-
可以实现封装,属性私有化。 eg : person()
-
-
Deng
函数运行完变量销毁,但与里面的函数形成闭包,通过作用域链找到
4.模块化开发,防止污染全局变量,使用于模块化开发 (命名空间)
防止变量冲突问题
1.传统方法
2.闭包和立即执行函数
运用立即执行函数,在函数中定义私有属性。与内部函数形成闭包,再
return
一个函数函数内部有函数接口。