JavaScript:在函数间传递大对象或字符串被视为不良实践

6

在函数之间传递一个大字符串或对象(假设是从ajax响应中获取的),这是否被认为是一种不好的做法?将响应保存在变量中并重复使用该变量有什么好处吗?

因此,在代码中,应该像这样:

var response;

$.post(url, function(resp){
   response = resp;
})

function doSomething() {
  // do something with the response here
}

vs

$.post(url, function(resp){
   doSomething(resp);
})

function doSomething(resp) {
  // do something with the resp here
}

假设 resp 是一个大的对象或字符串,并且可以在多个函数之间传递。

3
传递函数参数比杂乱全局命名空间更可取。 - Blunderfest
1
@Malcoda 它不一定要是全局的,它可以在闭包中。 - Scimonster
5
在JavaScript中传递对象引用并不昂贵。 - Pointy
1
在函数式编程中,你传递一切,这是很好的。 - dandavis
1
response = resp;这样赋值外部变量的做法必然会让代码难以维护(如果它能工作的话,还要考虑不可避免的竞态条件)。从闭包中赋值可能看起来很有用,但我总是能找到更好的解决方案,通常涉及启动回调,传递直接参数,并查看回调的返回值。如果这种策略似乎太普通,那么它通过有效性和可维护性获得了它的普遍性。 - Keen
显示剩余3条评论
1个回答

11

Javascript中的对象和字符串是传递引用的。 (严格来说是按值传递引用,这意味着在函数内部使用=重新分配变量不会影响函数外的变量,但这与本问题无关。)

这意味着将它们传递给函数并不昂贵,因为不会复制任何内容。传递给函数的只是指向原始对象的指针,这是高效的。


你需要认识到你的第一个方案甚至不能正常工作:

var response;

$.post(url, function(resp){
   response = resp;
})

function doSomething() {
  // do something with the response here
}

因为事情的时机,你不知道何时调用doSomething()。正如你展示的$.post()是异步的,因此你无法确定它实际上何时完成。在你的代码中,必须使用完成函数中的resp值。你必须要么在完成函数中使用它,要么从完成函数中调用某些东西并将resp传递给它(就像你的第二个示例)。只有这样,当数据可用时才能正确地控制时间。


2
@djechlin - 请用任何人都能理解的术语解释“按引用值”是什么意思,以及它与“按引用”有何不同。我知道语言内部发生了什么,但我想看看是否可以用易于理解的方式解释这个术语,而不会使理解正在发生的事情更加困难。 - jfriend00
1
很多用户认为Javascript以某种方式按引用传递,当它的行为与预期不符时,他们就会哭喊着回到SO,所以当好的答案对此粗心大意时,情况尤其糟糕。如果我的括号表述让用户感到困惑,那么他们可能应该花些时间来理解这个问题。是的,这是我的观点,我知道这是有争议的,但我坚持这样的看法。 - djechlin
@FelixKling - “传递共享”是一个有趣的短语,试图代表中间状态(通过指针传递,但不是完全的反向引用),但如果没有解释,它对大多数人来说并没有意义,因为它不是一个被广泛理解的标准术语。如果我必须选择一个短语,我可能会使用“作为指向原始对象的指针内部传递”,这样在传递时不会复制对象,因此可以更改原始对象的属性。 - jfriend00
1
@jfriend00:我同意。在我看来,它仍然是按值传递,只是该值是一个引用。从外部来看,这肯定会让人感到非常困惑 :) - Felix Kling
1
@mr-smee - 这是一篇关于值与引用以及参数传递的好文章:http://docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm - jfriend00
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接