JavaScript:Array方法如何可链接?这是如何运作的?

时间:2018-04-14 20:19:13

标签: javascript

我一直在学习方法链,以及当方法返回this时,方法如何在每个方法返回对象时变为可链接。

我想知道,Array方法(例如.map.filter.reduce等)如何可链接,当他们不在时。 t返回this

我猜测它与Array.map()实际上是Array.prototype.map()的事实有关,而且从Array.prototype.map()返回的新数组具有所有的Array方法它的原型,允许它是可链接的?

这是如何在幕后工作的? Array.prototype.map()是否会返回一个新数组,并将其原型设置为this

我真正想学习的是,如何编写一个具有方法的对象,例如返回新数组,可以链接,而不返回this?与Array的工作方式相同。

这不起作用,但说明了我的想法。

const generate = {
  method1(arr) {
    console.log(`Param: ${arr}`)
    const result = ['NameA', 'NameB']
    result.prototype = this
    return result
  },
  method2(arr) {
    console.log(`Param: ${arr}`)
    const result = ['NameC', 'NameD']
    result.prototype = this
    return result
  },
}

const example = generate.method1(['Paul']).method2(['Steve'])
console.log(example)
console.log(generate)

另一种尝试

const generate = {
  method1: (arr) => {
    console.log(`Param: ${arr}`)
    const result = ['NameA', 'NameB']
    return Object.assign(result, Object.create(this))
  },
  method2: (arr) => {
    console.log(`Param: ${arr}`)
    const result = ['NameC', 'NameD']
    return Object.assign(result, Object.create(this))
  },
}

const example = generate.method1(['Paul']).method2(['Steve'])
console.log(example)
console.log(generate)

2 个答案:

答案 0 :(得分:3)

数组方法不会返回this,但它们会在转换后使用任何方法返回数组 。你不希望数组方法返回它所调用的原始对象 - 这是没有意义的,因为那时数组方法对任何东西都没用。

您经常希望在另一次转换后链接一个转换,依此类推 - 每个方法使用的特定对象是上一个转换的结果,如果您是,那么这是一个数组在某些情况下使用mapfilter(或reduce)。

因为您可以将Array方法应用于Array对象,并且由于某些Array方法返回Array对象,因此它们是可链接的。

答案 1 :(得分:2)

  

当方法返回this时,该方法变为可链接,因为每个调用都返回对象

返回调用该方法的对象(this)只是使某些东西可链接的众多方法之一。您需要返回的只是任何对象,该对象具有应该在链中可调用的方法。

数组方法mapfilter通过返回新的数组对象来满足该标准 - 当然,这些数组对象同样具有所有数组方法。

  

我猜测从Array.prototype.map()返回的一个新数组在它的原型上有所有的Array方法,允许它是可链接的吗?

  

Array.prototype.map()是否会返回一个新数组,其原型设置为this

不,它返回一个普通的普通数组,其原型设置为Array.prototype。它仅在迭代中使用this

  

如何编写一个包含方法的对象,例如返回新数组,这些方法是可链接的,而不返回this

您不应该返回数组,因为数组既没有method1也没有method2 1 。使用您喜欢的方法返回您自己的对象,其中包含数组结果。

function generate(result) {
  return {
    result,
    method1(arr) {
      console.log(`Method1 called with args ${arr} on object with ${this.result} result`);
      return generate(['NameA', 'NameB']);
    },
    method2(arr) {
      console.log(`Method1 called with args ${arr} on object with ${this.result} result`);
      return generate(['NameC', 'NameD']);
    }
  };
}
const start = generate();
const example = start.method1(['Paul']).method2(['Steve']);
console.log(example);
console.log(start);

1:从技术上讲,您可以将Array子类化,但我不能在不了解您的用例的情况下推荐它。