【问题标题】:Factory function: why doesn't status variable change to "OK"?工厂功能:为什么状态变量没有变为“OK”?
【发布时间】:2019-03-10 10:08:09
【问题描述】:

我正在从 javascript 类切换到工厂函数。 除了参数,我还需要内部属性,例如。以下简化示例中的状态。那么,为什么 status 没有设置为 OK,应该如何设置呢?

const Model = (name) => {
    name = "myname";
    let status = "initial";

    const setOK = () => {
        status = "OK";
    }
    return {name, status, setOK}
};

const m = Model();
console.log(m.status); //status is initial
m.setOK();
console.log(m.status);  //expecting OK, but still initial

【问题讨论】:

  • 返回对象中的statuslet status获取初始值,但是改变let status的值并不会改变返回的对象
  • "... 不使用类并使用工厂函数。我只是在寻找完成此任务的“最佳”方法。“ 请参阅我的answer on对象组合
  • 感谢CertainPerformance 和zer00ne,你们都帮了我很多忙,并为我指明了正确的方向。在大重构之前,我将不得不更深入地研究它并首先使用这些概念:-)

标签: javascript function factory


【解决方案1】:

目前,返回的对象永远不会改变:你的

return {name, status, setOK}

返回具有这三个属性的对象,其值与返回对象时的值相同。如果您希望对象更改,请在 Model 内预先定义对象,然后在 setOK 内更改所述对象:

const Model = (name) => {
  name = "myname";
  let status = "initial";
  const setOK = () => {
    obj.status = "OK";
  };
  const obj = { name, status, setOK };
  return obj;
};

const m = Model();
console.log(m.status);
m.setOK();
console.log(m.status);

【讨论】:

  • 感谢您的帮助。所以如果我做对了,我需要在我的工厂函数中构建一个对象并返回这个对象。这是使用 => 函数创建工厂函数的方式吗?
  • 不在这里 - 在此代码中,使用箭头函数与标准 function() { 没有任何区别,因为从未检查或分配调用上下文 (this)。
  • 我明白了。在我开始重构我的代码之前,有没有更好的方法来做到这一点?我的意思是我读过的未来明智的,不使用类和使用工厂函数。我只是在寻找完成这项工作的“最佳”方式。
  • 类绝对没有错——事实上,如果可能的话,我更喜欢它们。它们工作得很好,而且通常更容易阅读:jsfiddle.net/7smhp9ru
  • 那是真的,我的程序在一小部分类中运行良好,我开始重构......但后来我读了这个link,之后我开始阅读有关工厂函数的内容。 . 然后它变得有点复杂:-)
【解决方案2】:

Object Composition

使用Object.assign() 合并对象或“继承” 方法,而不使用classprototypeComposition over inheritance


演示

demo中评论的详细信息

/* 
Object monitor has setOK() method. 
Note the parenthesis wrapped around the curly braces ensures
that the object literal will be invoked as a expression.
The props object from Model is passed to monitor object
*/
const monitor = props => ({
  setOK: () => {
    props.status = "OK";
  }
});

/* Factory Function 
Note the object literal props. props will be passed through
Object.assign() method in order to inherit the method setOK() from the monitor object.
*/
const Model = name => {
  let props = {
    name: name,
    status: "initial"
  };
  return Object.assign(props, monitor(props));
};

// Create object m with the name: "checkStatus"
const m = Model("checkStatus");
// Verify object m is named "checkStatus"
console.log('name: '+m.name);
// Check status
console.log('status: '+m.status);
// Invoke .setOK() method
m.setOK();
// Check status
console.log('status: '+m.status);

【讨论】:

  • 嗨 zer00ne,谢谢。在可重用性方面似乎更灵活一些。我想我需要让它沉入其中。到目前为止,我只是使用了“普通”函数,在我的真实代码中,除了状态之外,我还需要很多其他内部属性,所以我将看看如何获​​取它完成。
  • 嗨@WU7 第一个链接是一篇非常好的文章,它启发了我——我也只使用了函数(虽然这没有错)。一旦掌握了对象组合,我也开始更好地理解 OOP 概念,如经典继承和原型。编码愉快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 2021-11-20
相关资源
最近更新 更多