如何使用链式变量构建类似名称空间的字符串

How to build a namespace-like string using chained variables

这很奇怪,但我正在探索它是否可行。

假设我有一个使用 PubSub 的 .NET 应用程序。我想要一种使用链接对象(不是函数)来定义主题字符串的方法。目标是让我有一种定义字符串的方法,让我可以利用 Visual Studio 的 IntelliSense 并减少拼写错误的可能性。

这是一个例子:

/* Manual way */
var topic = "App.Navigation.CurrentItem"



/* Desired Solution */

// ... define the objects here ...

var topic = App.Navigation.CurrentItem;
console.log(topic); // "App.Navigation.CurrentItem"

var topic2 = App.Footer.CurrentItem;
console.log(topic2); // "App.Footer.CurrentItem"

我希望每个对象负责输出它自己的值,并让链接过程负责通过预定义的分隔符(在我的例子中,一个句点将自己连接到前一个链接的对象[.]).

我一直在玩 JavaScript getter 语法,但我很好奇是否有更好的方法。

有没有人以前做过这样的事情,如果有,你是怎么解决的?

我不太清楚你的要求,但你在找这样的东西吗?

function namespace(ns) { this._ns = ns; }
namespace.prototype.toString = function() {return this._ns};
namespace.prototype.extend = function(suffix) {
    return new namespace(this._ns + "." + suffix)
};

用法:

App = new namespace('App');
App.Navigation = App.extend('Navigation');
App.Navigation.CurrentItem = App.Navigation.extend('CurrentItem');
console.log(App.Navigation.CurrentItem.toString()); // "App.Navigation.CurrentItem"

这是我在查看 StriplingWarrior 的回答后得出的结论:

function Namespace(name, config) {
    if (typeof name === "object") {
        config = name;
        name = null;
    }
    config = config || {};

    this._ns = name;
    this.define(config);
}
Namespace.prototype.toString = function() { return this._ns };
Namespace.prototype.define = function(config, base) {
    base = base || this;

    for (key in config) {
        var name = (base._ns) ? base._ns + "." + key : key;
        base[key] = new Namespace(name);
        base.define(config[key], base[key]);
    }

    return base;
};

用法:

var App = new Namespace("App", {
    Navigation: {
        Items: {
            Current: {}
        }
    },
    Content: {},
    Footer: {
        Items: {
            Current: {}
        }
    }
});

console.log(App.toString()); // App
console.log(App.Navigation.Items.Current.toString()); // App.Navigation.Items.Current
console.log(App.Footer.toString()); // App.Footer

我还写了一个方便的方法来减少 toString():

function NS(namespace) {
    return namespace.toString();
}

console.log(NS(App.Navigation.Items.Current));

再次感谢 StriplingWarrior 的帮助!