从对象(Date对象)解构函数

时间:2019-01-30 19:13:35

标签: javascript date methods this destructuring

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

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可能?如果可能的话,如何实现?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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())