为什么布尔对象属性不会更新?

Why won't a boolean object property update?

提问人:sspboyd 提问时间:11/4/2022 更新时间:11/4/2022 访问量:164

问:

我有一个对象数组。每个对象都有一个方法,该方法更新名为“found”的同一对象中的布尔属性。

当我调用该函数时,该属性不会更新。我不知道为什么。

我以为“找到”属性是可以访问的,但事实并非如此??

我在这里创建了问题的最小版本:https://codepen.io/sspboyd/pen/XWYKMrv?editors=0011

const gen_s = function () { // generate and return the object
  let found = false;

  const change_found = function () {
    found = true;
  };

  const update = function () {
    change_found();
  };

  return {
    change_found,
    found,
    update
  };
};

const s_arr = []; // initialize an array

s_arr.push(gen_s()); // add a new s object to the array

console.log(s_arr[0].found); // returns 'false'

s_arr.forEach((s) => {
  s.update();
});

console.log(s_arr[0].found);

JavaScript 作用域 关闭 工厂

评论

0赞 katniss 11/4/2022
当您返回对象时,是当前闭包中内容的“快照”(即 ) - 因此它不会更改。foundfoundfalse

答:

1赞 Andrew Parks 11/4/2022 #1

当函数更改 的值时,它会更改变量指向的值,但函数返回的对象仍指向旧值。change_foundfoundlet foundgen_s

您可以使用“holder”模式修复代码,如下所示:

const gen_s = function () { // generate and return the object
  let foundHolder = {value: false};

  const change_found = function () {
    foundHolder.value = true;
  };

  const update = function () {
    change_found();
  };

  return {
    change_found,
    foundHolder,
    update
  };
};

const s_arr = []; // initialize an array

s_arr.push(gen_s()); // add a new s object to the array

console.log(s_arr[0].foundHolder.value); // returns 'false'

s_arr.forEach((s) => {
  s.update();
});

console.log(s_arr[0].foundHolder.value);

或者更好的是,使用一个类:

class S {
  constructor() { this.found = false; }
  change_found() { this.found = true; }
  update() { this.change_found(); }
}
const s_arr = [];
s_arr.push(new S());
console.log(s_arr[0].found);

s_arr.forEach(s => s.update());
console.log(s_arr[0].found);

评论

0赞 sspboyd 11/5/2022
非常感谢您@andrew公园的帮助回复!我假设这里的相关区别在于更改分配给生成对象的变量与创建对象持有者并更改其“值”之间的相关区别是否正确?我想了解更多关于为什么 Javascript 这样工作的信息。有没有我可以查找此类变量声明/引用的术语?
1赞 Andrew Parks 11/5/2022
@sspboyd 搜索“javascript scope”。您的问题与将变量作为参数传递给函数时发生的情况基本相同。在该函数中,如果将参数设置为不同的值,则将设置自己的局部变量以引用不同的值。调用函数的代码将具有自己的变量,该变量仍引用原始值。