【问题标题】:declare static variable in javascript在javascript中声明静态变量
【发布时间】:2017-12-13 11:32:26
【问题描述】:
 var i=0;
 function mul()
 {
    var qty = document.getElementsByClassName("qty");
    var rs = document.getElementsByClassName("rs");
    var amt = document.getElementsByClassName("amt");
    var mul=(qty[i].value)*(rs[i].value);
    amt[i].setAttribute("value",mul);
   sp.appendChild(iteminp);
   sp.appendChild(qtyinp);
   sp.appendChild(rsinp);
   sp.appendChild(amtinp);
   i++;
}

在上面的程序中,我希望每次调用函数时都增加 'i' 的值,并且它在整个程序中都应该像静态变量一样。 怎么办?

【问题讨论】:

  • 有什么问题?
  • 正是这样。它是全局的,所以每个函数都会看到相同的i
  • 只需将var 放在i 之前。那么i 将是一个全局变量
  • i 无处可被视为静态。你只是想要一个全局变量吗?如果是,则将其声明为window._i = 1;,但这似乎是实现某些目标的坏方法。 (通常的做法是在全局变量前加上下划线,当然不要只叫它i

标签: javascript variables static


【解决方案1】:

JS 变量是函数的局部变量,或者它们是全局变量。由于您在函数外部声明了i,因此它是全局的。

为了证明这一点,将其保存为 test.html,在浏览器中打开它并按几次按钮。我稍微简化了你的功能!

<script>
var i=0
function mul(){
  alert("i: " + i++)
}
</script>
<button onclick='mul()'>Press me</button>

【讨论】:

  • 不,您会看到上面的代码,我确实喜欢这样,但是,如果我第二次调用该函数,它会显示错误“未捕获的类型错误:无法读取未定义的属性'值' "
  • 我认为错误消息来自这一行:(qty[i].value)*(rs[i].value) - 如果qty[i]rs[i] 不评估某些东西(因为qtyrs 在元素处没有任何内容i) 那么你会得到那个错误。所以我认为这个问题与i 是全球性的无关。
  • 是的,你是对的,错误就在那一行,但问题是什么?
  • 当我第一次运行它时它成功执行但第二次它显示这样,但第二次我提供了一个值,但我不知道为什么会这样像这样展示如何解决它。你能帮忙解决这个问题吗?
  • 您能提供您的联系电话号码吗?
【解决方案2】:

您可以有一个名为 globals.js 的 javascript 文件(不要忘记将其包含在您的 index.html 中),然后声明您的全局变量,该变量将在您的所有网络解决方案中可用。

globals.js:

var _i = 0; // Would not recomend using "i" as the variable name since it 
            // can polute the global scope

yourFile.js:

 function mul()
 {
   var qty = document.getElementsByClassName("qty");
   var rs = document.getElementsByClassName("rs");
   var amt = document.getElementsByClassName("amt");
   var mul=(qty[_i].value)*(rs[_i].value);
   amt[_i].setAttribute("value",mul);
   sp.appendChild(iteminp);
   sp.appendChild(qtyinp);
   sp.appendChild(rsinp);
   sp.appendChild(amtinp);
   _i++;
}

【讨论】:

  • 它是一样的,它不起作用。你能告诉我任何其他的方法来解决这个问题吗?
【解决方案3】:

您可以创建一个装饰器函数,该函数可以用一个计数器包装您的函数,让您可以通过只读属性访问计数。

由于使用了Symbol,此解决方案将需要现代浏览器,但您可以将其替换为 dunder 属性,例如。 __count__ 在它的位置。

// this is used to create a privaty property on your function
const COUNT = typeof Symbol !== 'undefined' ? Symbol('count') : '__count__'

// this function takes your function and wraps it with a counter
function counter(fn) {
  // this is called whenever you call the decorated function
  function _counter(...args) {
    // increment the counter
    _counter[COUNT]++
    // call the original function
    return fn(...args)
  }
  // create the private property on your function and the accessor
  Object.defineProperties(_counter, {
    [COUNT]: { value: 0, writable: true },
    name: { value: fn.name || 'counter' },
    count: { get: () => _counter[COUNT] }
  })
  // return the decorator function
  return _counter
}

// function to decorate
function _mul(x, y) {
  // do something to multiply
  return x * y
}

// decorate your functions with the counter
const mul = counter(_mul)
const mul2 = counter(_mul)

// proof that both counters are independent and work correctly
console.log(
  mul(1, 2), // 2
  mul(3, 4), // 12
  `mul has been called ${mul.count} times`
)
console.log(
  mul2(5, 6), // 30
  mul2(7, 8), // 56
  mul2(9, 10),// 90
  `mul2 has been called ${mul2.count} times`
)
&lt;script src="https://codepen.io/synthet1c/pen/KyQQmL.js"&gt;&lt;/script&gt;

【讨论】:

  • 我看不懂,你能建议我在我上面的程序中编辑一下吗
  • 可以给你手机联系方式吗?
  • 嗨,对不起,我没有回复。我提供的功能包装了您的功能。它将附加一个计数器属性,当您需要知道它被调用了多少次时,您可以使用mul.count 访问该属性。这是最好的解决方案,因为您不会用变量污染全局命名空间。尤其是 i 的使用会在以后咬你,因为按照惯例,它在 for 循环中使用。
猜你喜欢
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多