【问题标题】:Destructuring a function from object ( Date Object )从对象(日期对象)解构函数
【发布时间】:2019-01-30 19:13:34
【问题描述】:

如果我想破坏一个对象,我会这样做:

const obj = {
  a: 'a',
  fn: () => 'some function'
}

// const fn = obj.fn;
// OR

const {
  a,
  fn
} = obj;

console.log( fn() );

这不适用于Date 对象:

未捕获的 TypeError:这不是 Date 对象。

const date = new Date();

const day = date.getDate();
console.log(day); // works

const {
  getDate
} = date;
console.log( getDate() ); // doesn't work

为什么使用第一个 Object 而不是 Date ?如果可能,人们将如何实现这一目标。

【问题讨论】:

  • 解构只是name = obj.name 的简写,在这两种情况下,您都会丢失objthis 上下文。因此,这不仅限于日期,任何 obj 都会丢失 this
  • 这两个日期示例不等价。你的解构是这样的:const getDate = date.getDate; getDate() 如果没有date 对象是this stackoverflow.com/a/2025839,这毫无意义
  • 来自ECMA-262设 t 为 LocalTime(?thisTimeValue(this value))。。调用解构后的getDate时,this是什么?您可以使用getDate.call(date) 修复它。 ;-)
  • @RobG 您评论中的问题有助于理解正在发生的事情,现在很有意义,当我解构函数时,我松散了 this,谢谢 :)

标签: javascript date methods this destructuring


【解决方案1】:

这可能不值得,但您可以编写一个函数来帮助您从对象中解构方法。这里bindMethods 使用帮助器allKeys 执行此操作,它从对象的整个原型链中收集键,而后者又依赖于walkPrototypeChain。如果需要,它们显然可以折叠成一个函数。

const walkPrototypeChain = (process, init, finish) => (obj) => {
  let currObj = obj, currRes = init();
  do {
    currRes = process(currRes, currObj)
  } while (currObj = Object.getPrototypeOf(currObj))
  return finish(currRes)
}

const allKeys = walkPrototypeChain(
  (set, obj) => {Object.getOwnPropertyNames(obj).forEach(k => set.add(k)); return set},
  () => new Set(),
  s => [...s]
)

const bindMethods = (obj) => allKeys(obj).reduce(
  (o, n) => typeof obj[n] == 'function' ? ({...o, [n]: obj[n].bind(obj)}) : o, 
  {}
)

const date = new Date()
const {getDate, getFullYear} = bindMethods(date) // or any other date function

console.log(getDate())
console.log(getFullYear())

【讨论】:

    【解决方案2】:

    因为 this 它不是 Date 对象。当您在没有适当上下文的情况下调用getDate()(即date.getDate())时,您将在window(或严格模式下的null)的上下文中调用它。 windownull 都不是 Date 对象,因此函数失败。

    试试const getDate = date.getDate.bind(date);

    演示:

    const test = { fn : function() { return this.constructor; } };
    
    const normal = test.fn();
    console.log(normal); // object
    
    const {fn} = test;
    console.log( fn() ); // window
    
    const bound = test.fn.bind(test);
    console.log( bound() ); // object

    【讨论】:

    • @ABOS 所以...?这个问题与析构函数没有任何关系,它是在询问解构。
    • 标题说destruct,所以我以为OP想这样做。
    • @ABOS:这就是这个答案的重点。此处的解构为您提供了一个裸函数引用,而不是绑定方法。如果你能找到解构的方法来做到这一点,我们都在听。
    • @ScottSauyet,我认为困难在于如何使用 destruct 编写“单行”,如果在像 f = date.getDate, f() 这样的简单分配中进行,我很高兴它已经在 SO 上进行了很多讨论之前...
    • @ABOS:我没有关注。 f = date.getDate, f() 与问题中描述的问题完全相同。
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多