2012-09-17 101 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