如何存储javascript对象变量?

时间:2012-09-17 08:58:33

标签: 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'?

1 个答案:

答案 0 :(得分: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();}

这会在object中创建pluginA属性。请注意,然后本地函数f1作为属性传递到作用域之外的全局object。然后有一个return语句,它弹出所有局部变量,以及堆栈中的所有实际参数,并放入返回值,该值将转义调用范围。然后是范围。

这里有一个小技巧。返回的值是一个对象,它具有一个函数,该函数具有对已经离开的作用域的'default_value'的引用。这是可能的,因为实际上,实际对象存储在堆上,而在堆栈上只有对这些对象的引用。这意味着default_value仍然存在于堆上,并由返回的对象中的f2函数引用。

f2被调用时,控件进入f2通话范围。由于它已在create中定义,因此它引用了堆上的default value对象。由于它可以访问该对象,因此也可以将其更改为'pa'。然后保留f2的调用范围,并在分号后返回返回的值。 f1函数还引用了default_value,现在等于'pa'。在f1的{​​{1}}属性中,'pluginA'函数已“关闭”。

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

中的间接引用来访问这些值

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

之后,以下是不言自明的......

'pb'