Javascript中对象链的速记创建

Javascript中对象链的速记创建,javascript,semantics,Javascript,Semantics,我想知道的是,是否有较短的方法实现以下目标: App.Plugins = App.Plugins || {}; App.Plugins.SomePlugin = App.Plugins.SomePlugin || {}; App.Plugins.SomePlugin.Models = App.Plugins.SomePlugin.Models || {}; App.Plugins.SomePlugin.Views = App.Plugins.SomePlugin.Views || {}; App

我想知道的是,是否有较短的方法实现以下目标:

App.Plugins = App.Plugins || {};
App.Plugins.SomePlugin = App.Plugins.SomePlugin || {};
App.Plugins.SomePlugin.Models = App.Plugins.SomePlugin.Models || {};
App.Plugins.SomePlugin.Views = App.Plugins.SomePlugin.Views || {};
App.Plugins.SomePlugin.Collections = App.Plugins.SomePlugin.Collections || {};
function defaults(obj, prop) {
    return obj[prop] = obj[prop] || {};
}
defaults(App, 'Plugins');
defaults(App.Plugins, 'SomePlugin');
defaults(App.Plugins.SomePlugin, 'Models');
defaults(App.Plugins.SomePlugin, 'Views');
defaults(App.Plugins.SomePlugin, 'Collections');
据我所知,这种格式很好,如果我弄错了,请有人告诉我,我只是想知道是否有更好的方法在我的singleton上进行初始设置


提前感谢…

您可以执行以下操作:

App.Plugins = App.Plugins || {};
App.Plugins.SomePlugin = App.Plugins.SomePlugin || {};
App.Plugins.SomePlugin.Models = App.Plugins.SomePlugin.Models || {};
App.Plugins.SomePlugin.Views = App.Plugins.SomePlugin.Views || {};
App.Plugins.SomePlugin.Collections = App.Plugins.SomePlugin.Collections || {};
function defaults(obj, prop) {
    return obj[prop] = obj[prop] || {};
}
defaults(App, 'Plugins');
defaults(App.Plugins, 'SomePlugin');
defaults(App.Plugins.SomePlugin, 'Models');
defaults(App.Plugins.SomePlugin, 'Views');
defaults(App.Plugins.SomePlugin, 'Collections');

您可以执行以下操作:

App.Plugins = App.Plugins || {};
App.Plugins.SomePlugin = App.Plugins.SomePlugin || {};
App.Plugins.SomePlugin.Models = App.Plugins.SomePlugin.Models || {};
App.Plugins.SomePlugin.Views = App.Plugins.SomePlugin.Views || {};
App.Plugins.SomePlugin.Collections = App.Plugins.SomePlugin.Collections || {};
function defaults(obj, prop) {
    return obj[prop] = obj[prop] || {};
}
defaults(App, 'Plugins');
defaults(App.Plugins, 'SomePlugin');
defaults(App.Plugins.SomePlugin, 'Models');
defaults(App.Plugins.SomePlugin, 'Views');
defaults(App.Plugins.SomePlugin, 'Collections');
可能会使用它

function namespace(path) {
    var segments = path.split('.'),
        result = {};

    function define(name, obj) {

        if (name === '.') {
            return obj;
        } 

        !obj[name] && (obj[name] = {});
        return define(segments.shift(), obj[name]);
    }

    segments.push('.'); //add stop symbol;
    define(segments.shift(), result);

    return result;
}

namespace('App.Plugins.SomePlugin.Collections').controller = function() {}
可能会使用它

function namespace(path) {
    var segments = path.split('.'),
        result = {};

    function define(name, obj) {

        if (name === '.') {
            return obj;
        } 

        !obj[name] && (obj[name] = {});
        return define(segments.shift(), obj[name]);
    }

    segments.push('.'); //add stop symbol;
    define(segments.shift(), result);

    return result;
}

namespace('App.Plugins.SomePlugin.Collections').controller = function() {}

我不明白你为什么这么做

总之,一种较短的书写方式是:

App={
 Plugins:{
  SomePlugin:{
   Models:{},
   Views:{},
   Collections:{}
  }
 }
}
然后考虑到功能

function defaults(obj, prop) {
    return obj[prop] = obj[prop] || {};
}
将使用返回一个错误

defaults(App.Plugins.AnotherPlugin,'Models')
检查这是一种痛苦:

var x={};
if(App&&
   App.Plugins&&
   App.Plugins.AnotherPlugin&&
   App.Plugins.AnotherPlugin.Models
){
 x=App.Plugins.AnotherPlugin.Models
}
console.log(x);
解决办法是

var x={};
try{x=App.Plugins.AnotherPlugin.Models}catch(e){}
console.log(x)
这不会给你任何错误

但是你不能简单地设置它

编辑

评论回答

然后你应该在没有确定的地方开始检查。在您的情况下,您只需要检查是否存在其他插件。您可能已经有App&App.Plugins。因此,您不需要App=App | |{},只需要App.Plugins.anotherPlugin

!App.Plugins.AnotherPlugin||App.Plugins.AnotherPlugin=NewPlugin
还是一个函数

function addPlugin(name,newPlugin){
 !App.Plugins[name]||App.Plugins[name]=newPlugin
}
定义自己的标准。。。我的意思是,如果对象不存在,为什么要返回它

如果它不存在,你无论如何也不能做任何事情

再说一次,最大的问题总是检查它是否存在。。。正如我前面所描述的,它是“尝试捕捉”

EDIT2

检查此功能

