2012-09-17 163 views
1

我试图理解这个插件系统,但有点困惑。JavaScript对象变量如何存储?

var obj={}; 
obj.plugin={ 
create: function(pluginname){ 
    var default_value='p1'; 
    var f1 = function(){ 
      alert(default_value); 
      //define plugin properties 
     } 
    obj[pluginname] = function(){return new f1();} 
    /* 
    run other code here 
    */ 
    return { 
     // 
     f2: function(args){ 
      default_value=args; 
     }      
    } 
} 
}; 
obj.plugin.create('pluginA').f2('pa'); 
obj.plugin.create('pluginB').f2('pb'); 
obj.pluginA(); // pa 
obj.pluginB(); // pb 

我想结果应该是这样的:

obj.pluginA(); // pb 
obj.pluginB(); // pb 

而另一个问题是:“新的F1()”将不会被直到最后两线运行。 'default_value'已存储在哪里?

+0

对象就像它可以包含子文件夹和文件的文件夹。即:简单变量类型和/或子对象。 – Jay

回答

0

小源代码解释第一:

var obj={}; 
obj.plugin={ 
// object plugin property is an object that has create property defined here 
// create property is a function that adds another properties to object in general 
create: function(pluginname){ 
    // this default value has got 'var' modifier - it is local and has scope of 'create' 
    var default_value='p1'; 
    // f1 is a plugin's function - it does what a plugin creator implements 
    var f1 = function(){ 
      // it encloses 'default_value' locally in 'create' 
      alert(default_value); 
      //define plugin properties 
     } 
    // the line below is the creation of a new property, which allows the object 
    // to call a method of name of a plugin; it assigns to the property of that name 
    // the f1 function closure, but local to actual execution of 'create'; 
    // note the use of 'new' operator which copies the function making it independent 
    // from other calls of 'create' 
    obj[pluginname] = function(){return new f1();} 
    /* 
    run other code here 
    */ 
    return { 
     // this function allows you to change 'default_value' still in scope 
     // of the same call of 'create', thus effectively changing that one (locally - it's 'var'); 
     f2: function(args){ 
      default_value=args; 
     }      
    } 
// after leaving this brace you leave the 'create' scope 
} 
// and the plugin object scope 
}; 

现在怎么它会工作:

此:obj.plugin.create('pluginA').f2('pa');
询问create插件属性,这是一个功能,被称为与'pluginA'串。 要调用该函数的js创建呼叫(这实际上是在堆栈的顶部一些结构化对象)的情况下。 'pluginA'被放在堆栈作为参数,default_valuef1f2被放在堆栈上的局部变量上。然后执行create函数。变量的初始化首先进行,然后分配 obj[pluginname] = function(){return new f1();}

这会在对象中创建pluginA属性。请注意,那么本地函数f1将作为属性传递给全局范围object。然后有一个return语句,它会弹出所有局部变量,并从堆栈中弹出所有实际参数,并放入返回值以避开调用范围。然后范围被留下。

这里有个小窍门发生。返回的值是一个对象,该对象具有一个函数,该函数在已经保留的作用域中引用了'default_value'。这是可能的,因为实际上,实际的对象存储在堆上,而在堆栈上只有这些对象的引用。这意味着default_value仍然存在于堆中,并且被该返回对象中的f2函数引用。

f2称为控制进入f2呼叫范围。由于它已在create中定义,因此它引用堆中的default value对象。由于它可以访问该对象,因此它也可以将其更改为'pa'。然后,f2的调用范围保留,分号后也返回值。该f1功能也有参照该default_value,现在等于'pa'。这f1功能是在object'pluginA'财产“关闭”。

这意味着,全球object现在有一个属性pluginA,这是一个函数(名为f1)。该函数引用了一个对象(名为default_value)。该对象是一个字符串'pa'通过始终可访问的object,可通过间接参考值保存这些值。

此:obj.plugin.create('pluginB').f2('pb');
分别做同样的事情与其他参数,因此,在创建对象pluginB属性。这是另一个电话create,所以它有一个全新的default_value。那是另一个本地实例。同样的魔法在另一个属性(pluginB)中关闭全局object中的新对象。 Create返回一个包含新函数的新对象f2。那个人可以访问那个'更新的'default_value,但与前一个电话无关。当在另一个返回对象上调用f2时,它将“新”default_value更改为'pb'

之后,下面是不言自明......

obj.pluginA(); // pa 
obj.pluginB(); // pb 
+0

我得到了你,但我不明白js如何在记忆中工作。 T_T – HACK21

+0

要了解整体,您需要先了解该部分。你最担心的是什么?指出,所以我可以知道你在哪里需要详细的解释。 –

+0

你说:“分号后,创建的调用范围保留”,但我不能通过萤火虫或Chrome工具看到“创建的调用范围”。我只是想知道它是如何存在的。 – HACK21