假设我有一个 JavaScript 库来生成如下所示的 DOM 片段
<main>
<h1>A heading</h1>
<p>A paragraph</p>
</main>
其中库
domlib
具有适用于任何类型元素的方法,并且生成上面片段的函数可能如下所示:
function(domlib){
return domlib.main(
domlib.h1('A heading'),
domlib.p('A paragraph')
);
}
在这个函数中,我宁愿调用这样的
domlib
方法:
main(
h1('A heading'),
p('A paragraph')
)
为了实现这一点,我可以将
domlib
的所有方法放在全局范围内,但我宁愿避免污染全局范围。对我来说,这似乎是 with
语句是理想解决方案的情况:
function(domlib){
with(domlib){
return main(
h1('A heading'),
p('A paragraph')
);
}
}
with
语句实际上已被弃用,并且会在严格模式下抛出错误。
除了将
domlib
方法分配给局部函数变量之外,我没有看到很多其他选项,但这很容易导致分配数十个局部变量,在这种情况下,第一种方法(直接调用 domlib
上的方法)将导致更简单的代码。
我的问题是,有没有其他替代方案可以实现我想要的,并且具有与使用
with
语句类似的简单性和可读性?
我将使用的方法是通过解构显式列出我想要的元素。
例如,在你的情况下,我会有这样的东西:
const component = ({main, h1, p}) => main(
h1('A heading'),
p('A paragraph')
);
这与做类似
const component = (domlib) => {
const {main, h1, p} = domlib;
return main(
h1('A heading'),
p('A paragraph')
);
};
你可以使用 es6 轻松实现这一点 :
const functionName = ({ main, h1, p }) => main(h1('heading'), p('paragraph'))
functionName(domlib)
但是跨浏览器会遇到困难,因为 es6 不完全支持
另一种选择是重新设计
domlib
,以便它以类似于的方式支持链接
domlib
.begin('main')
.h1('A heading')
.p('A paragraph')
.end()
...但在现实生活中的代码中,我宁愿将
domlib
替换为 $
或 _
:
function($){
return $.main(
$.h1('A heading'),
$.p('A paragraph')
);
}
每次调用两个额外字符的开销是避免欺骗和黑客行为的合理价格。
我对这个主题的 2 美分(KaboomJS/KaPlay 也有类似的问题,我想将其从 replit 移植到 vue 应用程序以供实习生使用)
let htmlFragment = (function() {
return main(
h1('A heading'),
p('A paragraph')
);
}).apply(domLib); // executes function with specific context
作为
with(domLib){}
的替代品
替代方案:
let func = (function() { return main(...); }).bind(domLib); // bind context for later use
let htmlFragment = func();