如何声明一个具有短函数名称的 javascript 类,然后分配给一个长类名称?

发布于 2024-08-20 21:48:25 字数 953 浏览 6 评论 0原文

让我解释一下,这是关于在 IDE 中显示类源代码。我总是每个文件只有一个类。在文件 mod1.js 中声明一个类是这样的:(

MYGLOB.MOD1.ClassXy = function () {
  //constructor, do somothing
}

MYGLOB.MOD1.ClassXy.prototype.memberfunc1 = function () {
  //member function 1, do somothing
}

在真实的类中还有很多类似 memberfunc1 的函数。)

但是在不同的 IDE 和编辑器中,函数列表的宽度现在非常大。我希望函数列表仅显示函数名称的最后一部分(函数名称本身)。

怎么样:

ClassXy = function () {
  //constructor, do somothing
}

memberfunc1 = function () {
  //member function 1, do somothing
}

MYGLOB.MOD1.ClassXy = ClassXy;
MYGLOB.MOD1.ClassXy.prototype.memberfunc1 = memberfunc1;

它在功能列表中显示很好。文件底部有 2 个长赋值,这并不妨碍。但我的全局命名空间被污染了。如何在不影响全局“ClassXy”和“memberfunc1”的全局命名空间的情况下执行此操作? (MYGLOB.MOD1.ClassXy 很好。)

我可以用括号/闭包来做到这一点吗?或者你有什么建议?并保持 IDE 中具有干净函数列表的效果,至少函数列表的第一部分向我显示成员函数及其短名称?

请不要建议不同的 IDE 或编辑器,这不是选择不同的代码编辑器,如果您想讨论这个问题,请自行提出不同的问题。这个问题是关于 javascript 和类的。

也许这是一件简单的事情,但我对 javascript 很陌生。

Let me explain, this is about displaying class source code in IDEs. I have always only one class per file. A class is declared like this in the file mod1.js:

MYGLOB.MOD1.ClassXy = function () {
  //constructor, do somothing
}

MYGLOB.MOD1.ClassXy.prototype.memberfunc1 = function () {
  //member function 1, do somothing
}

(There are many more functions like memberfunc1 in the real class.)

But in different IDEs and editors the width of the function list is now very large. I want the function lists to display only the last part of the function name (the function name itself).

How about this:

ClassXy = function () {
  //constructor, do somothing
}

memberfunc1 = function () {
  //member function 1, do somothing
}

MYGLOB.MOD1.ClassXy = ClassXy;
MYGLOB.MOD1.ClassXy.prototype.memberfunc1 = memberfunc1;

It displays nice in the function list. It does not disturb that there are the 2 long assignments at the bottom of the file. But I have the global namespace polluted. How to do this without affecting the global namespace with the global "ClassXy" and "memberfunc1"? (MYGLOB.MOD1.ClassXy is fine.)

Can I do this with parens / closures somehow or what do you suggest? And keep the effect of having the clean function list in the IDE, at least the first part of the function list showing me the member function with their short names?

Please don't suggest different IDEs or editors, this is not about choosing a different code editor, please open a different question on your own if you want to discuss that. This question is about javascript and classes.

Maybe this is a simple thing, but I am quite new to javascript.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离去的眼神 2024-08-27 21:48:25

这在一定程度上取决于您所使用的编辑器的功能,但模块模式对此很有用(并且通常可以避免全局命名空间污染)。我将假设您在定义类(实际上是对象)时这样做,但最后有一个关于在使用类时使用速记别名的注释(物体)也是如此。

模块模式的基本示例

var MYGLOB.MOD1.ClassXy = (function() {

    // Define your constructor function
    function ClassXy() {
    }

    // Define your member functions
    function memberfunc1() {
    }

    // Put your member functions on the prototype
    ClassXy.prototype = {
        memberfunc1: memberfunc1
    };

    // Return the constructor function to assign it to the MYGLOB.MOD1 object
    return ClassXy;
})();

