百分点【chat GTP】

介绍ES6的功能

  • let和const:增加了块级作用域变量
  • 箭头函数:使用箭头 => 定义函数,方便简洁
  • 模板字符串:使用反引号 `` 和 ${} 实现字符串插值
  • 解构赋值:从对象或数组中提取值,赋给不同的变量
  • 参数默认值:设置函数参数的默认值,未传入时使用默认值
  • 扩展运算符:快速遍历数组,合并数组等,用…表示
  • Promise:用同步的方式写异步代码,避免回调地狱
  • class类: 实现面向对象编程
  • 模块化:import和export模块化语法
  • 遍历数据结构的新方法:for…of, Array.from(), Map/Set等
  • 异步函数async/await: 同步方式编写异步代码
  • 新数据结构Map/Set等

let、const以及var的区别

  • 作用域不同
    • var 声明的变量只有全局作用域和函数作用域
    • let 和 const 声明的变量有块级作用域
  • 变量提升不同
    • var 声明的变量会变量提升到作用域顶部
    • let 和 const 不会变量提升
  • 暂时性死区
    • let 和 const 声明的变量会有一个暂时性死区,访问会报错
    • var 不会有这个问题
  • 重复声明
    • var 可以无限次重复声明同一个变量
    • let 和 const 不允许在同一作用域内重复声明
  • 是否常量
    • const 声明的变量是一个常量,初始化后不能修改
    • var 和 let 声明的变量值可以修改
      总结:

在全局作用域中优先使用 const,块级作用域优先考虑 let
需要修改的变量用 let 声明
全局常量使用 const 声明
避免使用 var

浅拷⻉和深拷⻉的区别

  • 拷贝层级不同

    • 浅拷贝只拷贝一层对象的属性, deeper level 的对象还是共享的。
    • 深拷贝将对象完全拷贝一份出来,每一级别的数据都会拷贝。
  • 共享引用情况不同

    • 浅拷贝会共享子对象的引用,源对象和拷贝对象指向同一个子对象。
    • 深拷贝不会共享任何引用,源对象和拷贝对象中的子对象都是完全独立的。
  • 修改源对象是否会影响拷贝对象

    • 浅拷贝会被影响,因为子对象是共享的。
    • 深拷贝不会被影响,因为所有层级数据都是完全独立的。
  • 实现方式不同

    • 浅拷贝可以使用 Object.assign() 或展开语法 {…obj} 实现。
    • 深拷贝可以通过递归、JSON.parse(JSON.stringify())等方式实现。

所以在需要完全独立的对象拷贝时要用深拷贝,而如果只需要一层数据,可以用浅拷贝来优化性能。需要根据具体需求选择合适的拷贝类型。

介绍箭头函数的this

箭头函数中的this与普通函数不同,它的this是词法作用域中的this,由上下文确定。

主要的区别有:

  • 普通函数的this是调用的时候确定的,箭头函数的this是在定义时绑定的,后面无法修改。
  • 普通函数作为对象的方法调用,this指向对象,箭头函数作为方法调用,this还是指向上下文。
  • 普通函数调用call/apply/bind可以修改this,箭头函数不可以。
  • 普通函数的this在严格模式和非严格模式下有区别,箭头函数this在两种模式下都是一样的。
  • 普通函数的this在事件回调中指向触发事件的元素,箭头函数的this在回调中继承外层this。
let obj = {
  name: 'Jack',
  normal() {
    console.log(this.name)  
  },
  arrow: () => {
    console.log(this.name) 
  }
}

obj.normal() // Jack
obj.arrow() // undefined

所以箭头函数可以更好地保持this绑定,避免由this引起的一些问题。但作为对象方法时要注意this不再绑定对象,需要根据情况而定是否要使用。

介绍Promise和then

Promise和then都是用于异步编程
Promise是一种异步编程的解决方案,有以下几个特点:

  • 对象的状态不受外界影响,Promise对象代表一个异步操作,一旦状态改变,就不会再变化。
    有三种状态:Pending(进行中)、Resolved(已完成)和 Rejected(已失败)。
  • Promise对象用then方法分别指定Resolved和Reject状态的回调函数。then方法返回的是一个新的Promise实例。

then方法是Promise最基础的方法,作用是为Promise注册回调

  • then方法接收两个参数,onFulfilled和onRejected,分别对应Promise成功或失败的回调。
  • then方法返回一个新的Promise,可以链式调用。后面then根据前面then的返回值来确定自身的状态。
  • 如果then中的回调函数返回的是一个Promise,那后面的then会等待它的状态改变;如果返回的是一个普通值,那下一个then会在下一轮事件循环中执行。

示例代码:

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success') 
  }, 1000)
})

p.then(result => {
  console.log(result) // 'success'
  return new Promise((resolve, reject) => { 
    // do something
  })  
}).then(result2 => {
  console.log(result2) 
})

介绍快速排序

快速排序是一种非常高效的排序算法,利用了分治策略,可以实现在O(nlogn)的时间复杂度内对数组进行排序。

其基本思想是:

  • 选择一个基准值(pivot),通常选择数组的第一个元素。
  • 对数组进行分割,将小于基准值的元素放到基准值的左边,大于基准值的元素放到基准值的右边。称为分区(partition)操作。
  • 对左右两个分区递归进行快速排序。

代码实现:

function quickSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }

  let pivot = arr[0]; 
  let left = [];
  let right = [];

  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }

  return quickSort(left).concat(pivot, quickSort(right));
}

快速排序通过设定基准值分割数组,可以很好地利用分治策略将计算复杂度降低到O(nlogn),是最快的排序算法之一。但它是不稳定的排序算法。

算法:前K个最⼤的元素

对一个无序数组寻找前K个最大的元素,可以使用如下算法:

建立一个大小为K的大根堆(最大堆)

遍历数组,依次将每个元素和堆顶元素(当前堆中最大值)比较:

如果大于堆顶,删除堆顶,将该元素插入堆中

如果小于等于堆顶,不做处理

遍历完成后,堆中剩余的K个元素就是数组中前K大的元素

// 考虑时间复杂度:快速选择算法,平均时间复杂度为O(n)
// 快速选择算法是基于快速排序的分治方法。它将数组分为两部分
// 一部分包含比选定的枢纽元素小的所有元素
// 另一部分包含比枢纽元素大的所有元素。
function partition(nums, left, right) {
    let pivot = nums[Math.floor((right + left) / 2)], i = left, j = right;
    while (i <= j) {
        while (nums[i] > pivot) i++;
        while (nums[j] < pivot) j--;
        if (i <= j) {
            [nums[i], nums[j]] = [nums[j], nums[i]];
            i++;
            j--;
        }
    }
    return i;
}

function quickSelect(nums, left, right, k) {
    if (nums.length > 1) {
        let index = partition(nums, left, right);
        if (left < index - 1 && k <= index) {
            return quickSelect(nums, left, index - 1, k);
        }
        if (index < right && k >= index) {
            return quickSelect(nums, index, right, k);
        }
    }
    return nums.slice(0, k);
}

function findKthLargest(nums, k) {
    return quickSelect(nums, 0, nums.length - 1, k);
}

// 示例
const nums = [3, 2, 1, 5, 6, 4];
const k = 2;
console.log(findKthLargest(nums, k));
// 数据量大的话不可行, O(nlogn)
function findKthLargest(nums, k) {
    // 对数组进行降序排序
    nums.sort((a, b) => b - a);
    // 选取前K个元素
    return nums.slice(0, k);
}

// 示例
const nums = [3, 2, 1, 5, 6, 4];
const k = 2;
console.log(findKthLargest(nums, k));
  • 29
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值