【问题标题】:If a variable is defined in terms of another, can it reflect changes in the binding of the other?如果一个变量是根据另一个变量定义的,它能否反映另一个变量绑定的变化?
【发布时间】:2021-10-19 10:05:21
【问题描述】:

我有一个变量,它的值部分是根据另一个变量定义的。我想更改该变量的值,以便初始变量也发生更改。但这不会发生。看第二行:

var offset = 0;
var message = "the number is " + offset;

如果我修改offset,那么message 不会改变:

console.log(message); // This says "the number is 0".
offset += 20;         // `offset` is changed to `20`.
console.log(message); // The message is still "the number is 0".

message,在这种情况下,将被称为“反应性”变量。

为什么它不起作用,我将如何解决它?

【问题讨论】:

  • 这不是变量在我所知道的任何语言中的工作方式。
  • 它不起作用,因为 JavaScript 中的变量(就像在大多数语言中一样)使用急切赋值而不是惰性赋值。为了实现你想要的,你可能需要将消息构造为一个函数。
  • 定义,已构建。您有一个变量,其值部分是 built 与另一个变量。如何解决?使用新值再次构建 message。而且因为一遍又一遍地编写相同的代码很烦人,所以把它放在一个 (template) 函数中。

标签: javascript variables


【解决方案1】:

表达式'the number is' + offset 只计算一次。不管你更新了多少次offset,JavaScript 不会跟踪messageoffset 之间的任何关系,它们是两个独立的变量。

正如建议的那样,您可以使用函数而不是变量来表示消息。

var offset = 0;

function message() {
    return 'the number is ' + offset;
}

console.log(message());  
offset += 20;             
console.log(message());   

这样,每次都会重新计算消息。

【讨论】:

    【解决方案2】:

    为什么不行

    当您执行'the number is ' + offset 时,会读取offset 的值并在那里创建一个新值,即字符串'the number is 20',它被分配给message。新值不“知道”它是如何创建的,因此无法重新计算自身。这根本不是 JavaScript 的工作原理。

    我想改变那个变量的值,使初始变量也改变。

    变量无法做到这一点。但是您可以使用带有 getter 的 object 来实现类似的效果:

    var obj = {
      offset: 0,
      get message() {
        return 'the number is ' + this.offset;
      },
    };
    
    console.log(obj.message);
    obj.offset += 20;
    console.log(obj.message);

    (注意:getter 不是必需的,您也可以创建一个普通的方法/函数并将其称为obj.message()

    【讨论】:

      【解决方案3】:

      它只是一个简单的赋值,当程序流到达它时,将"the number is" 连接到 偏移值 并继续下一行到程序末尾。

      这是 Javascript 的本质,原始类型(数字、字符串等)是按值传递的。所以offset 中的更改不会反映在message 中。

      变量不“持有”对象,它持有一个引用。您可以将该引用分配给另一个变量,现在两者都引用同一个对象。它总是按值传递(即使该值是引用......)。 没有办法改变作为参数传递的变量所持有的值,如果 JS 支持通过引用传递,这将是可能的。From Here

      为了有一个始终依赖的消息值,你可以将它定义为一个函数:

      var offset = 0;
      var message = function(){
        return('the number is ' + offset);
      }
      
      console.log(message());   //this says 'the number is 0'
      
      offset +=20;             //offset is changed to 20
      
      console.log(message());  //this says 'the number is 20'

      【讨论】:

      • “原始类型(数字、字符串等)是按值传递的。” 请注意此处的术语。 “按值传递”和“按引用传递”通常描述 变量 (/parameters) 之间的关系。变量持有的值的实际“类型”是无关紧要的。您可能会想到值类型(原始)和引用类型(对象),但这与“按值传递”无关。请参阅en.wikipedia.org/wiki/Evaluation_strategy。不过,引用是正确的。
      • 同意,答案并不完全正确。这与数据类型无关。所有变量都受值约束。对于对象,值只是 引用。与变量绑定相关的对象和基元之间没有固有的区别。
      【解决方案4】:

      在这两种情况下都会显示0,因为在您设置它时,offset 的值是 0,这就是 message 变量将保持的信息,直到您更改它价值。

      var offset = 0;
      var message = 'the number is ' + offset;
      console.log(message);  
      offset += 20;             
      console.log(message);

      您必须将offset 变量重新分配(刷新)到message 变量才能使更改可见。

      var offset = 0;
      var message = 'the number is ' + offset;
      console.log(message);  
      offset += 20;  
      message = 'the number is ' + offset;
      console.log(message);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-12
        • 2015-05-24
        • 2020-05-24
        • 1970-01-01
        • 1970-01-01
        • 2019-07-31
        • 2011-11-14
        • 1970-01-01
        相关资源
        最近更新 更多