替换原型;你可能只想添加它,在这种情况下,我建议在某个地方有一个实用程序函数来进行浅层属性复制:

function shallowCopy(dest, src) {
    var name;
    for (name in src) {
        // Depending on your needs, you may want to check
        // src.hasOwnProperty(name) here and only copy it
        // when that's true
        dest[name] = src[name];
    }
}

然后将上面对 prototype 的赋值替换为:

shallowCopy(ClassXy.prototype, {
    memberfunc1: memberfunc1
});

命名函数

除其他事项外,使用此模式意味着您使用命名函数而不是匿名函数。这有助于您的工具(特别是调试器)为您提供帮助。这种格式创建一个匿名函数并将其分配给对象的属性:

MyObject.functionName = function() { ... }; // Not ideal

而如果您使用模块模式,则可以正常声明函数,然后将它们分配给属性(见上文);这样它们就有了调试器可以在调用堆栈等中显示的名称。

私有实用函数

该模式还提供了一种很好的方法,让类可以使用实用函数(或类范围的数据),而无需让它们完全公开——不在构造函数上,不在其原型上,不在实例上。例如,下面是带有私有实用程序函数的上面的内容:

var MYGLOB.MOD1.ClassXy = (function() {

    // Define your constructor function
    function ClassXy() {
    }

    // Define your member functions
    function memberfunc1() {

        // Call our utility function. In this form, be aware that
        // within the utility, `this` will *not* be set within
        // the utility
        utility('bar');

        // Alternate form if you want to call `utility` as though it
        // were an instance member function; within the utility, it
        // can refer to `this` and have it mean the same thing it
        // means here in `memberfunc1`
        utility.call(this, 'bar');
    }

    // A utility function. This is entirely private to the class,
    // we don't make it a property of anything and so it's never
    // visible outside the closure
    function utility(foo) {
        alert("foo = " + foo);
    }

    // Put your member functions on the prototype
    shallowCopy(ClassXy.prototype, {
        memberfunc1: memberfunc1
    });

    // Return the constructor function to assign it to the MYGLOB.MOD1 object
    return ClassXy;
})();

使用助手

上面的内容乍一看可能有点笨拙,但是您没有理由不能创建助手来更轻松地以这种方式定义类。这就是我所做的;使用我的助手我会这样定义您的示例:

MYGLOB.MOD1.ClassXy = Class.defineClass(function() {

    // Takes the place of the constructor function; defining it is
    // optional, though, if you don't need to do anything when created
    function initialize() {
    }

    // A member function
    function memberfunc1() {
    }

    // Export our public symbols
    return {
        initialize:  initialize,
        memberfunc1: memberfunc1
    };
});

您可以从 我关于该主题的博客文章

使用冗长的 API

当您想要使用一个冗长的 API 时,也可以将同样的模式反过来:只需定义一个函数,将冗长的内容作为参数传递,并使用参数名称代替:

(function(xy) {

    // Use the member function; within this closure, xy = MYGLOB.MOD1.ClassXy
    xy.memberfunc1();

})(MYGLOB.MOD1.ClassXy);

It will depend a bit on the capabilities of the editors you're using, but the module pattern can be useful for this (and for avoiding global namespace pollution in general). I'll start the answer assuming you're doing this when defining your classes (objects, really), but there's a note at the end about using shorthand aliases when consuming classes (objects) as well.

Basic example of module pattern

var MYGLOB.MOD1.ClassXy = (function() {

    // Define your constructor function
    function ClassXy() {
    }

    // Define your member functions
    function memberfunc1() {
    }

    // Put your member functions on the prototype
    ClassXy.prototype = {
        memberfunc1: memberfunc1
    };

    // Return the constructor function to assign it to the MYGLOB.MOD1 object
    return ClassXy;
})();

There I replaced the prototype; you may want to just add to it instead, in which case I suggest having a utility function somewhere that does a shallow property copy:

function shallowCopy(dest, src) {
    var name;
    for (name in src) {
        // Depending on your needs, you may want to check
        // src.hasOwnProperty(name) here and only copy it
        // when that's true
        dest[name] = src[name];
    }
}

