在Nicholas Zakas和Addy Osmani的这些会谈中,他们讨论了在构建大规模Javascript应用程序时使用Facade模式作为沙箱的想法,以便将应用程序与底层基础库分离。 / p>
这种解耦理论上允许您切换基础库而无需重写应用程序模块。但实际上,这似乎更难以实施。
此建议架构的具体实现,例如AuraJS。然而,从查看源代码看,沙箱似乎仍然通过从其某些方法返回jQuery对象而具有泄漏抽象。
我并不特别关注AuraJS,而是更多关注尝试抽象像jQuery这样的库而不会失去太多功能的一般概念。
举个例子,假设我的facade / sandbox有一个dom方法.find(selector)
。我可以想到它可能会返回的3个选项:
一个jQuery对象 - 这会将jQuery泄漏到消费模块中。
原始dom元素 - 功能丧失,没有人真正想要使用它!没有链接。
一个类似jQuery的自定义包装器 - 可能非常复杂,但似乎是理想的解决方案。
所以我的问题是,你如何在不丢失太多功能的情况下抽象像jQuery这样的库,这样可以在未来的某个时候用最小的努力来替换它?
答案 0 :(得分:0)
我认为你在考虑编写更多的模块化代码,但jquery并不是一个很好的例子。
答案 1 :(得分:0)
以下是使用模块作为架构的一个非常简单的示例:
<!DOCTYPE html>
<title>Module play</title>
<body>
<script>
// myCore provides all functionality required by modules
// Could use a library in here
var myCore = {
getContainer: function() {
// code in here to find a suitable container in which to put widgets
// This is where different client capabilities will be tested to ensure the
// widget behaves in it's user agent context - desktop, phone, tablet, pad, etc.
// very simple shortcut
return {
element: document.body,
// This function could use a general purpose library
add: function(widget) {
this.element.appendChild(widget.getElement());
}
};
},
// This function could use a general purpose library
getNewWidget: function() {
var element = document.createElement('div');
return {
getElement: function() {
return element;
},
display: function(text) {
// Tightly couple to itself or not?
this.getElement().innerHTML = '<em>' + text + '</em>';
// or
element.innerHTML = '<em>' + text + '</em>';
}
}
}
};
// Missing sandbox layer...
// Add a module - only uses myCore API (access should be controlled by
// the sandbox), does not deal with underlying library or host objects
(function() {
// Get a container to add a widget too
var container = myCore.getContainer();
// Create a widget
var widget = myCore.getNewWidget();
// Add the widget to the container
container.add(widget);
// Give something to the widget to display
widget.display('Hello World');
}());
</script>
</body>
所以你可以看到,在模块级别,你不关心主机环境或底层库,你只是编写简单的ECMAScript。你可以得到真正的防守并做类似的事情:
(function() {
var container, widget;
if (!myCore) return;
if (myCore.getContainer) { // Some would include an isCallable test too
container = myCore.getContainer();
}
// getWidget could be a method of container instead so that
// everything you need is either a method or property of container
// or widget
if (myCore.getWidget) {
widget = myCore.getWidget();
}
...
}
等所有内容都经过测试和检查。我遗漏了错误处理,但希望这个例子已经足够了。