【问题标题】:How to combine functions from many javascript classes into one object如何将多个 javascript 类中的函数组合到一个对象中
【发布时间】:2016-07-28 14:21:53
【问题描述】:

我有一个快速的 JavaScript 问题。

说我有RootFile.js

import UserApi from './UserApi'
export default class RootFile {

  get userApi() {
    return UserApi;
  }
};

然后我得到了UserApi.js

import Auth from './auth';
import Profile from './profile';

const merged = {
  ...new Auth, 
  ...new Profile 
}

export default merged;

然后我得到了单独的功能文件,例如auth.jsprofile.js

auth.js

export default class Auth{
  authLog(){
    console.log("DONE");
    //Gotta find a way to run this.
  }
}

profile.js

export default class Profile{
  profileLog(){
    console.log("DONE");
    //Gotta find a way to run this.
  }
}

现在我希望能够打电话:

import RootFile from './RootFile'

RootFile.userApi.profileLog();
//and
RootFile.userApi.authLog();

我无法让它工作,RootFile.userApiobject 的类型,但 authLogundefined。 我做错了什么?

【问题讨论】:

  • profileLogauthLog继承 方法,不会被 Object.assign 或属性扩展运算符复制。但是,您实际上并不真正想要将多个彼此无关的类组合在一个对象中。如果它们应该是可组合的,则将它们设为 mixin。
  • @Bergi 你能写一个答案来解释这样做的正确方法吗?
  • 我什至不确定您为什么要这样做,所以我不知道“正确”的方式是什么。这些东西应该是单例吗?如果没有class,你会怎么写?
  • 你看也许它们不一定是类,我真正想要实现的是,有一组与配置文件有关的函数,另一组与auth,另一组与其他事情有关的函数等等。我最终希望实现的是能够以一种干净的方式从我的UserApi 引用所有这些函数,而不必为每个函数编写单独的 getter的功能。来自 C++、Java 和 Objective-C,没有类的 JavaScript 对我来说总是很奇怪,所以也许这就是我感到困惑的原因。

标签: javascript ecmascript-6 ecmascript-next


【解决方案1】:

我最终做了以下事情:

我的RootFile.js 现在看起来像这样:

import UserApi from './UserApi'
export default class RootFile {

    get userApi(){
        return UserApi;
    }
};

我摆脱了get,因为@Tim 说它们的性能不高。

那么我的UserApi.js 现在看起来像这样:

import * as Auth from './auth';
import * as Profile from './profile';

const merged = {
  ...Auth, 
  ...Profile 
}

export default merged;

没有更多的new

然后我得到了单独的功能文件,例如auth.jsprofile.js

auth.js

export function authLog(){
    console.log("auth test ");
},
export default auth;

profile.js

export function profileLog(){
    console.log("profile test ");
} 
export default profile;

因此,正如@Bergi 建议的那样,不再上课了。

现在我可以打电话了:

import RootFile from './RootFile'

RootFile.userApi.profileLog();
//and
RootFile.userApi.authLog();

谢谢大家的回答,但毕竟我会这样做,效果很好。

【讨论】:

  • 更好:您应该使用命名导出而不是默认导出对象。你仍然可以import * as Auth from './auth';
  • @Bergi 刚刚更改了我的答案以反映这一点:) 谢谢。
  • 我已经简化了一点 :-) 我不确定你是否真的需要两个不同的文件 RootFileUserApi,目前看起来你应该合并它们合而为一。
  • 谢谢@Bergi,但你看我想在 RootFile 构造函数中运行代码。我想传递令牌并将其保存在其中的属性中。此外,将不仅仅是 userApi,因此根文件必须包含所有其他 api。我希望能够运行RootFile(token).userApi.whateverFunction();RootFile(token).whateverApi.whateverFunction();
  • 好的,当然,然后将RootFile 设为构造函数/工厂;您以前从未在问题或答案中以这种方式使用过它。虽然对我来说仍然很奇怪;为什么一个可实例化的对象会有静态的…Api 属性?
【解决方案2】:

我认为你不想这样做。在各自的类中分离逻辑的全部意义在于获得一个更结构化和更易于维护的库。

我会选择作文:

export default class RootFile  {

  get userApi() {
    // Some logic here?

    // Just return a newly created api for now:
    return new UserApi;
  }
};

UserApi做同样的事情:

export default class UserApi {

  get profile() {
    return new Profile;
  }
};

并像这样使用它:

rootFile.userApi.profile.log("etc");

为什么要作曲?

  • 这样您就不必担心函数的重新定义。
  • 速度更快,JavaScript 引擎现在可以针对您的类进行优化,而这对于合并的构造是不可能的。

还要记住,getter 的性能不如属性。我认为您应该考虑为常用的类成员使用属性

【讨论】:

  • 会有很多很多的功能,我真的很想将它们分散在单独的文件中。而且因为它们都将成为 UserApi 的一部分(并且还有其他类型的 API 我想要避免为每个功能使用单独的名称。
  • 我了解,您可以多次使用此模式来嵌套 API(请参阅编辑)。这样您就不必担心函数的重新定义。还要记住,getter 的性能不如属性。我认为您应该考虑为常用的类成员使用属性。
  • 感谢您抽出宝贵的时间来回答这个问题,但我真的很想打电话给rootFile.userApi.profileLog() 而不是将其与profile.log() 分开另外关于吸气剂的性能较差,如果是这样,我会转储它们我不知道的情况,谢谢!
  • 好的。也许如果你能告诉我你为什么要这样,我可以提供进一步的帮助。
  • @SudoPlz:如果你只想将一个大类分布在多个文件中,你应该让文件只导出方法而不是一个完整的类。
【解决方案3】:

我认为... 扩展运算符的使用是不正确的。尝试改用Object.assign - 它接受一个目标对象并将其他对象的所有可枚举属性分配给它。

import Auth from './auth';
import Profile from './profile';

let merged = {};
Object.assign(merged, new Auth, new Profile);

export default merged;

【讨论】:

  • 我在 SO stackoverflow.com/a/32372430/1658268 的这个答案中看到了 ... 扩展运算符用于此目的
  • 我会试一试,几分钟后告诉你..!
  • @SudoPlz:默认情况下,最新版本的 Babel (v6) 不再包含第 2 阶段和更高版本提案的功能 - 我认为您链接的答案来自该版本发布之前。您现在必须在您的 .babelrc 配置(以及标准 ES2015 配置)中包含 stage 2 preset 才能获得该行为。
  • 扩展运算符确实不是 ES6(ES7 中也不会出现),但是 Object.assign 没有做任何不同的事情,它仍然不起作用。
猜你喜欢
  • 2022-12-05
  • 2019-06-28
  • 1970-01-01
  • 2023-01-11
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多