js:深入闭包(作用域:下)

function fn1(){
  //创建了一个数组
  var fns = new Array();
  //i这个变量是保存在fn1这个作用域中
  for(var i=0;i<10;i++){
    //数组中的值是一组函数
    fns[i] = function(){
      return i; 
    } 
  }
  return fns;
}

var fs = fn1();
for(var i=0;i<fs.length;i++){
  //此时通过闭包来调用所有的函数,当要输出i的时候会在它所在的定义域(fn1)中找到它,
  //此时它已变为10,所以连续输出了10个10
  console.log(fs[i]()); 
} //输出:10

---------------------------解决方案------------------------------
function fn1(){
  //创建了一个数组
  var fns = new Array();
  //i这个变量是保存在fn1这个作用域中
  for(var i=0;i<10;i++){
    //num这个变量保存在tf作用域,每一个闭包的num都是不一样的
    //所以此时所消耗的内存较大。
    var tf = function(num){
      fns[num] = function(){
        return num; 
      }
    }
    tf(i);
  }
  return fns;
}

var fs = fn1();
for(var i=0;i<fs.length;i++){
  //
  console.log(fs[i]()); 
} //输出:0 ~ 9

---------------------------块作用域------------------------------
for(var i=0;i<10;i++){
   
}
//在js中没有块作用域,不管是使用循环还是判断之后,这个变量一直存在
/**
 * 所以当在全局使用某个变量进行循环或判断之后,这个变量可能会影响到函数的变量,所以
 * 所以在特殊情况下不要使用全局变量,而且全局变量在作用域链的最上层,访问是最慢的。
 */
console.log(i);
function fn1(){
  console.log(i); 
}
fn1();

/**
 * 在一个团队进行开发中,可能会涉及到定义同名的全局变量,所以在开发中要养成一个好习惯:
 * 将全局变量代码放到一个匿名函数,并且马上调用匿名函数,这样也可以执行全局变量的代码。
 * 但是这些变量被控制在开发人员想要控制的作用域中。
 */
解决办法:将块作用域定义在一个匿名函数中。
(function(){
  for(var i=0;i<10;i++){
   
  }  
})(); //在function的{}后不能直接调用,一定要加把匿名函数放在()内再执行。

---------------------------私有变量------------------------------
function Person(name){
  /**
   *此时没有办法直接访问name这个属性,因为没有this.name,
   *要访问name只能通过this.getName获取,通过this.setName设置
   */
  this.setName = function(value){
    name = value;
  } 
  this.getName = function(){
    return name; 
  }
}

var p = new Person("zhang"); //zhang
console.log(p.getName());
p.setName("li");
console.log(p.getName()); //li

/**但是使用这种方式创建私有变量带来的问题是每个对象要存储大量函数。
 * 解决的方法是通过静态私有变量来解决。
 */
---------------------------解决方案------------------------------
var Person;
(function(){
  //name在函数结束之后就消失,在外面无法使用
  var name = "";
  Person = function(value){
    name = value;
  }
  Person.prototype.setName = function(value){
    name = value;
  }
  Person.prototype.getName = function(){
    return name;
  }
})();

var p1 = new Person("aaa"); //aaa
console.log(p1.getName());
p1.setName("bbb"); //bbb
console.log(p1.getName());

原创文章如转载,请注明出处,本文首发于csdn网站:http://blog.csdn.net/magneto7/article/details/25459099

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值