参数化方法与全局变量


10

当我的代码开始增长时,我有一个很简单的问题困扰了我一段时间。

当参数经过嵌套函数调用的长路径时,是否应将其替换为全局变量?

我知道全局环境会使程序的状态不可预测,因为许多函数可以修改共享变量,但是全局空间仍然使事情变得如此容易。

让我解释一下自己:

functionA(){
   x = something
   functionB(x)
}
functionB(x){
   functionC(x)
}
functionC(x){
   finallyDoSomethingWithX(x)
}
finallyDoSomethingWithX(x){
  x += 1 //Very dummy example ignoring pass by value, not reference.
}

取而代之:

globalX;
functionA(){
   globalX = something
   functionB()
}
...
...
...
finallyDoSomethingWithX(){
   globalX += 1
}

我觉得第二种方式给程序带来了很大的自由度,因为参数很容易累积,并且有时在必须重用代码时可能会受到很大的限制,但是与此同时,我觉得函数在与变量相关时会失去其模块化在全球环境中,例如当我想finallyDoSomethingWithX使用另一个变量tha 时,它也失去了可重用性globalX

我认为这是发生在我身上的原因,因为我实际上不是在使用设计模式,因为我使用Javascript进行编程,对我而言,这感觉像是针对中型项目的所有语言的一种脚本交易。

有什么建议吗?模式?如果需要,我可以更具体。


5
通常,如果要非常深入地传递变量,则说明问题没有得到正确解决。至于驱动系统中其他位置的状态的全局变量,请像瘟疫一样避免使用。在某一点上不可能进行管理,并且您会发现事情随机中断,因为某些状态被您不期望的函数所突变。
mgw854 '17

避免像瘟疫一样。明白了 您能否详细说明一下“您没有正确解决问题”。我了解一般的想法,但是我无法提出一个例子或一些东西来深入地理解它。
AFP_555 '17

2
当您发现自己传递了很多层参数时,一种常见的补救方法是创建一个方法对象:新类的对象,其新方法与传递参数的函数相对应。然后,参数可以成为对象本地变量,并且其方法不再需要传递值。
吉莲·佛丝

@KilianFoth谢谢。您能否详细说明一些代码,以便我检查答案?
AFP_555 '17

1
考虑像对待其他语言(例如使用“真实”类的语言)一样对待JavaScript代码的结构。:对SO此相关的问题一些有用的链接 stackoverflow.com/questions/927651/...
本·科特雷尔

Answers:


7

不要使用全局变量。

另外,请勿将参数传递给函数的下链!

这很困难,因为您没有使用实际的示例。但是通常会有更好的方法。

假设我们有一个密码变量,我们需要使用该变量来调用api,而这些api又会被各种底层函数使用。

全局方法(伪代码)

var pass;

function multiply(a,b) {
   return apiMultiply(pass,a,b);
}

参数传递方式

function multiply(a,b,pass) {
    return apiMultiply(pass,a,b);
}

对象方法

class math {
    var api;
    constructor(pass) {
        api = new api(pass);
    }

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}

优秀。这种方式的传递不是在全局环境中,也不是多个函数的参数,因为它可以从对象的属性中获取。谢谢。
AFP_555 '17

3

避免像瘟疫这样的全球性疾病。

任何代码都可以修改全局代码。因此,如果您有一条链A(x)-> B(x)-> C(x)-> ...-> Z(x),并将x存储到全局X中,那么现在有了一条链A- > B-> C-> ...-> Z,那么在该长链的每一步或完全独立的代码中,某人都可以更改X。Z所使用的值可能与A所使用的值完全不同。开始。

如果您想确保自己的代码能够执行应做的事情,或者想要执行自己想做的事情,那将是一场噩梦。


1
完全同意。如果使用全局变量解决问题,那么现在有两个问题。
卡雷布·莫尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.