最有效的方式来引用嵌套对象

时间:2014-10-18 20:21:16

标签: javascript object reference

我的查询:

引用嵌套JavaScript对象的最有效方法是什么?到目前为止,我找到了一对,我想知道哪个是最有效的,如果还有其他的比我在这里列出的更好。问题涉及使用根对象,类似于许多JavaScript框架使用的对象。 根对象是强制性的。请不要发布不使用根对象的答案。

请注意,这特别适用于名称较长的根/子根对象 - 引用a.b将毫无用处,而引用abcdefghijklm.nopqrstuvwxyz则非常有用。

修改

只是为了澄清一些事情:

  • 通过效率我的意思首先是代码长度(这可能反过来影响性能,但稍微不那么重要)。我担心代码长度部分是因为文件大小 - 是的,我会在之后缩小它 - 但也是因为任何人都可以查看我的原始代码(包括我自己)。性能也略显重要,我不希望长时间的解决方法会降低执行速度。
  • 引用主要是针对常用的子对象,不是每一个。我声明(在方法1中)需要创建许多全局变量 - 因为我假设所有的第一级子对象都是常用的。

要引用的对象:

对象foo包含各种子对象barbazqux,每个子对象都包含各种其他对象。

var foo = {

    bar: {

        bar: {},
        baz: {},
        qux: {}

    },
    baz: {

        bar: {},
        baz: {},
        qux: {}

    },
    qux: {

        bar: {},
        baz: {},
        qux: {}

    }

};

方法1 - 参考变量:

第一种方法涉及为每个子对象创建一个变量。

var bar = foo.bar;
var baz = foo.baz;
var qux = foo.quz;
然后可以通过foo.bar.bazbar.baz通过foo.qux.qux引用

qux.qux

优点:

  • 参考变量可以非常简洁 - 单个字符是最小可能的长度。

缺点:

  • 如果要引用的子对象很多,这会增加全局变量计数。这可能会导致冲突,跨脚本和其他 - 特别是使用单字符变量名称。
  • 需要为每个嵌套对象创建一个新的引用变量。这不仅不方便,而且还要求程序员在修改对象后记住来创建每个变量。相反,如果删除了一个子对象并且程序员也忘记了删除引用变量,那么代码就会变得混乱,无用的全局变量使它变得混乱。

方法2 - 参考功能:

第二种方法涉及创建一个返回子对象的函数,具体取决于几个参数。

function ref(a, b) {

    //Ensure that the first parameter is passed:
    if (!a) {

        return false;

    }

    return foo.a.b;

};
然后可以通过foo.bar.baz引用

ref("bar", "baz"),通过foo.qux,qux引用ref("qux", "qux")

优点:

  • 适用于所有第一级子对象,无需重复且杂乱的单独变量定义。

缺点:

  • 仅对缩短根对象非常有用 - 如果根对象名为a,那么使用引用函数实际上会延长代码。

2 个答案:

答案 0 :(得分:2)

假设我们有一个图形控件对象,它是GraphicObject类(函数)的一个实例。
 让我们说一个实例看起来像:

grControl = {
   visual : {
     boundingBox : { x : , y : , width: , height : ... },
     ...
   },
   action : {
     ...
   }
};

创建快捷方式的正确方法是:
•在将使用它的函数中的var中本地缓存适当的对象:

function drawBBox (someGraphicControl) {
     var bbox = someGraphicControl.visual.boundingBox;
     // maybe you want also to cache sub-properties :
     var width = bbox.width;
     ...
}

•在原型上定义一个getter和/或setter,它将提供对嵌套属性的访问:

// read-only example
Object.defineProperty(GraphicControl.prototype, 'width', 
                                { get : function() { 
                                           return this.visual.boundingBox.width }, 
                                  enumerable : true};


// read-write example
Object.defineProperty(GraphicControl.prototype, 'width', 
                                { get : function() { 
                                           return this.visual.boundingBox.width }, 
                                  set : function(val) {
                                           this.visual.boundingBox.width = val ; }, 
                                  },
                                  enumerable : true};

这样你可以使用:

 grObject.width  

并完全参考:

 grObject.visual.boundingBox.width

答案 1 :(得分:1)

javascript中的常规做法取决于具体情况:

1)在特定功能中对该对象进行一次性访问。如果您只是一次访问深度嵌套的引用,则只需将所有干预措施拼写出来名称:

var data = foo.baz.quz.prop1;

2)对特定嵌套对象的多次访问。如果对特定深度嵌套对象有多个引用,则创建一个指向公共对象的临时局部变量,然后从在本地函数内。

function getDeepData() {
    var obj = foo.baz.quz;
    var prop1 = obj.prop1;
    var prop2 = obj.prop2;
    var prop2 = obj.prop3;

    // code that uses prop1, prop2 and prop3 here

}

3)迭代属性谁的名字事先不知道。由于您事先不知道属性名称,这是通过一次迭代一个级别(有时是递归)来完成的将父对象保留在局部变量中。


如果您发现自己在代码中进行了大量深度嵌套的一次性引用,那么您可能希望重新访问代码或数据的结构,因为通常可以避免这种情况。