function def(a,b,c,d){
 c=b.split('.');
 d=c.shift();
 a[d]||(a[d]={});
 !(c.length>0)||def(a[d],c.join('.'));
}
用法:

var A={};
def(A,'B.C.D.E.F')
//this transforms your {}
//to 
A:{
 B:{
  C:{
   D:{
    E:{
     F:{
     }
    }
   }
  }
 }
}

要创建插件,请执行以下操作:

var App={}
def(App,'Plugins.SomePlugin.Models')
def(App.Plugins.SomePlugin,'View')
// &/or
def(App,'Plugins.SomePlugin.Collections')

我不明白你为什么这么做

总之,一种较短的书写方式是:

App={
 Plugins:{
  SomePlugin:{
   Models:{},
   Views:{},
   Collections:{}
  }
 }
}
然后考虑到功能

function defaults(obj, prop) {
    return obj[prop] = obj[prop] || {};
}
将使用返回一个错误

defaults(App.Plugins.AnotherPlugin,'Models')
检查这是一种痛苦:

var x={};
if(App&&
   App.Plugins&&
   App.Plugins.AnotherPlugin&&
   App.Plugins.AnotherPlugin.Models
){
 x=App.Plugins.AnotherPlugin.Models
}
console.log(x);
解决办法是

var x={};
try{x=App.Plugins.AnotherPlugin.Models}catch(e){}
console.log(x)
这不会给你任何错误

但是你不能简单地设置它

编辑

评论回答

然后你应该在没有确定的地方开始检查。在您的情况下,您只需要检查是否存在其他插件。您可能已经有App&App.Plugins。因此,您不需要App=App | |{},只需要App.Plugins.anotherPlugin

!App.Plugins.AnotherPlugin||App.Plugins.AnotherPlugin=NewPlugin
还是一个函数

function addPlugin(name,newPlugin){
 !App.Plugins[name]||App.Plugins[name]=newPlugin
}
定义自己的标准。。。我的意思是,如果对象不存在,为什么要返回它

如果它不存在,你无论如何也不能做任何事情

再说一次,最大的问题总是检查它是否存在。。。正如我前面所描述的,它是“尝试捕捉”

EDIT2

检查此功能

function def(a,b,c,d){
 c=b.split('.');
 d=c.shift();
 a[d]||(a[d]={});
 !(c.length>0)||def(a[d],c.join('.'));
}
用法:

var A={};
def(A,'B.C.D.E.F')
//this transforms your {}
//to 
A:{
 B:{
  C:{
   D:{
    E:{
     F:{
     }
    }
   }
  }
 }
}

要创建插件,请执行以下操作:

var App={}
def(App,'Plugins.SomePlugin.Models')
def(App.Plugins.SomePlugin,'View')
// &/or
def(App,'Plugins.SomePlugin.Collections')

您可以编写一个方法来解决这些问题:
buildTree(App,'Plugins','SomePlugin','Models')
等,它可以像
mkdir-p
一样工作,但是考虑到执行这种操作的频率很低,并且为了保持代码简单,它没有上面提到的那么有意义。我想知道是否有一行代码,但我认为你不能写一个方法来打破这些:
buildTree(App,'Plugins','SomePlugin','Models')
等,可以像
mkdir-p
一样工作,然而,考虑到执行此操作的频率很低,并且为了保持代码的简单性,它没有上面提到的那么有意义。我想知道是否有一行代码,但我认为我没有考虑创建一个函数来实现这一点,事实上,尽管这与问题中提供的手动方法一样多的代码行,但它也增加了另一个潜在的失败点,我相信我的问题的答案可能是否定的。不过谢谢你的回答。如果你担心“失败点”,你没有一个很好的测试套件。也许你需要先解决这个问题。你应该把它改写成“没有测试套件”,我刚刚加入这个项目,它是我优先考虑的项目之一!事实上,我不认为这比最初的方法增加了任何价值,但我认为这是一个完全有效的答案,感谢你的洞察力。我考虑创建一个函数来实现这一点,事实上,尽管这与问题中提供的手动方法一样多的代码行数,但它也增加了另一个潜在的失败点,我相信我的问题的答案可能是否定的。不过谢谢你的回答。如果你担心“失败点”,你没有一个很好的测试套件。也许你需要先解决这个问题。你应该把它改写成“没有测试套件”,我刚刚加入这个项目,它是我优先考虑的项目之一!事实是,我不认为这比最初的方法增加了任何价值,但我接受它作为一个完全有效的答案,感谢你的洞察力。我这样做的原因是,在执行我的代码时,应用程序对象已经存在,我正在为我的应用程序组件添加额外的容器。我对你对这一点的任何批评都很感兴趣。我需要一段时间来创建一个自定义函数,但现在它就在这里。。。检查一下。同意评论回答,在这个阶段,这是代码中唯一采用这种方法的地方,应用程序已经过验证,但其余的没有。向前看,我会有应用程序。插件检查链上的某个更高的位置,因为单个插件不需要关心它们自己。另外+1用于优雅的功能。我这样做的原因是,在执行我的代码时,App对象已经存在,我正在为我的应用程序组件添加额外的容器。我对你对这一点的任何批评都很感兴趣。我需要一段时间来创建一个自定义函数,但现在它就在这里。。。检查一下。同意评论回答,在这个阶段,这是代码中唯一采用这种方法的地方,应用程序已经过验证,但其余的没有。向前看,我会有应用程序。插件检查链上的某个更高的位置,因为单个插件不需要关心它们自己。另外+1用于优雅的功能。被认为是最有力和最有洞察力的答案。