Skip to content

Latest commit

 

History

History
96 lines (74 loc) · 2.58 KB

实现Date类的继承.md

File metadata and controls

96 lines (74 loc) · 2.58 KB

要调用 Date上方法的实例对象必须通过 Date构造出来,否则不允许调用 Date的方法

由于上述限制,所以想要继承 Date类,就无法使用经典的寄生组合式继承法进行继承。

  • ES5实现1
// 需要考虑polyfill情况
Object.setPrototypeOf = Object.setPrototypeOf ||
function(obj, proto) {
  obj.__proto__ = proto;
  return obj;
};

/**
 * 用了点技巧的继承,实际上返回的是Date对象
 */
function MyDate() {
  // 下面这句话主要是为了能够拿到传入参数,换成下面两种写法也是可以的
  // new(Date.bind(([Date].concat(Array.prototype.slice.call(arguments))).join(',')))
  // new(Date.bind(Date, ...arguments))
  var dateInst = new(Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))))();

  // 更改原型指向,否则无法调用MyDate原型上的方法
  // ES6方案中,这里就是[[prototype]]这个隐式原型对象,在没有标准以前就是__proto__
  Object.setPrototypeOf(dateInst, MyDate.prototype);

  dateInst.abc = 1;

  return dateInst;
}

// 原型重新指回Date,否则根本无法算是继承
Object.setPrototypeOf(MyDate.prototype, Date.prototype);

MyDate.prototype.getTest = function getTest() {
  return this.getTime();
};

var date = new MyDate();
var date2 = new Date();

console.log(date instanceof Date);  // => true
console.log(date2 instanceof Date);  // => true
console.log(date.abc)  // => 1
console.log(date2.abc)  // => undefined
console.log(date.getTest());  // => 正常输出调用 getTime()
console.log(date2.getTest());  // => Uncaught TypeError: date2.getTest is not a function
  • ES5实现2
function MyDate() {}
MyDate.prototype.getTest = function() {
  return this.getTime()
}

let d = new Date()
Object.setPrototypeOf(d, MyDate.prototype)
Object.setPrototypeOf(MyDate.prototype, Date.prototype)

console.log(d.getTime()) // 1537532987673
  • ES5实现3
Date.prototype.clone = function() {
  return new Date(this.valueof())
}
var date = new Date('2010')
var cloneDate = date.clone()
console.log(cloneData)  // => Fri Jan 01 2010 08:00:00 GMT+0800 (中国标准时间)
  • ES6实现
class MyDate extends Date {
  constructor() {
    super();
    this.abc = 1;
  }
  getTest() {
    return this.getTime();
  }
}

let date = new MyDate();

// 正常输出,譬如1515638988725
console.log(date.getTest());

可以看到,使用 ES6class关键字,配合 super方法可以很容易实现继承,不过上述写法只限于 ES6,如果使用 Babel等工具对上述代码进行转换,同样不可行