开发者问题收集

我的代码中不断出现“未捕获范围”错误,我不知道为什么

2019-10-15
68

我的导师让我创建一个代表车辆的类和两个代表“救护车”和“公共汽车”的子类。我的 HTML 文件将实例化每个子类,并允许我通过发出方法来驾驶它们。在我写这篇文章的时候,我的控制台一直出现“未捕获范围”错误。

class Vehicle {
  constructor(color, direction, currentSpeed, topSpeed) {
      this.color = color; //string
      this.direction = direction; //integer 0-359 (representing a compass)
      this.currentSpeed = currentSpeed; //integer
      this.topSpeed = topSpeed; // integer
      this.engineStarted = true; //boolean
     }

//Methods:
  turnOn() {
    this.engineStarted = true;
  }
  info(){
    if(this.engineStarted){
      const info = `${this.color}, ${this.direction}, ${this.currentSpeed}, ${this.topSpeed}`;
      return info;
      } else {
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate.";
      return status;
      }
    }
  statusOn(){
    if(this.engineStarted){
      const statusOn = "Engine Started, Vehicle Operational.";
      return statusOn;
    } else {
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate.";
      return status;
    }
  }
  turnOff() {
    this.engineStarted = false;
  }
  info() {
    const status = "The Engine is now disengaged and vehicle is inactive."
    return status;
  }
  accelerate(){
    if(this.engineStarted = false){
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
      return status;
    }
    if (this.currentSpeed < 100) {
      this.currentSpeed += 10;
      console.log("Accelerate speed is now: " + this.currentSpeed);
    } else {
      console.log("Top Speed Reached");
    } 
  }
  brake(){
    if(this.engineStarted = true){
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
      return status;
    }
    if (this.currentSpeed > 10) {
      this.currentSpeed -= 10;
      console.log("Brake speed is now: " + this.currentSpeed);
    } else {
      this.currentSpeed = 0;
      console.log("Speed is now: " + this.currentSpeed);
    }
  }
  turnLeft(){
    if (this.engineStarted = true) {
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
      return status;
    }
    this.direction - 90;
    if (this.direction < 0) {
      this.direction + 90;
    }
  }
  turnRight(){
    if (this.engineStarted = true) {
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
      return status;
    }
    this.direction + 90;
    if (this.direction > 359) {
      this.direction - 90;
    }
  }
}

class Bus extends Vehicle {
  constructor(color, direction, currentSpeed, topSpeed, numberOfSeats) {
    super(color, direction, currentSpeed, topSpeed);
    this.numberOfSeats = numberOfSeats;
  }
  info() {
    if (this.engineStarted) {
      const info = `${this.color}, ${this.direction}, ${this.currentSpeed}, ${this.topSpeed}, ${this.numberOfSeats} seats`;
      return info;
      } else {
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
      return status;
      }
    }

    set numberOfSeats(newSeats) {
      if (newSeats < 50) {
        this.numberOfSeats = newSeats;
      } else {
        alert("Exceeded Seat Number");
      }
    }
  }

class Ambulance extends Vehicle {
  constructor(color, direction, currentSpeed, topSpeed, sirens) {
    super(color, direction, currentSpeed, topSpeed, sirens);
    this.sirens = sirens;
    
  }
    info() {
      if (this.engineStarted) {
        const info = `${this.color}. ${this.direction}, ${this.currentSpeed}, ${this.topSpeed}, Toggle ${this.sirens}`;
        return info;
      } else {
        const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
        return status;
      }
    }

    toggleSirens(){
    this.sirens = true;
    }
    set sirens(toggleSiren) {
      if (this.sirens){
        const info = "Sirens Activated";
        return info;
      } else {
        const status = "Sirens Inactive";
        return status;
      }
    }
}
<DOCTYPE html/>
<html>
  <head>
    <title>Vehicles</title>
  </head>
  <body>
    <script src="Johnson_ES6_Classes.js"></script>
    <script>
      let bus = new Bus("Yellow", 90, 45, 50, 45);
      let ambulance = new Ambulance("White", 180, 60, 65);

      alert(bus.info());
      alert(ambulance.info());
    </script>
  </body>
</html>

Bus.set numberOfSeats [as numberOfSeats] (Johnson_ES6_Classes.js:116) Uncaught RangeError: 超出最大调用堆栈大小

2个回答

就像@jfriend00说的,你的setter有一个无限循环。 我认为另一种解决方案可以是这样的。

class Bus extends Vehicle {
  constructor(color, direction, currentSpeed, topSpeed, numberOfSeats) {
    super(color, direction, currentSpeed, topSpeed);
    this.setseats(numberOfSeats);
  }
  info() {
    if (this.engineStarted) {
      const info = `${this.color}, ${this.direction}, ${this.currentSpeed}, ${this.topSpeed}, ${this.numberOfSeats} seats`;
      return info;
      } else {
      const status = "Engine has not been started! Vehicle is idle and inactive. Please activate";
      return status;
      }
    }

    setseats(newSeats){
        if (newSeats < 50) {
        this.numberOfSeats = newSeats;
      } else {
        alert("Exceeded Seat Number");
      }
    }

   } 
Fabio Assuncao
2019-10-15

此处的 setter:

set numberOfSeats(newSeats) {
  if (newSeats < 50) {
    this.numberOfSeats = newSeats;
  } else {
    alert("Exceeded Seat Number");
  }
}

导致无限递归,从而溢出堆栈。当您尝试设置 this.numberOfSeats = newSeats 时,会再次调用 setter,而 setter 又会再次调用 setter,无限循环,直到堆栈溢出。

如果您要执行 setter,则需要创建另一个命名属性来存储没有 setter 的值。一种可能性是使用 _numberOfSeats 作为属性名称。

set numberOfSeats(newSeats) {
  if (newSeats < 50) {
    this._numberOfSeats = newSeats;
  } else {
    alert("Exceeded Seat Number");
  }
}

get numberOfSeats() {
    return this._numberOfSeats;
}

但是,您并没有真正解释为什么首先要为该属性使用 setter,因此可能还有其他合适的解决方案。

jfriend00
2019-10-15