js闭包

闭包的作用域

fn1();
funcion fn1(){
alert(“fn1”);
}
这种定义函数的方式先调用后定义不会报错

fn2();
var fn2() = function(){
alert(“fn2”);
}
这种定义函数的方式会报错
在JS中进行函数的调用,会为每一个函数增加一个属性SCOPE,通过这个属性来指向一块内存,这块内存中包含有所有的上下文使用的变量,当在某个函数中调用新函数之后,新函数依然会有一个作用域来执行原有的函数SCOPE和自己新增加的SCOPE,这样就形成一个链式结构,这就是JS中的作用域链。
var color = “color”;
var showColor = function(){//函数的作用域链
alert(this.color);
}
function changeColor(){
var anotherColor = “blue”;
function swapColor(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
}
swapColor();
}
changeColor();
showColor();
以下操compareObjectFunction的作用域变大了compareObjectFunction结束之后,prop这个变量依然存在。
function compareObjectFunction(prop){
return function(obj1,obj2){
if(obj1[prop] > obj2[prop]){
return 1;
}else if(obj1[prop] < obj2[prop]){
return -1;
}else{
return 0;
}
}
}
var o1 = {name: “Leon”,age:23};
var o2 = {name: “Ada”,age:28};
var compare = compareObjectFunction(“age”);
(返回函数扩大作用域的方法叫闭包)
var rel = compare(o1,o2);
alert(rel);//-1
注意:使用闭包虽然可以延长作用域,但是会占用更多的内存,一般非特殊原因不建议使用闭包,使用闭包还有两个缺点。
变量的问题与解决方法
以下操compareObjectFunction的作用域变大了compareObjectFunction结束之后,prop这个变量依然存在。
function compareObjectFunction(prop){
return function(obj1,obj2){
if(obj1[prop] > obj2[prop]){
return 1;
}else if(obj1[prop] < obj2[prop]){
return -1;
}else{
return 0;
}
}
}
var o1 = {name: “Leon”,age:23};
var o2 = {name: “Ada”,age:28};
var compare = compareObjectFunction(“age”);
(返回函数扩大作用域的方法叫闭包)
var rel = compare(o1,o2);
alert(rel);//-1
注意:使用闭包虽然可以延长作用域,但是会占用更多的内存,一般非特殊原因不建议使用闭包,使用闭包还有两个缺点。
function fn1(){
var fns = new Array();
for(var i=0;i<10; i++){
fns[i]=function(){
return i;
}
}
return fns;
}
var fs = fn1();
for(var i=0;i

块作用域

for(var i=0;i<10;i++){}
var i;//此时无效,var i=0;有效
alert(i);//10
在JS中没有块作用域,不管在循环还是在判断之后,这个变量会一直存在。所以当在全局使用某个变量进行循环或者判断之后,这个变量可能影响到函数中的变量,所以在非特殊情况下不要使用全局变量,而且全局变量在作用域链的最上层,访问是最慢的。解决方法是匿名函数。
在团队开发时,可能会涉及到定义同名的全局变量,所以在开发中一定养成如下习惯,将全局变量的代码放到一个匿名函数,并马上调用,这样也可以执行全局变量的代码,但是这些变量就被控制在开发人员想要控制的作用域中了
(function(){
for(var i=0;i<10;i++){}
})();
function fn(){
alert(i);
}
fn();//报错
当然es6完善了这部分内容,使用let定义变量可以将变量的作用域控制在花括号内。

私有变量

function Person(value){
this.setName = function(value){
name=value
}
this.getName = function(){
return name;
}
}
var p = new Person(“aa”);
alert(p.getName());
p.setName(“bb”);
alert(p.getName());//bb
此时没有办法直接访问name这个
属性,因为没有this.name,要访
问name只能通过this.getName,
this.setName,但是这种方式创建
私有变量带来的问题是,每个对象
都存储大量的函数,解决方法是通
过静态私有变量来解决。
var Person;
(function(){
var name = “”;
Person = function(value){
name = value;
}
Person.prototype.setName =
function(value){
name = value;
}
Person.prototype.getName =
function(){
return name;
}
})();
var p1 = new Person(“aa”);
alert(p1.getName());
p1.setName(“bb”);
alert(p1.getName());
name在函数结束之后就消失了,
在外面是无法引用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值