2024/03/1, 每日3题
问题1:实现JS算法题「旋转数组」?
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1, 2, 3, 4, 5, 6, 7] 和 k = 3 输出: [5, 6, 7, 1, 2, 3, 4] 解释: 向右旋转 1 步:
[7, 1, 2, 3, 4, 5, 6] 向右旋转 2 步: [6, 7, 1, 2, 3, 4, 5] 向右旋转 3 步: [5, 6, 7, 1, 2, 3, 4]
示例 2:
输入: [-1, -100, 3, 99] 和 k = 2 输出: [3, 99, -1, -100] 解释: 向右旋转 1 步: [99, -1, -100, 3] 向右旋转 2 步: [3, 99, -1, -100]
const rotate = (nums: number[], k: number): number[] => {
const copyArr = JSON.parse(JSON.stringify(nums));
copyArr.unshift(copyArr.pop());
const i = k - 1;
if (i >= 0) {
return rotate(copyArr, i);
} else {
return nums;
}
}
rotate([1, 2, 3, 4, 5, 6, 7], 3);
问题2:简述Javascript 抽象工厂模式 ?
抽象工厂模式是一种设计模式,它提供了一种方式来创建一系列相关或依赖对象的工厂,而无需指定具体的类。这种模式有助于封装一组具体工厂的创建逻辑,从而使得客户端代码可以与抽象工厂接口交互,而无需关心具体工厂的实现细节。
在 JavaScript 中,抽象工厂模式通常以对象字面量或者构造函数的形式实现。下面是一个简单的示例来说明抽象工厂模式的基本原理:
// 抽象工厂 function ShapeFactory() { this.createCircle = function() { // 创建圆形对象的具体逻辑 return new Circle(); }; this.createSquare = function() { // 创建正方形对象的具体逻辑 return new Square(); }; } // 具体工厂实现 function Circle() { this.draw = function() { console.log('画一个圆形'); }; } function Square() { this.draw = function() { console.log('画一个正方形'); }; } // 使用抽象工厂创建对象 const factory = new ShapeFactory(); const circle = factory.createCircle(); const square = factory.createSquare(); circle.draw(); // 输出: 画一个圆形 square.draw(); // 输出: 画一个正方形
-
在这个示例中,
ShapeFactory充当了抽象工厂的角色,它包含了用于创建不同形状对象的方法。Circle和Square分别是具体工厂的实现,它们实现了相应的创建逻辑。使用抽象工厂模式的主要优点包括:
- 客户端代码与具体工厂的实现解耦,因此可以更容易地进行替换和扩展。
- 通过抽象工厂接口创建对象,可以隐藏具体工厂的实现细节。
然而,抽象工厂模式也有一些缺点,例如增加新的产品类可能需要修改抽象工厂接口,从而引起一系列相关的变更。
总的来说,抽象工厂模式在一些情况下可以提供一种灵活的解决方案,特别是当需要根据不同的条件创建一组相关的对象时。
问题3:简述ES6 的 class 和构造函数的区别 ?
-
语法:
- 在 ES6 中,
class关键字提供了一种更加简洁、面向对象的类定义语法,使得创建和继承类更加直观和易于理解。 - 构造函数是在 ES6 之前就存在的方式,通过
function关键字来定义。虽然构造函数也可以用于创建类似于类的结构,但语法和继承的实现相对更为繁琐。
- 在 ES6 中,
-
继承:
- 使用
class关键字可以更容易地实现类之间的继承关系,通过extends关键字和super关键字来进行继承和调用父类的构造函数。 - 在构造函数中,继承是通过原型链和原型继承来实现的,需要手动设置子类的原型对象并且调用父类构造函数来确保正确的继承行为。
- 下面是一个使用
class关键字和构造函数来定义和继承类的简单示例: -
使用
class关键字: -
class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise.'); } } class Dog extends Animal { speak() { console.log(this.name + ' barks.'); } } const dog = new Dog('Buddy'); dog.speak(); // 输出: Buddy barks.
- 使用构造函数和原型链继承:
function Animal(name) { this.name = name; } Animal.prototype.speak = function() { console.log(this.name + ' makes a noise.'); } function Dog(name) { Animal.call(this, name); } Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; Dog.prototype.speak = function() { console.log(this.name + ' barks.'); } const dog = new Dog('Buddy'); dog.speak(); // 输出: Buddy barks.
总的来说,class 关键字提供了更直观和简洁的方式来定义和继承类,而构造函数需要手动处理原型链和原型继承,更为繁琐和容易出错。因此,通常情况下建议使用 class 关键字来定义类和继承关系。
当然也有其他细微的差别如下图

坚持不懈,加油!!!坚信努力不一定能上岸,但不努力永远上不了岸。

浙公网安备 33010602011771号