And then replacing the assignment to prototype above with this:

shallowCopy(ClassXy.prototype, {
    memberfunc1: memberfunc1
});

Named functions

Amongst other things, using this pattern means you're using named functions rather than anonymous ones. That helps your tools (debuggers in particular) help you. This format creates an anonymous function and assigns it to a property on an object:

MyObject.functionName = function() { ... }; // Not ideal

Whereas if you use the module pattern, you can declare your functions normally and then assign them to properties later (see above); that way they have names that debuggers can show you in call stacks, etc.

Private utility functions

The pattern also provides a nice way of having utility functions (or class-wide data) used by the class without having to make them public at all -- not on the constructor function, not on its prototype, not on instances. For instance, here's the above with a private utility function:

var MYGLOB.MOD1.ClassXy = (function() {

    // Define your constructor function
    function ClassXy() {
    }

    // Define your member functions
    function memberfunc1() {

        // Call our utility function. In this form, be aware that
        // within the utility, `this` will *not* be set within
        // the utility
        utility('bar');

        // Alternate form if you want to call `utility` as though it
        // were an instance member function; within the utility, it
        // can refer to `this` and have it mean the same thing it
        // means here in `memberfunc1`
        utility.call(this, 'bar');
    }

    // A utility function. This is entirely private to the class,
    // we don't make it a property of anything and so it's never
    // visible outside the closure
    function utility(foo) {
        alert("foo = " + foo);
    }

    // Put your member functions on the prototype
    shallowCopy(ClassXy.prototype, {
        memberfunc1: memberfunc1
    });

    // Return the constructor function to assign it to the MYGLOB.MOD1 object
    return ClassXy;
})();

Using a helper

The above may seem a bit clunky at first, but there's no reason you can't create helpers to make it easier to define classes this way. That's what I've done; using my helper I'd define your example like this:

MYGLOB.MOD1.ClassXy = Class.defineClass(function() {

    // Takes the place of the constructor function; defining it is
    // optional, though, if you don't need to do anything when created
    function initialize() {
    }

    // A member function
    function memberfunc1() {
    }

    // Export our public symbols
    return {
        initialize:  initialize,
        memberfunc1: memberfunc1
    };
});

You can grab the helper (and the reasoning behind it) from my blog post on the topic.

Consuming long-winded APIs

This same pattern can also be turned on its head, when you want to consume an API that's long-winded: Just define a function, pass in the long-winded things as arguments, and use the argument name instead:

(function(xy) {

    // Use the member function; within this closure, xy = MYGLOB.MOD1.ClassXy
    xy.memberfunc1();

})(MYGLOB.MOD1.ClassXy);
黑色毁心梦 2024-08-27 21:48:25

您始终可以使用对象作为名称空间。例如,您创建一个具有短变量名的对象并用它来保存您的函数。准备好后,您可以将其分配给您的实际生产类名称。

Fs = new Object();
Fs['ClassXy'] = function() {
    this.time = new Date();
    alert("From ClassXy: " + this.time);
};

Fs['memberfunc1'] = function() {
    alert("From memberfunc1: " + this.time);
};

ClassXy                       = Fs['ClassXy'];
ClassXy.prototype.memberfunc1 = Fs['memberfunc1'];

const aCX1 = new ClassXy();
aCX1.memberfunc1();

上面的示例代码有效。

希望这有帮助。

You can always use an object as a name space. For example, you create an object with short variable name and use it to hold your function. Once ready, you can assign it to your actual production class name.

Fs = new Object();
Fs['ClassXy'] = function() {
    this.time = new Date();
    alert("From ClassXy: " + this.time);
};

Fs['memberfunc1'] = function() {
    alert("From memberfunc1: " + this.time);
};

ClassXy                       = Fs['ClassXy'];
ClassXy.prototype.memberfunc1 = Fs['memberfunc1'];

const aCX1 = new ClassXy();
aCX1.memberfunc1();

The example code above works.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文