【问题标题】:passing javascript method params as object literal [closed]将javascript方法参数作为对象文字传递[关闭]
【发布时间】:2014-01-30 10:11:45
【问题描述】:

我习惯性地将参数作为对象字面量传递给函数,因此....

调用:

render({
 param1: 99
 param2: {'a': 88, 'b': 77}
});

方法:

render: function (p) {
 alert( p.param1);
 var data = p.param2;

 etc
}

我现在倾向于在所有情况下传递这样的参数 - 即使函数/方法只接受 1 个参数。原因是我觉得这个方法很简洁,而且如果我想在以后添加另一个参数,添加到对象很简单。

我想从一些经验丰富的 javascript 人员那里了解是否有任何理由说明以这种方式做事可能是一个坏主意 - 我不与其他开发人员合作,所以有时不确定我做事的方式是否正确。

谢谢!

【问题讨论】:

  • 这是一个非常常见的模式,你在网上看到的大多数 JS 中都能找到。
  • 如果您知道该函数只会接受一个参数,这似乎有点不必要,但我认为它没有任何问题(除了额外的击键)。
  • 当你必须传递多个参数时,我会鼓励你继续使用这种模式,想想在 jQuery 或其他 jQuery 插件等库中这种情况发生的频率。
  • 感谢 cmets - 我感到放心!
  • 有趣的问题,但确实“主要基于意见”:stackoverflow.com/a/22191929/1636522 ;)

标签: javascript parameter-passing


【解决方案1】:

参数桶基本上是个好主意。这里缺少什么:

render: function (p) {
 alert( p.param1);
 var data = p.param2;

 etc
}

如果未设置p.param2,您仍将继续使用undefined。存储桶需要使用默认值进行验证。有一个线程here,正在讨论这个。

为了更通用,您可以这样做:

render: function (p) {
 var myDefaults = { param1: 99
                     param2: {'a': 88, 'b': 77} };
 $.extend(p, myDefaults);

 alert( p.param1);
 var data = p.param2;

 etc
}

查看 here 获取 jQuery 文档

【讨论】:

  • 感谢 Axel - 使用 extend 是一个很好的建议! - 对 SO 来说太新了,不能投票给你的答案,但如果可以的话:)
【解决方案2】:

在我看来,如何传递您的参数是一个口味问题。我认为您应该验证您的对象文字参数或使用 jQuery.extend 之类的东西提供默认值:

var myParams = jQuery.extend({
  param1: 99 // default value for param1
  param2: { a: 10, b: 10 } // default value for param2
}, params);

在渲染方面,就像在您的示例中一样,性能可能是一个选项的参数。我做了一个快速测试http://jsperf.com/obj-literal-params。在我的情况下(Chrome 32)使用带有 jQ​​uery.extend 的对象文字参数比使用普通函数参数慢大约 80%。但与渲染功能的其余部分相关时,这可能是微不足道的性能损失。

我的结论是:用你最喜欢的,让代码更易读的东西

【讨论】:

  • 谢谢 - 与上面建议的 Axel 相同,而且是个好主意!
【解决方案3】:

没有参数... :)

我和你一样开始.. 但我注意到我的大部分功能都基于 ajax 或事件或基于插件。在那种情况下,我从不使用参数,否则我必须使用绑定并丢失本机事件。所以我尝试从全局或元素中获取我需要的一切。

(function(){
var myGlobals={};
function ajax(){
 //....
};
function handleAjax(e){
 myGlobals.currentAjaxResponse=JSON.parse(this.response);
}
function handleClick(e){
 myGlobals.elements
 myGlobals.currentAjaxResponse
 myGlobals.data
 e.target
}
function handleLoad(e){
 myGlobals.elements=document.getElemntsByClassName('buttons');
 myGlobals.elements[0].addEventListener('click',calculateXY,false);
 myGlobals.data={x:1,y:2}
 window.removeEventListener('load',handleLoad,false);
}
function calculateXY(){
 myGlobals.data.x+
 myGlobals.data.y+
 (myGlobals.elements[0].dataset['num']*1)+
 (e.target.dataset['num']*1)+
 myGlobals.currentAjaxResponse.key
}
window.addEventListener('load',handleLoad,false);
})()

仅当我使用一些基本实用程序来转换我使用的东西时:

function(argument){return result}

而且大多数时候我只需要一个参数。

正如你所说,如果我需要一个对象,我会传递一个对象。

【讨论】:

  • 谢谢 cocco - 我有时会按照你描述的方式使用“全局变量” - 通常是在 ajax 时发现我的大脑太小而无法应对上下文变化的任何地狱 - 我总是觉得对此有点内疚,可能是因为“全局”这个词 - 它确实让事情变得更容易。
  • 如果你这样写,名字就没有问题。因为什么都不能出去 (function(){})()
【解决方案4】:

这种模式肯定很有用,但我倾向于不使用它,除非它实际上是合理的 - 因为它正在考虑 jQuery.extend() 或数据绑定 (link)。

也许我不完全有资格谈论这个,但我担心它可能会导致软件架构方面的坏习惯。我的意思是,忽略函数的签名,你正在创建某种“包罗万象”的函数,很容易可变,但特征很差。真的是缺点吗?这个问题可能已经讨论过了,我认为值得思考。

同样值得注意的是,这种模式隐含地需要创建一个对象。除了可能对性能产生负面影响之外,这种编码风格对于不熟悉它的人来说可能更难理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多