Typescript中的继承示例

Typescript代码示例

Typescript

typescript 复制代码
class Animal {
    constructor(public name: string) { }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 45) {
        console.log("Galloping...");
        super.move(distanceInMeters);
    }
}

let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

对应的JavaScript编译结果

JavaScript

javascript 复制代码
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        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);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Animal = /** @class */ (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 0; }
        console.log(this.name + " moved " + distanceInMeters + "m.");
    };
    return Animal;
}());
var Snake = /** @class */ (function (_super) {
    __extends(Snake, _super);
    function Snake(name) {
        return _super.call(this, name) || this;
    }
    Snake.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 5; }
        console.log("Slithering...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Snake;
}(Animal));
var Horse = /** @class */ (function (_super) {
    __extends(Horse, _super);
    function Horse(name) {
        return _super.call(this, name) || this;
    }
    Horse.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 45; }
        console.log("Galloping...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Horse;
}(Animal));
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);

__extends方法解析

1. 整体结构

这是一个立即执行的函数表达式(IIFE),返回一个函数并赋值给 __extends 变量。它用于处理类继承关系。

2. extendStatics 函数

这个内部函数负责复制静态属性和方法:

javascript

css 复制代码
var extendStatics = function (d, b) {
    extendStatics = Object.setPrototypeOf ||  // 优先使用现代方法
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||  // 兼容老式__proto__赋值
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };  // 最后回退到逐个属性复制
    return extendStatics(d, b);
}
  • 它会根据环境选择最优的静态属性继承方式
  • 优先级:Object.setPrototypeOf > __proto__赋值 > 逐个属性复制

3. 返回的继承函数

javascript

javascript 复制代码
return function (d, b) {
    extendStatics(d, b);  // 继承静态成员
    
    function __() { this.constructor = d; }  // 中间构造函数
    
    d.prototype = b === null 
        ? Object.create(b)  // 处理继承null的情况
        : (__.prototype = b.prototype, new __());  // 常规继承
};
  • d 是子类,b 是父类
  • 创建中间构造函数 __ 来维护原型链
  • 最后一行是关键:
    • __ 的原型指向父类的原型
    • 然后创建 __ 的实例作为子类的原型
    • 这样既继承了父类的方法,又能保证 constructor 正确指向子类

4. 兼容性处理

这段代码考虑了多种环境:

  1. 现代浏览器:使用 Object.setPrototypeOf
  2. 较老浏览器:使用 __proto__
  3. 最差情况:逐个复制属性

这种实现方式确保了在大多数 JavaScript 环境中都能正确实现类继承机制。

相关推荐
掰头战士7 分钟前
多重影分身!恨不得把一个agent掰成两个? 还真能干!
typescript·llm·agent
八荒启·交互动画30 分钟前
# Web特效020—让 Web 特效真正动起来:时间循环应该怎么接
前端·webgl·网页特效·八荒启-交互动画·八荒启
动恰客流统计31 分钟前
线下零售数字化浪潮下,客流统计的3个核心发展趋势
大数据·前端·人工智能
用户938515635071 小时前
从小米前端面试题,彻底搞懂闭包、作用域链与 useState 惰性初始化
前端·面试
粥里有勺糖2 小时前
视野修炼第133期 | Native 回春了?
前端·github·agent
aichitang20242 小时前
前端小skill
前端·人工智能·算法·ai·前端框架
前端·柱子3 小时前
q-floodfill白边锯齿?一招搞定抗锯齿边缘问题
前端·html·canva可画
葡萄城技术团队3 小时前
SpreadJS V19.2新特性揭秘:功能区键盘提示
前端
计算机魔术师3 小时前
AI 幻觉导致的错误情报险些引发美军拦截中国船只
前端
万物智能3 小时前
SARADC模数转换—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端