ES5 实现 ES6 的 class以及extends

ts中是这样的

class Greeter {
    greeting:string;
    constructor(message:string){
        this.greeting = message;
    }
    greet(){
        console.log("Hello," + this.greeting) 
    }
}

let greeter = new Greeter("world")

class Dog extends Greeter{
    bark() {
        console.log('Woof! Woof!');
    }
}
let dog = new Dog('123')
dog.bark()
dog.greet()

经过tsc test.ts编译成ES5的源码如下,可在对应生成的test.js中查看

var __extends = (this && this.__extends) || (function () {//(this && this.__extends) 有this且已有该函数则不执行后面的函数
    var extendStatics = function (d, b) {
        // 从这个函数的名字就可以看到它是实现静态的属性的继承的
        // 静态属性就是直接绑定在构造函数这个函数对象上的属性
        // function (d, b) { d.__proto__ = b; } 将b对象设置为d对象的原型
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            // 上面这种是兼容老版本浏览器的拷贝继承
        return extendStatics(d, b);
        // {__proto__: []} instanceof Array用来判断浏览器是否支持__proto__属性
        // instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
        // b.prototype 是否存在于d的原型链上
        // {} 空的对象的__proto__属性设为空数组,Array 是[]的原型链上的,所以返回true
    };
    return function (d, b) {
        extendStatics(d, b);//完成静态属性继承
        function __() { this.constructor = d; }//新构造函数,将constructor指向d
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        //如果b 是null 即空对象,则d的prototype 等于Object.create(b),即初始化一个新对象
        //v8上直接{}创建对象比Object.create(null)快
        //否则,采用原型继承,__的prototype 等会 b 的
    };
})();
var Greeter = /** @class */ (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        console.log("Hello," + this.greeting);
    };
    return Greeter;
}());
var greeter = new Greeter("world");
var Dog = /** @class */ (function (_super) {
    __extends(Dog, _super);
    function Dog() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Dog.prototype.bark = function () {
        console.log('Woof! Woof!');
    };
    return Dog;
}(Greeter));
var dog = new Dog('123');
dog.bark();
dog.greet();

总结:理解起来还是挺费劲的,或者说到现在都没完全理解,面向对象、原型链这一块容易忘记,当然,还是理解的不够深刻,不然很难忘掉的。

 

posted @ 2019-02-27 16:36  萝卜爱吃青菜  阅读(1569)  评论(0编辑  收藏  举报