码迷,mamicode.com
首页 > Web开发 > 详细

一道有趣的js题以及个人的理解

时间:2017-04-05 13:54:39      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:全局   back   原因   color   res   声明   media   优先   turn   

var number = 2;
var obj = {
  number : 4,
  fn1 : ( function() {     
    this.number *= 2;
    number=number*2;
    var number=3;
    return function() {
      this.number *= 2;
      number*=3;
      alert(number);
    } 
  } )(),
  db2:function(){this.number*=2}
};
var fn1 = obj.fn1;
alert(number);//问这会会弹出什么结果 4
fn1();//这会弹出什么结果 9
obj.fn1();//这次弹出什么结果 27
alert(window.number); //这会window.number的结果是什么 8 
alert(obj.number);   //这会obj.number的结果是什么 8

  这是我无意间看到的一道js题,当时理解了好久,不过总算明白了,下面附上自己的解析。

一、编译阶段

var number = 2;
var obj = {
  number : 4,
  fn1 : ( function() {     
    this.number *= 2;
    number=number*2;
    var number=3;
    return function() {
      this.number *= 2;
      number*=3;
      alert(number);
    } 
  } )(),
  db2:function(){this.number*=2}
};
先看以上这段代码,其中包括了一个IIFE(Immediately-Invoked Function Expression )立即执行函数表达式(function(){})()。这个函数在编译阶段就执行了。主要作用是隔离作用域,模仿块级作用域。
为了方便理解,我在代码中添加alert();
var number = 2;
var obj = {
  number : 4,
  fn1 : ( function() {     
    this.number *= 2;
    alert(this);  //window
    number=number*2;
    alert(number);  //NAN  原因:变量声明提前
    var number=3;
    alert("执行");
    return function() {
      this.number *= 2;
      number*=3;
      //alert(number);
    } 
  } )(),
  db2:function(){this.number*=2}
};
可以看到IIFE的function的this指向的是window,并且在函数编译阶段就执行了,所以运行以上代码就会依次打印:
window 
NAN 
执行
并且 全局number=4; 
     obj.number=4;
     IFFE 中存在的var number=3;(由于闭包的存在使IIFE的活动对象仍会存在)
二、执行阶段
var fn1 = obj.fn1;
alert(number);//问这会会弹出什么结果 4
fn1();//这会弹出什么结果 9
obj.fn1();//这次弹出什么结果 27
alert(window.number); //这会window.number的结果是什么 8 
alert(obj.number);   //这会obj.number的结果是什么 8
1、var fn1 = obj.fn1;使fn1指向了IFFE的闭包,闭包的存在
2、alert(number);//此时是指全局number=4;
3、fn1();//调用fn1()函数,闭包中this的原则是是哪个对象调用该函数,this就指向哪个对象。此时是window对象调用。因此,
this.number 是指全局number(既是变量也当作window属性),全局 number=8;
变量的number根据作用域链以及闭包的规则,优先在内部环境找(无),再往上一级找(匿名函数中 var number=3 有) 所以var number=9;所以再alert(number)就为9。
4、obj.fn1();//obj调用fn1,obj.number=8,变量的number根据作用域链以及闭包的规则,优先在内部环境找(无),再往上一级找(匿名函数中 var number=9 有) 所以var number=27;所以再alert(number)就为27。
5.此时window.number=8;
6.此时obj.number=8;
 
重点:
理解IIFE的隔绝作用域,理解闭包的作用域链。

一道有趣的js题以及个人的理解

标签:全局   back   原因   color   res   声明   media   优先   turn   

原文地址:http://www.cnblogs.com/waterserver/p/6668226.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!