标签:ges targe span gif div 原因 ons www 存储
一、Js以前没有块级作用域,不过在ES6中有let了。
二、Js使用函数作用域
function aaa(){
var a = "a";
}
console.log(a);//报错
三、声明提前
console.log(aaa)//报错
console.log(aaa);//undefined 声明未定义 var aaa;
console.log(aaa); //undefined 声明未定义 var aaa = "aaa";
四、Js的作用域链
function Fun(){
var aaa = "aaa",
fun = "fun";
function Inter(){
var aaa = "ccc";
console.log(aaa); //ccc
console.log(fun); //fun
}
Inter();
}
Fun();
Inter的作用域链


找到就停止查找返回数据,找不到就延作用域链查找,直到Global也查不到就返回报错;
五、Js的作用域链在执行前已经被创建
一、闭包:是指有权访问另一个函数作用域中的变量的函数;
二、闭包的特点:局部变量不会被垃圾回收;
//定义一个函数时,实际是保存它的作用域链。当调用这个函数时,会创建一个新的对象来保存局部变量,并且把这个新的对象添加到作用域链上。当函数返回时,将作用域链中的这个对象删除。
//如果这个函数定义了嵌套函数,并将它作为返回值返回或者存储在某处的属性里,就会有一个外部的引用指向这个嵌套函数。
三、上面那句是书上的话,不好理解。我翻译下就是父函数内创建的变量,子函数调用。只要子函数没有被销毁,父函数和创建的变量就不会被销毁。
举个栗子
function counter(){
var a = 0;
function rest(){
console.log(a++);
}
return rest;
}
var scope = counter();
scope();//0
scope();//1
scope();//2
创建闭包的常见方式,就是在一个函数内部创建另一个函数,外部函数将内部函数作为返回值返回。有的时候这个外部是全局。
for(var i = 0;i<elements.length;i++){
elements[i].onclick = function(){
console.log(i); //elements.length
}
}
上面每次点击,输出的都是elements.length。因为onclick是一个点击的函数,不能被销毁,所以i也不能被销毁保存在Global中。所以点击输出的是elements.length。
for(var i = 0;i<elements.length;i++){
function F(n){
elements[n].onclick = function(){
console.log(n);
}
}
F(i);
}
这样修改下就可以了。
四、垃圾回收机制:如果一个对象不再被引用,这个对象会被GC回收。如果两个对象相互引用,这两个都会被回收。如果a被b引用,b又被c引用,就不会被回收,就是闭包第一个例子的原因。
五、闭包的两种写法
function counter(){
var a = 0;
function rest(){debugger
return a;
}
return rest();
}
counter();
定义调用在同一作用域
function counter(){
var a = 0;
function rest(){debugger
return a;
}
return rest;
}
//counter()();
var scopt = counter();
scopt();
定义调用不在同一作用域
原文:http://www.cnblogs.com/taohuashan/p/6689619.html
标签:ges targe span gif div 原因 ons www 存储
原文地址:http://www.cnblogs.com/yanglang/p/6698132.html