【面试题】使任何数组都可以调用 array.last() 方法,这个方法将返回数组最后一个元素

前言

请你编写一段代码实现一个数组方法,使任何数组都可以调用 array.last() 方法,这个方法将返回数组最后一个元素。如果数组中没有元素,则返回 -1 。

示例 1 :

  • 输入:nums = [null, {}, 3]
  • 输出:3
  • 解释:调用 nums.last() 后返回最后一个元素: 3。

示例 2 :

  • 输入:nums = []
  • 输出:-1
  • 解释:因为此数组没有元素,所以应该返回 -1。

方法 1:扩展数组原型以包含 .last() 方法

概述

根据问题陈述,需要增强所有数组,使其具有返回数组最后一个元素的方法 .last()。如果数组中没有元素,则应返回-1。

为此,可以向数组原型添加一个新方法。这个新方法可以通过访问这个 this[this.length-1] 简单地返回数组的最后一个元素。

添加到数组原型的方法中的 this 关键字引用调用该方法的数组。

注意:扩展原生原型是 JavaScript 的一个强大功能,但应该谨慎使用。如果其他代码(或更高版本的 JavaScript)添加了同名的方法,则可能会导致冲突。在扩展本机原型时始终保持谨慎

算法步骤

  1. 在名为 last 的数组原型上定义一个新方法。
  2. 在这个方法中,检查数组是否为空。如果是,返回 -1。
  3. 如果数组不为空,则返回数组的最后一个元素。最后一个元素可以通过以下方式访问:this[this.length - 1]

1. 常规if检查

Array.prototype.last = function() {
  if (this.length === 0) {
    return -1;
  }

  return this[this.length - 1];
}

2. 三元运算符

Array.prototype.last = function() {
  return this.length === 0 ? -1 : this[this.length - 1];
}

3. 空值合并运算符

Array.prototype.last = function() {
  return this[this.length - 1] ?? -1;
}

这种实现方式,使用空合并运算符(??)。如果不为 null 或 undefined,则返回左侧操作数,否则返回右侧操作数。
请注意,此实现假定数组只包含数字。如果数组的最后一个元素为空或未定义,则此方法将返回-1,这可能会掩盖最后一个元素的实际值。它可能不适合包含其他数据类型的数组,在这些数组中,null 或 undefined 是有效且不同的值。始终确保使用适合数组中包含的数据类型的方法。

4. 使用数组 pop() 方法

Array.prototype.last = function() {
  let val = this.pop();
  return val !== undefined ? val : -1;
}

这种实现方式,使用数组 pop() 方法,该方法从数组中移除最后一个元素并返回它。如果数组为空,则 pop() 返回 undefined,我们检查它并将其替换为 -1。需要注意的是,该操作会改变原始数组,这可能并不理想,具体取决于您的用例。

5. 将空值合并运算符与 Array.prototype.at() 方法结合使用

Array.prototype.last = function() {
  return this.at(-1) ?? -1;
}

这种实现方式,使用 ES6 中的 Array.prototype.at() 方法。此方法接受一个整数值,并返回该索引处的元素,允许使用正整数和负整数。负整数从数组末尾开始计数。如果数组为空,则 at(-1) 将是未定义的,因此提供 -1 作为备用。

6. 使用 Array.prototype.slice() 方法

Array.prototype.last = function() {
  return this.length ? this.slice(-1)[0] : -1;
}

这种实现方式,使用 Array.prototype.slice() 方法。此方法提取数组的一部分并返回新数组。通过提供 -1 作为参数来请求最后一个元素。如果数组为空,则 slice(-1)[0] 将为 undefined,因此我们提供 -1 作为备用。需要注意的是,该方法不会改变原始数组,这与前面提到的 pop() 方法不同。

7. 使用默认参数

Array.prototype.last = function() {
  const [lastElement = -1] = this.slice(-1);
  return lastElement;
}

它本质上与 slice(-1)[0] 版本相同,但具有不同的语法。

8. findLast 方法(适用于 ECMAScript 2022 及之后版本)

如果在非 ECMAScript 2022 版本中,可以创建polyfill(模拟旧版本中没有的新方法)。

if (!Array.prototype.findLast) {
    Array.prototype.findLast = function(predicate) {
        for (let i = this.length - 1; i >= 0; i--) {
            if (predicate(this[i], i, this)) {
                return this[i];
            }
        }
        return undefined;
    };
}

实现:

Array.prototype.last = function() {
  return this.findLast(() => true) ?? -1;
}

方法 2:使用 ES6 Getters

概述

在 JavaScript 中,getter 是获取特定属性的值的方法。在这里,我们将为最后一个属性创建一个 getter。

算法

  1. 通过为最后一个属性定义一个 getter来增强数组原型。
  2. getter 函数将返回另一个函数,该函数返回数组的最后一个元素,如果数组为空,则返回 -1。

实现

Object.defineProperty(Array.prototype, 'last', {
  get: function() {
    return () => this.length ? this[this.length - 1] : -1;
  }
})

定义一个 getter 时,实际上是把 last 当作一个属性而不是一个函数。因此,它是通过 array.last 而不是 array.last() 访问的。如果将数组的最后一个元素视为该数组的属性,而不是函数的结果,则这种观点在语义上会更清晰。

你可能感兴趣的:(面试题,JavaScript,javascript,ecmascript,前端)