You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Typescript类方法作为sort回调丢失上下文 如何实现函数复用?

问题原因

你遇到的报错本质是类方法作为独立回调传入Array.sort时,丢失了类实例的this绑定。Array.sort执行回调时默认使用全局上下文(严格模式下为undefined),因此objectpinnedSortSample内部的this指向undefined,自然无法读取pinnedSortSample方法。

解决方案

下面提供几种可落地的实现方案,均可保留this上下文、实现排序逻辑复用:

方案1:调用时用箭头函数包裹(最灵活,无需修改类定义)

传入sort时用箭头函数包裹类方法,箭头函数会继承当前作用域的this(也就是类实例),无需修改原有方法定义:

interface A {
   num: number
}

class Example {
  sortTwoLists():boolean {
    // 用箭头函数包裹,绑定this
    let sortList1 = [4,5,3,1,2].sort((a, b) => this.pinnedSortSample(a, b));
    let sortList2 = [{num:4} as A, {num:5} as A, {num:3} as A, {num:1} as A, {num:2} as A]
      .sort((a, b) => this.objectpinnedSortSample(a, b))
    let numsOnly = sortList2.map((x) => x.num)
    return numsOnly.length === sortList1.length && numsOnly.every((value, index) => value === sortList1[index])
  }

  pinnedSortSample(item1:number, item2:number) {
    let pins = [3,6]
    if (pins.includes(item1) && pins.includes(item2)) {
      return pins.indexOf(item1) - pins.indexOf(item2)
    } else if (pins.includes(item1)) {
      return -1;
    } else if (pins.includes(item2)) {
      return 1;
    } else {
      if (item1 < item2) {return -1}
      if (item1 > item2) {return 1}
      return 0;
    }
  }

  objectpinnedSortSample(item1: A, item2: A) {
    return this.pinnedSortSample(item1.num, item2.num);
  }
}

const x = new Example().sortTwoLists();
console.log(x); // 输出 true

方案2:将类方法定义为箭头函数属性(永久绑定实例this)

直接把类方法定义为箭头函数属性,该方法的this会永久绑定到类实例,后续直接传入sort即可:

class Example {
  sortTwoLists():boolean {
    // 直接传方法即可,无需额外处理
    let sortList1 = [4,5,3,1,2].sort(this.pinnedSortSample);
    let sortList2 = [{num:4} as A, {num:5} as A, {num:3} as A, {num:1} as A, {num:2} as A]
      .sort(this.objectpinnedSortSample)
    // 其余逻辑不变
  }

  // 定义为箭头函数属性,自动绑定this到实例
  pinnedSortSample = (item1:number, item2:number) => {
    // 原有逻辑不变
  }

  objectpinnedSortSample = (item1: A, item2: A) => {
    return this.pinnedSortSample(item1.num, item2.num);
  }
}

方案3:高阶函数实现通用适配(进一步提升复用性)

如果需要适配更多类型的对象排序,可以封装通用的高阶排序函数,无需为每种对象单独写适配方法:

class Example {
  // 基础排序逻辑不变
  private pinnedSortSample(item1:number, item2:number) {
    let pins = [3,6]
    if (pins.includes(item1) && pins.includes(item2)) {
      return pins.indexOf(item1) - pins.indexOf(item2)
    } else if (pins.includes(item1)) {
      return -1;
    } else if (pins.includes(item2)) {
      return 1;
    } else {
      return item1 - item2;
    }
  }

  // 通用排序器生成方法,传入取值函数即可适配任意类型
  createPinnedSorter<T>(getValue: (item: T) => number): (a: T, b: T) => number {
    return (a, b) => this.pinnedSortSample(getValue(a), getValue(b))
  }

  sortTwoLists():boolean {
    // 数字数组直接用基础方法
    let sortList1 = [4,5,3,1,2].sort((a,b) => this.pinnedSortSample(a,b));
    // 对象数组传入取值函数生成专属排序器
    const sorterForA = this.createPinnedSorter<A>(item => item.num)
    let sortList2 = [{num:4} as A, {num:5} as A, {num:3} as A, {num:1} as A, {num:2} as A]
      .sort(sorterForA)
    let numsOnly = sortList2.map((x) => x.num)
    return numsOnly.length === sortList1.length && numsOnly.every((value, index) => value === sortList1[index])
  }
}

内容的提问来源于stack exchange,提问作者Ryan Deschamps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 03:18:03