【问题标题】:JS: Best practice on global "window" objectJS:全局“窗口”对象的最佳实践
【发布时间】:2018-06-16 21:37:13
【问题描述】:

采用快速原型设计方法,我正在 Marionette.js/backbone.js 中开发一个应用程序,并大量使用窗口对象将集合和视图绑定到全局堆栈(例如 window.app.data、window.app .views)。

当然,将对象封装在单个类中并在需要时将它们作为参数传递总是更好(更顺畅!)。但是,当应用程序及其潜在用例变得非常大时,这会受到一些限制。由于我处理的数据来自 API,因此任何感兴趣的人都可以访问,这是否证明将数据存储在窗口对象中是合理的?或者在 ES6(或特别是 Marionette.js)中是否有其他最佳实践来实现相同的结果,但以更私密的方式?!

【问题讨论】:

  • 避免污染全局window 对象的一种方法是创建一个namespace for your app
  • 好吧,我还没有找到与 Browserify/AMD-modules 很好地集成的基于名称空间的解决方案(这将是只读的,不是吗?!)。另外,我不想将对象附加到命名空间,而是附加实际实例,以便我可以读取和写入已获取的数据。

标签: javascript backbone.js marionette


【解决方案1】:

我已经在另一个答案中进入details about a simple namespacing pattern in JavaScript。您似乎已经与 window.app.data 等接近。

但您似乎对 JavaScript 的工作原理有很多误解。

一个基于命名空间的解决方案,与 Browserify/AMD-modules 完美集成

那为什么不使用 RequireJS 呢?浏览器化?还是 Webpack?没有什么是遍布全球的意大利面条代码可以做到的,而模块化方法则不能做得更好。

这样是只读的

没有。虽然将对象属性设置为只读并非不可能,但您必须明确使用 Object.seal or Object.freeze 之类的内容。

我不想将对象附加到命名空间,而是附加实际实例

JavaScript 没有“命名空间”作为语言的一部分,它只是一种将所有代码限定在文字对象(键值)内的模式。

你可以放任何你喜欢的东西。

const MyNamespace = {
  MyType: Backbone.Model.extend({ /*...*/ }),
  instance: new Backbone.Model(),
  anyValue: "some important string",
};

理想情况下,您应该在 IIFE 中定义命名空间,以避免将任何变量泄漏到全局范围内。

const app = app || {};

app.MyModel = (function(app){
  return Backbone.Model.extend({
    // ...
  });
})(app);

[...] 我处理的数据来自 API,因此任何感兴趣的人都可以访问

即使数据包含在不泄漏到全局范围的模块中,任何人都可以访问数据。这就是 JavaScript 的工作原理,它在用户的浏览器中,他可以对代码和数据做任何他想做的事情。

这是否证明在窗口对象中存储数据是合理的?

没有。

或者 ES6 中还有其他最佳实践

ES6 与您为应用采用的架构和模式无关。

但以更私密的方式?!

就像我之前说的,JavaScript 中的隐私是不可期待的。

[将对象封装在单个类中并在需要时将它们作为参数传递]当应用程序及其潜在用例变得非常大时会受到一些限制。

这是不正确的。这是相反的方式。软件模式的存在只是为了帮助减轻随着项目范围扩大而出现的任何限制。

您可以使用多种模式来帮助处理大型应用程序的复杂性,例如:

  • 使用组件的模块化方法
  • 依赖注入
  • 服务容器
  • 工厂
  • 活动

我没有专门阅读这本书,但JavaScript Design Patterns 似乎是了解更多信息的好方法,它演示了 JS 中软件模式的具体实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2019-01-20
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    相关资源
    最近更新 更多