【问题标题】:the "const something = () => ({..." arrow function pattern"const something = () => ({..." 箭头函数模式
【发布时间】:2019-12-18 12:17:06
【问题描述】:

第一种方式:

const logger = () => ({
  log(msg) {
    console.log(msg)
  }
})
class Component {
  constructor() {
    Object.assign(this, logger())
  }
}

第二种方式:

const logger = {
  log(msg) {
    console.log(msg)
  }
}
class Component {
  constructor() {
    Object.assign(this, logger)
  }
}

现在,两者有什么区别?

const obj = new Component()
obj.log('what is the difference?')

我在人们的代码中多次看到第一个模式。这种 IFFE 模式有名称吗?我们在什么场景下使用这种模式?

我将其简化为第二段代码,仍然有效。它似乎工作相同?

【问题讨论】:

  • 除非对象的属性被更改,否则我认为第一个 logger 没有多大意义,只是声明一个对象文字(第二种方式)更容易
  • 我称之为工厂函数
  • 不同之处在于之前的logger 对象将始终是唯一的。如果你在某处修改它可能很重要。
  • 我不确定你在问什么——区别很明显;你是在问为什么你会使用第一个?您可以使用第一种形式来传递一个记录器实例唯一的参数,例如使用它的组件的名称,可以关闭并在所有后续记录消息中使用。

标签: javascript ecmascript-6


【解决方案1】:

第一个示例在每次创建Component 的实例时创建一个新对象(和一个新的log 函数)。

第二个示例每次都重复使用同一个(因此对log 的任何更改都将被共享)。

【讨论】:

  • 不,无论如何它都不会返回相同的对象。由于构造函数使用的不是对象本身,而是Object assign的返回
  • @GuilhermeLúcio — 复制所有属性,包括 log 函数,因此对 log 的任何更改都将被共享。
【解决方案2】:

简而言之,它们将在您的示例中产生相同的结果。那是因为Object.assign 本身将始终返回一个新对象,该对象由您作为参数传递的对象组成。在这两种情况下,您都使用相同的参数调用它,例如您正在调用工厂函数来创建对象,或者如果您正在传递一个简单的对象字面量,因此实例对象上的任何突变都不会影响原始对象。

Object.assign documentation

不同之处在于,在第二种情况下,日志函数在所有实例之间共享,这是因为运行工厂函数每次都会创建一个新对象,因此是一个新函数,但它位于对象内部并引用对象将返回相同的函数。

如果您必须传入参数以基于它们创建动态对象,则第一种方法会很有用。这种方法的危险在于,因为您每次都返回一个新函数,您可能会根据您打算创建的实例数量创建一些性能问题。你可以通过第三个选项来解决这个问题

const log = (msg) => console.log(msg);

const logger = () => ({ log });

class Component {
  constructor() {
    Object.assign(this, logger())
  }
}

【讨论】:

  • 这忽略了你可以做this.log.foo = 'bar',它修改了log函数。这仍然有所作为。
  • 无论采用哪种方法都会发生这种情况,您仍然可以根据需要修改实例对象。这不会修改原始对象,因为 Object.assign 返回了它的副本。在这两种情况下,更改实例上的任何内容都不会触及原始对象
  • Object.assign 仅“复制”{} 包装器。它不会复制log 函数本身!在这种情况下,无论log 函数是否为单例,它确实会有所不同。
猜你喜欢
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多