Chr*_*phe 148 javascript json arguments function object
在创建具有多个参数的JavaScript函数时,我总是面临这样的选择:传递参数列表与传递选项对象.
例如,我正在编写一个函数来将nodeList映射到数组:
function map(nodeList, callback, thisObject, fromIndex, toIndex){
...
}
Run Code Online (Sandbox Code Playgroud)
我可以改用它:
function map(options){
...
}
Run Code Online (Sandbox Code Playgroud)
options是一个对象:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
Run Code Online (Sandbox Code Playgroud)
推荐哪种方式?是否有何时使用其中一种?
[更新]似乎有一个共识支持选项对象,所以我想添加一个注释:在我的案例中我试图使用参数列表的一个原因是有一个与JavaScript一致的行为内置于array.map方法.
Jer*_*her 147
像许多其他人一样,我经常更喜欢传递options object一个函数而不是传递一长串参数,但它实际上取决于确切的上下文.
我使用代码可读性作为试金石.
例如,如果我有这个函数调用:
checkStringLength(inputStr, 10);
Run Code Online (Sandbox Code Playgroud)
我认为代码是可读的,并且传递单个参数就好了.
另一方面,有这样的调用函数:
initiateTransferProtocol("http", false, 150, 90, null, true, 18);
Run Code Online (Sandbox Code Playgroud)
除非你做一些研究,否则完全不可读.另一方面,这段代码读得很好:
initiateTransferProtocol({
"protocol": "http",
"sync": false,
"delayBetweenRetries": 150,
"randomVarianceBetweenRetries": 90,
"retryCallback": null,
"log": true,
"maxRetries": 18
});
Run Code Online (Sandbox Code Playgroud)
它更像是一门艺术,而不是一门科学,但如果我不得不说出经验法则:
在以下情况下使用options参数:
Ber*_*rgi 28
多个参数主要用于强制性参数.他们没有错.
如果您有可选参数,则会变得复杂.如果其中一个依赖于其他人,以便他们有一定的顺序(例如第四个需要第三个),你仍然应该使用多个参数.几乎所有原生的EcmaScript和DOM方法都是这样工作的.一个很好的例子是openXMLHTTPrequests的方法,其中最后3个参数是可选的 - 规则就像"没有用户的密码"(参见MDN文档).
选项对象在两种情况下派上用场:
undefineds).在你的情况下,我建议map(nodeList, callback, options).nodelist并且callback是必需的,其他三个参数仅偶尔出现并具有合理的默认值.
另一个例子是JSON.stringify.您可能希望在space不传递replacer函数的情况下使用该参数- 然后您必须调用…, null, 4).一个参数对象可能更好,虽然它只对2个参数不合理.
Flu*_*yte 11
使用"选项作为对象"方法将是最好的.您不必担心属性的顺序,并且可以更灵活地传递数据(例如,可选参数)
创建对象也意味着可以在多个函数上轻松使用这些选项:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
function1(options){
alert(options.nodeList);
}
function2(options){
alert(options.fromIndex);
}
Run Code Online (Sandbox Code Playgroud)
ajx*_*jxs 10
我的回答可能有点晚了,但我正在寻找其他开发人员对这个主题的看法,并发现了这个帖子。
我非常不同意大多数回应者的观点,并支持“多重论点”的方法。我的主要论点是它不鼓励其他反模式,例如“改变并返回参数对象”或“将相同的参数对象传递给其他函数”。我曾在广泛滥用这种反模式的代码库中工作过,并且调试执行此操作的代码很快变得不可能。我认为这是一个非常特定于 Javascript 的经验法则,因为 Javascript 不是强类型的并且允许这种任意结构化的对象。
我个人的观点是,开发人员在调用函数时应该明确,避免传递冗余数据并避免引用修改。这并不是说这种模式妨碍编写简洁、正确的代码。我只是觉得这会让你的项目更容易陷入不良的开发实践。
考虑以下可怕的代码:
function main() {
const x = foo({
param1: "something",
param2: "something else",
param3: "more variables"
});
return x;
}
function foo(params) {
params.param1 = "Something new";
bar(params);
return params;
}
function bar(params) {
params.param2 = "Something else entirely";
const y = baz(params);
return params.param2;
}
function baz(params) {
params.params3 = "Changed my mind";
return params;
}
Run Code Online (Sandbox Code Playgroud)
这种类型不仅需要更明确的文档来指定意图,而且还为模糊错误留下了空间。如果开发人员修改param1了怎么办bar()?您认为浏览足够大小的代码库需要多长时间才能发现这个问题?诚然,这个例子有点不诚实,因为它假设开发人员此时已经提交了几种反模式。但它显示了传递包含参数的对象如何允许更大的错误和歧义空间,需要更大程度的责任心和遵守 const 正确性。
只是我对这个问题的两分钱!
我想如果你要实例化某个东西或者调用一个对象的方法,你想要使用一个options对象.如果它是仅对一个或两个参数进行操作并返回值的函数,则最好使用参数列表.
在某些情况下,使用两者都很好.如果您的函数有一个或两个必需参数和一堆可选参数,则需要前两个参数,第三个是可选选项哈希.
在你的例子中,我会这样做map(nodeList, callback, options).需要节点列表和回调,只需通过读取它就可以很容易地判断发生了什么,就像现有的地图功能一样.任何其他选项都可以作为可选的第三个参数传递.
您对该问题的评论:
在我的例子中,最后三个是可选的.
那么为什么不这样做呢? (注意:这是相当原始的Javascript.通常我会使用default哈希并使用通过使用Object.extend或JQuery.extend或类似的传递的选项更新它.)
function map(nodeList, callback, options) {
options = options || {};
var thisObject = options.thisObject || {};
var fromIndex = options.fromIndex || 0;
var toIndex = options.toIndex || 0;
}
Run Code Online (Sandbox Code Playgroud)
所以,现在因为现在更明显的是什么是可选的,什么不是,所有这些都是函数的有效用途:
map(nodeList, callback);
map(nodeList, callback, {});
map(nodeList, callback, null);
map(nodeList, callback, {
thisObject: {some: 'object'},
});
map(nodeList, callback, {
toIndex: 100,
});
map(nodeList, callback, {
thisObject: {some: 'object'},
fromIndex: 0,
toIndex: 100,
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36843 次 |
| 最近记录: |