【问题标题】:Is setting properties on the Window object considered bad practice?在 Window 对象上设置属性是否被认为是不好的做法?
【发布时间】:2011-04-10 10:15:41
【问题描述】:

我正在编写一个非常复杂的 JavaScript 应用程序,它具有我正在使用 Prototype 的 Class 支持和模块模式实现的 MVC 架构。该应用程序使用 AJAX 和观察者模式。我在 DOM 加载后创建我的控制器实例,将视图和一些从 JSON 数据创建的模型传递给它,然后它就消失了。

但是,我发现我必须将我的控制器实例设置为 Window 对象上的一个属性——即不使用 var 声明它——因为我有一个 AJAX 成功回调,它刷新控制器拥有的视图对象,此时在代码中我漂亮的小 MVC 世界不在范围内。

我调查了将视图对象作为参数传递给包含 AJAX 代码的函数,但这变得非常混乱,并且会导致一些严重违反 MVC 模式的行为,例如耦合模型和视图。太可怕了。

将我的控制器实例直接存储在Window 上是否被认为是错误的形式?对我来说,这闻起来有点像使用全局变量,但我看不出有什么办法。

【问题讨论】:

  • 你能发布一个小代码示例吗?
  • 我不能,我害怕。我在家,代码在工作,更重要的是,我想我必须发布大量代码来说明这一点——我不喜欢阅读“文字墙”问题,所以我不想强加给别人!
  • 为什么 MVC 会超出范围?你的 AJAX 回调不应该至少在闭包中捕获对它的引用吗?
  • 我对闭包不太精通。本质上,AJAX 函数在控制器中,它被模型函数调用,而模型函数本身被另一个模型实例的更新调用(因此是观察者模式)。我正在使用 Prototype 的 onSuccess 回调,此时 this 指的是 Window
  • 然后简单地在回调代码之前加上var that = this之类的东西,然后将回调中对this的所有引用更改为that。或者,使用 Prototype 的 Function.bind 来修复 this 的值

标签: javascript architecture


【解决方案1】:

在窗口对象上设置属性相当于创建全局变量。也就是说,有时这样做是不可避免的,但您应该尽量将其保持在最低限度,因为它最终会污染全局命名空间。

在您的情况下,创建单个属性还不错。如果您想格外小心,可以为需要全局访问的任何内容显式创建命名空间:

// In init:
var mynamespace = {};

. . .

// Once the controller is available:
var namespace = window.mynamespace;
namespace.controller = controller;
namespace.foo = bar; // Set other stuff here as well.

【讨论】:

  • 谢谢。出于某种原因,我没想过要使用命名空间,即使我在别处使用。
【解决方案2】:

我会说这是不好的做法。如果需要,您可以随时轻松地为您的应用程序创建命名空间并将全局变量放入其中。

【讨论】:

    【解决方案3】:

    当您要调用事先不知道名称的全局函数时,它们很有用。

    var funcName = "updateAns" + ansNum;
    window[funcName]();
    

    它们可以用来 a) 在大多数情况下避免邪恶的评估。 b) 避免对全局变量的引用错误。

    x = x + 1 如果未定义全局 x,将生成引用错误。 window.x = window.x + 1不会

    【讨论】:

      猜你喜欢
      • 2012-01-05
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 2018-08-11
      • 2015-07-24
      相关资源
      最近更新 更多