【问题标题】:Does TypeScript have Extensions like Kotlin?TypeScript 有像 Kotlin 这样的扩展吗?
【发布时间】:2017-04-25 21:11:30
【问题描述】:

Kotlin 有一个名为 Extensions 的功能,它允许您“扩展”任何类型(包括内置类型)而无需实际扩展它。

例如:

function Array<T>.swap(i1: number, i2: number) {
    let tmp = this[i1]
    this[i1] = this[i2]
    this[i2] = tmp
}

let list = [1, 2, 3]
list.swap(0, 2)
console.log(list) // => 3, 2, 1

有趣的是,与基本类型的正常扩展不同,这种方法不会更改数组或其原型链

生成的 JS 代码会是这样的:

function _array_extensions_swap(i1, i2) {
    let tmp = this[i1]
    this[i1] = this[i2]
    this[i2] = tmp
}

let list = [1, 2, 3]
_array_extensions_swap(list, 0, 2)
console.log(list) // => 3, 2, 1

我想知道是否可以在 TypeScript 中做同样的事情,或者是否有计划在未来支持它?

【问题讨论】:

  • 我猜它不在计划中,它似乎与 JavaScript 偏差太大。 TypeScript 应该与 JavaScript 保持相对接近,希望 JavaScript 在未来能够采用它的特性。我认为你的问题应该是:JavaScript 会提供这个吗?

标签: typescript


【解决方案1】:

没有这样的事情,我怀疑它是否会在未来出现,主要原因是没有理由。
在像 kotlin 这样的编译语言中,您不能简单地向现有实例添加新属性,但在 javascript(以及因此与打字稿)中,您可以简单地这样做:

let list = [1, 2, 3] as number[] & { swap(i1: number, i2: number): void };
list.swap = function (i1: number, i2: number) {
    let tmp = this[i1]
    this[i1] = this[i2]
    this[i2] = tmp;
}

list.swap(0, 2);
console.log(list); // [3, 2, 1]

您可以创建工厂函数来扩展现有列表:

function extend<T>(list: T[]): T[] & { swap(i1: number, i2: number): void } {
    (list as T[] & { swap(i1: number, i2: number): void }).swap = function (i1: number, i2: number) {
        let tmp = this[i1]
        this[i1] = this[i2]
        this[i2] = tmp;
    }

    return list as T[] & { swap(i1: number, i2: number): void };
}

let list = extend([1, 2, 3]);
list.swap(0, 2);
console.log(list); // [3, 2, 1]

(code in playground)

【讨论】:

  • 您打算如何实际使用它?您是否要在代码中的每个数组实例中添加 10-20 个这样的函数?也适用于 String.isBlank / isPresent / reverse 等...
  • 检查我修改后的答案。 extend 函数可以添加任何你想要的实例
  • 这是一种众所周知的方法,但缺点很大。它的性能很差(你必须在每个创建的对象上存储一堆函数),并且需要显式扩展每个 Array/String 和其他对象。
  • 如果您想选择该路径,有一个更好的选择 - 引入 class MyArray extend Array 并改用它。无需在每个对象上存储一堆函数,但仍然不方便且冗长。
  • 从您的问题看来,您希望避免扩展或更改原型。有一些方法可以更好地做到这一点,比如声明函数,然后在每个实例中为它们分配一个引用,但关键是在 javascript 中,您可以更改实例并引入新属性,这与 kotlin 不同。
猜你喜欢
  • 2013-07-26
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多