客户端应用程序的全局可变状态
Global mutable state of client-side applications
这可能是一个非常普通(可能很天真)的问题。
据我所知,"客户端"应用程序(即在浏览器中运行的应用程序)的编程模型意味着有一个共享的可变对象——网页的DOM——要由javascript程序更新Naive我看到的应用程序由几十个JS回调组成,这些回调更新了一个大型共享DOM
这是正确的吗?现代JS框架是如何管理它的?他们如何实现数据隐藏?
除非您依赖window.open
、iframes,或者允许您的应用程序跨越多个相互通信的窗口/选项卡(可能通过postMessage
进行cmunication),否则您没有其他选择来操作同一文档:只有一个文档。
然而,并不是因为一个文档被操纵,文档本身就不能被划分为多个封装的协作模块。Nicholas Zakas在他的Scalable JavaScript Application Architecture演示中很好地展示了这个概念。
模块应该在其操作所依据的文档中有一个非常严格的部分。这是他们自己的小沙箱,他们不应该进入其他模块的沙箱。如果他们需要沟通,他们会以一种非常解耦的方式(例如通过中介)进行沟通。
今天的大多数框架都依赖于模型-视图-控制器(MVC)的客户端变体(通常称为MV*/MVW)来实现这一目标。我不会在这里详细介绍,但主要目标是将数据与视图(表示)解耦,并经常将视图与在Controller对象中完成的用户操作的处理解耦。
直到最近,还没有真正的方法来强制封装。例如,不可能阻止jQuery插件外部的一些代码修改该插件生成的DOM结构。我们不得不依靠程序员的专业精神来确保他们不会触及插件的内部。
现在,有了引入ShadowDOM等新概念的Web组件规范,就可以进行真正的封装。不幸的是,该规范尚未在浏览器中实现,但幸运的是,有谷歌的Polymer项目,它可以被视为一个Web组件填充程序。
现代JS框架使用Javascript语言来:
- 注册对DOM事件的兴趣
- 响应DOM事件:
- 直接通过创建或更改对象状态,或者
- 通过发出远程"ajax"请求并使用响应更新其状态
- 通过(选择性地)更新DOM来反映其修改后的部分或全部状态
这就是现代客户端应用程序的基本运行循环。
当然,有很多框架可以用来实现这一点,每一个框架都以不同的方式实现基本范式。像jQuery这样的一些框架倾向于采用"DOM就是真理"的方法,并将其状态数据挂在DOM上,而像Ember.js这样的其他框架则相反,采用"模型就是真理"方法,并在DOM之外管理状态。
许多框架中使用的一种常见模式是MV*,即Model/View/Something。框架将具有某种管理状态的模型、某种视图/模板层,以及控制/协调/编排应用程序的其他层。这可能是临时的,也可能是不存在的(即数百个DOM事件回调),或者是非常结构化和复杂的,具体取决于框架。
有一点值得注意,因为有一些稍微有误导性的评论,那就是这些框架中的视图层并不等同于DOM。最终在DOM中的实际上是呈现视图的输出,即DOM是视图的呈现。
- 全局变量和全局对象的属性之间有什么区别吗
- 正在全局范围中查找JavaScript函数
- 事件和状态
- delete关键字在全局变量上的不同行为
- 从数组中删除元素,然后保留其状态以备将来使用,而不使用全局变量
- 网络状态的全局侦听器
- 反应组件交互和全局状态变化
- 使用 ajaxError 全局处理程序显示 HTTP 状态代码 401 详细信息
- 使用离子框架改变全局函数的状态
- 在 javascript 中创建一个全局库,同时保存状态和行为
- jQuery插件如何维护全局状态
- 客户端应用程序的全局可变状态
- Angular 2路由器全局状态更改事件
- Javascript存储/全局数据/对象的状态
- 如何将全局状态数据处理到Redux中的深度嵌套组件中
- 在MVC中存储全局状态变量的位置以及如何传递它
- 全局变量 在所有相位器状态下未更新
- Javascript全局变量在下次事件调用时返回到之前的状态
- Javascript 全局变量绑定的状态 在函数内
- lambda函数的简单全局状态