【问题标题】:How to use constructor for Javascript client如何为 Javascript 客户端使用构造函数
【发布时间】:2017-01-12 01:48:03
【问题描述】:

我正在试验一个简单的 Javascript API 客户端,但不确定如何实现构造函数模式。

到目前为止,我有这个(基于 Stripe 的 NodeJS 客户端):

//myapp.js
'use strict';

MyApp.DEFAULT_HOST = 'api.myapp.io';
MyApp.DEFAULT_PORT = '443';
MyApp.DEFAULT_BASE_PATH = '/v1/';

function MyApp() {
    if(!(this instanceof MyApp)) {
        return new MyApp();
    }

}

MyApp.prototype = {
    init: function(appId) {
        console.log("Initializing");
    }
}

在我的 HTML 文件中:

...
<head>
    <script type="text/javascript" src="myapp.js"</script>
    <script type="text/javascript">
        var client = new MyApp();
        client.init('12345');
    </script>
</head>
...

我不希望此客户端的用户需要添加 var client = new MyApp(); 行。如何修改myapp.js,让用户只需要像这样使用MyApp.init('12345');这一行:

...
<head>
    <script type="text/javascript" src="myapp.js"</script>
    <script type="text/javascript">
        MyApp.init('12345');
    </script>
</head>
...

【问题讨论】:

  • 这听起来像您希望 MyApp 成为单例 - 这既不是一个好习惯,也与构造函数无关。
  • 除非您正在执行副作用,否则不要使用init 方法,而是将所有内容放入构造函数中。
  • 谢谢。那么如果一切都在构造函数中,我将如何传递应用 ID?
  • 构造函数也有参数。
  • 我意识到构造函数也有参数,但是从使用 SDK 的人的角度来看,他们需要做什么才能从 HTML 文件中传递 AppId?一个简单的例子会很好。干杯

标签: javascript oop constructor


【解决方案1】:

这听起来像是您希望 MyApp 成为单例 - 这既不是一个好习惯,也与构造函数无关。

不要使用 init 方法,而是将所有内容都放在构造函数中:

function MyApp(appId) {
    if(!(this instanceof MyApp)) {
        return new MyApp(appId);
    }
    console.log("Initializing instance "+appId);
}
MyApp.DEFAULT_HOST = 'api.myapp.io';
MyApp.DEFAULT_PORT = '443';
MyApp.DEFAULT_BASE_PATH = '/v1/';

MyApp.prototype = … // add other methods

然后您的用户只需拨打var client = new MyApp('12345')。但请注意,任何副作用(例如在 DOM 中注册实例或其他东西)都应该放在一个名为 client 的单独方法中。

如果你想简化实例创建,你也可以使用静态方法,例如

function MyApp(appId) {
    console.log("Initializing instance "+appId);
}
MyApp.create = function(appId) {
    return new MyApp(appId);
};
MyApp.init = function(appId, …) {
    var client = this.create(appId);
    client.register(…);
    client.start(…);
    … // whatever
    return client;
};

【讨论】:

  • 为了模拟纯静态对象,我喜欢使用json对象。这样做有什么警告吗?它在一些需要类似模式的项目中运行良好。
  • @Frederik.L 我假设您的意思是带有方法的对象文字,而不是 JSON?但是,是的,这很好,当您不需要实例时,它们应该优先于类。只要确保它们不包含类似单例的全局状态即可。
  • 是的,我就是这个意思。由于类似的符号,我错误地将其称为 json 对象。区别很有趣,经过一番挖掘,区别在于对象字面量不一定使用字符串键和有效的 json 值(例如,函数无效),因此对象字面量!= json 对象。谢谢!
【解决方案2】:

如果要使用MyApp.initinit应该是静态方法:

function MyApp(appId) {
  if(!(this instanceof MyApp)) {
    return MyApp.init(appId);
  }
  // ...
}
MyApp.init = function(appId) {
  return new MyApp(appId);
};

【讨论】:

  • 你能解释一下为什么init应该是一个静态方法吗?
  • @tommyd456 因为init会创建实例,所以在实例上调用它是没有意义的。
猜你喜欢
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
相关资源
最近更新 更多