首页 > 自执行函数返回对象的问题

自执行函数返回对象的问题

自执行函数是闭包的应用。返回的对象在自执行函数体外部对函数体内部的变量有访问权。
但是在返回的对象上新定义的函数却不能访问到函数内部的变量,能解释下原理么?

var module = (function(){
  var a = 1,
      b = 2;
  return {
    getA: function(){
      console.log(a);
    },
    getB: function(){
      console.log(b);
    }
  };
})();

module.addA = function(){
    a++;
}

module.addA(); //a is not defined

1.JS的作用域在函数体
2.JS没有代码块级别的作用域
3.JS变量的作用域在函数声明的时候就确定,而不是函数运行时确定。这个就是词法作用域
4.自执行函数和闭包没有必然的联系,2者不是同一个概念

var module = (function(){
  var a = 1,
      b = 2;
  return {
    getA: function(){ //A
      console.log(a);
    },
    getB: function(){ //B
      console.log(b);
    }
  };
})();

module.addA = function(){//C
    a++;
}

module.addA(); //a is not defined

//A getA函数声明的时候, 变量a的声明在其外层函数中能找到,变量a的作用域就确定
//B getB函数声明的时候, 变量b的声明在其外层函数中能找到,变量b的作用域就确定

//C addA函数被重新赋值,匿名函数声明的时候,在其外层函数中没有发现任何关于变量a的声明,那么就这个函数对象的作用域链内不会有这个变量;当其执行的时候就会报错 ReferenceError: Can't find variable: a


可以搜索一下js静态作用域这个概念。


首先你需要了解的是什么叫做函数的作用域,函数在执行的过程中会创建一个相应的作用域链,局部的环境变量对象,仅在函数执行的过程中存在,当函数执行完成之后就会被销毁,并且被回收;但是闭包的局部变量并没有被销毁,如题主的示例,在自执行函数运行结束后,变量a、b,并没有被销毁,依然保存在内存中,因为返回的对象中,getA 函数和 getB 函数分别创建了对变量 a 和 b的引用。当执行 getA() 或 getB() 时,便可以通过该引用指针获取到变量 a 或 b。addA() 函数是在外部创建的,并没有创建对变量 a 的引用。 所以返回 is not defined。


推荐好好看看js作用域链
http://www.cnblogs.com/TomXu/archive/201...


专业的东西上面已经讲解了,下面看下这个问题最基本的东西:

//当 module被声明的时候,已经执行了后面的自执行函数;因此此时的module的内部结构如下:
var module = {
    getA : function(){
        console.log(1);
    },
    getB : function(){
        console.log(2);
    },
};
//所以你这个时候给module添加方法没问题,但是:方法内容是a++;
//那么这个时候你再看看module里里哪里还有a++了呢!
var module = (function(){
             this.a = 1,
             this.b = 2;
            this.getA= function(){
              console.log(a);
            },
            this.getB= function(){
              console.log(b);
            }
          return this;
        })();
        module.getA();
        module.addA = function(a){
            this.a = a;
        }
        module.addA(4);
        module.getA()
//再看看这个,这个可能才是你需要的

自执行函数与闭包没有必然联系。
我理解的闭包是这样的。js在定义一个函数的时候,会把当时的作用域上下文保存起来(你可以用chrome开发者工具看到,函数里面有一个叫 <function scope>的隐藏属性),当你在函数内部调用某一个变量的时候,浏览器会在这个属性中逐层去找,当第一次找到的时候,就会中止,并认为那个变量就是这个值。

一般全局定义的函数,作用域里面只有一个对象,就是全局作用域。针对你给出的代码,getA,getB函数的作用域中会有两个对象,一个是{a:1,b:2},一个是全局。当要执行getA,getB的时候,先在第一个局部对象中找,找到a就会认为a是1。而这个局部的对象{a:1,b:2},只能是getA,getB函数能访问,其他函数并不能访问,对于就形成一个“闭包”。

而module.addA函数,定义的时候,只有全局作用,肯定找不到变量a了。

可以看出js中要形成这样的局部作用域,一个必要的条件是函数。所以很多时候都会用自执行函数去实现这种访问控件。

如果想达到你要的效果,应该把addA的定义放到匿名函数中。


你新定义的这个函数和之前的那个函数是相当于两个函数吧 而之前的那个函数里面的return里面的函数是在这个函数里面可以说成是闭包 所以能用外面的a的值和b的值

【热门文章】
【热门文章】