【问题标题】:Is there a way to chain Javascript functions without creating a new object?有没有办法在不创建新对象的情况下链接 Javascript 函数?
【发布时间】:2020-05-31 12:08:51
【问题描述】:

假设我们有一个 Button 元素

const ourButton = document.getElementById("#theButton");

我们想要一个流畅的 API 来改变这个按钮的样式而不创建一个新的对象,所以像这样链接一个函数:

style(ourButton).property("padding").value("32px");

这可能吗?我似乎无法弄清楚如何创建这种行为。我尝试通过创建如下构造函数来“以传统方式”构建 Fluent API:

var FStyle = function(node) {
  this.node = node;
}

FStyle.prototype.property = function(property) {
  this.property = property;
  return this;
}

FStyle.prototype.value = function(value) {
  this.value = value;
  this.node.style[this.property] = this.value;
  return this;
}

并通过构造一个新对象来使用它:

const ourButtonStyle = new FStyle(ourButton);
ourButtonStyle.property("padding").value("64px");

一次有效。如果我想添加一种新样式,我必须创建一个全新的对象。这是为什么呢?

TL;DR:出于学习目的,我正在尝试链接功能,但对它的理解不够充分,无法理解上述行为。在普通函数中返回 this 以将其他函数链接到它也不会完成这项工作。最后我想将一个函数的结果“管道”到另一个函数

【问题讨论】:

  • 为什么只能运行一次?看起来ourButtonStyle.property("foo").value("bar").property("baz").value("qux") 应该可以正常工作。 (除此之外:ourButtonStyle.property("foo").property("bar").value("baz") 之类的东西也是可能的,但令人困惑,这表明这可能不是最好的 API 设计。)
  • 只是说:创建新对象绝对没有错!
  • @Thomas 执行一次链后出现错误:“未捕获的 TypeError:ourButtonStyle.property 不是函数”。 MRA:codepen.io/melvinidema/pen/wvKVNba?editors=0011
  • @Bergi 我同意,但我为什么要这样做。 (而不仅仅是调用:node.style.property = value - 这更简约)是练习方法链接和创建 Fluent API。每次你想改变风格时创建一个新对象在 IMO 中并不实用。
  • @MelvinIdema 在理想的 fluent API 中,所有对象都是不可变的,每个方法调用都会返回一个新实例。 (我并不是说您应该多次调用new FStyle(…),我只是说您可以轻松地使用链中的多个对象)。

标签: javascript ecmascript-6 fluent chaining


【解决方案1】:

虽然不容易看出,但这里的问题是命名!

您正在创建一个名为 property 的原型函数,然后基本上用从函​​数调用中获得的值覆盖该函数。检查下面代码中的 cmets。

FStyle.prototype.property = function(property) {
  // at this point "ourButtonStyle.property" is a function
  this.property = property;
  // here "ourButtonStyle.property" is a string 
  return this;
}

一个简单的解决方法是用稍微不同的东西重命名它们

var FStyle = function(node) {
  this.node = node;
}

FStyle.prototype.property = function(prop) {
  this.prop = prop;
  return this;
}

FStyle.prototype.value = function(val) {
  this.val = val;
  this.node.style[this.prop] = this.val;
  return this;
}

【讨论】:

  • 这是一个巨大的“尤里卡”时刻。你是绝对正确的!奇怪的是,这完全超出了我的想象。可悲且奇怪的是,它似乎并没有解决问题......我仍然得到 typeError。但是检查 ourButtonStyle.property 的类型,它说:函数。即使在执行一次之后。控制台逐字记录:Typeof ourButtonStyle.property: function,紧接着:typeError ourButtonStyle.property is not a function
  • Facepalm,我没看到你也改变了值。太感谢了!我想是时候休息了哈哈。解决了!您是否建议在不创建新对象的情况下链接函数?比如:changeStyle(node).property("border-color").value("red");
  • @MelvinIdema 很高兴,你成功了!至于您关于在不直接创建新对象的情况下进行链接的问题,也许这样的事情可以帮助您:function changeStyle(node){ return new FStyle(node)}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 2021-08-18
  • 2016-07-07
  • 2021-10-15
  • 2012-07-25
  • 2011-01-03
  • 1970-01-01
相关资源
最近更新 更多