TypeScript与Date类型

js的继承方式 

/**
 * 经典的js寄生组合式继承
 */
function MyDate() {
    Date.apply(this, arguments);
    this.abc = 1;
}

function inherits(subClass, superClass) {
    function Inner() {}
    
    Inner.prototype = superClass.prototype;
    subClass.prototype = new Inner();
    subClass.prototype.constructor = subClass;
}

inherits(MyDate, Date);

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

let date = new MyDate();

console.log(date.getTest());

Date作为构造函数来实例化

new Date();

new Date(value);

new Date(dateString);

new Date(year,month,day,hours,minutes,seconds,milliseconds);

ES5黑魔法

// 需要考虑polyfill情况
Object.setPrototypeOf = Object.setPrototypeOf ||
function(obj, proto) {
    obj.__proto__ = proto;

    return obj;
};

/**
 * 实际上返回的是Date对象
 */
function MyDate() {
    // bind属于Function.prototype,接收的参数是:object, param1, params2...
    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();
};

let date = new MyDate();

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

shim:是一个库,它将一个新的API引入到一个旧的环境中,而且仅靠旧环境中已有的手段实现

polyfill:就是一个用在浏览器API上的shim,主要抚平不同浏览器之间对js实现的差异

先检查当前浏览器是否支持某个API,如果不支持的话就加载对应的polyfill.然后新旧浏览器就都可以使用这个API了

 prototype 属性:向对象添加属性

ES6大法

class MyDate extends Date {
    constructor() {
        super();
        this.abc = 1;
    }
    getTest() {
        return this.getTime();
    }
}
let date = new MyDate();

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

ES6写法,然后Babel打包(无法正常调用的)

因为转译后的ES5源码中,仍然是通过MyDate来构造
MyDate的构造中又无法修改属于Date内部的[[Class]]之类的私有标志,
因此构造出的对象仍然不允许调用Date方法(调用时,被引擎底层代码识别为[[Class]]标志不符合,不允许调用,抛出错误)

以上的方法的差别:

  1. MyDate们的__proto__指向不一样
  2. Object.prototype.toString.call的输出不一样
  3. 对象本质不一样,可以正常调用的1, 3都是Date构造出的,而其它的则是MyDate构造出的

普通对象是没有prototype属性的,只有隐藏属性__proto__,函数对象则两者兼有

所有函数对象的原型对象都继承自原始对象,即fn.prototype.__proto__为原始对象,Object函数,他的原型对象就是原始对象,即Object.prototype。

什么是原型链回溯?

用 new方法初始化函数得到新对象的__proto__属性指向原型对象

function f(){};
var a = new f();

a.__proto__=>f.prototype.__proto__=>Object.prototype=>null

把有__proto__串起来的直到Object.prototype.__proto__为null的链叫做原型链。原型链实际上就是js中数据继承的继承链。

猜你喜欢

转载自blog.csdn.net/xuxuan1997/article/details/82020176