【问题标题】:Javascript: instance method returning NANJavascript:返回 NAN 的实例方法
【发布时间】:2016-10-09 01:14:37
【问题描述】:

我在使用以下代码时遇到了一些问题:

var num_passengers;


function vehicleConstructor(name, num_wheels, num_passengers)
{
    var vehicle = {};
    vehicle.name = name;
    vehicle.num_wheels = num_wheels;
    vehicle.num_passengers = num_passengers;

    vehicle.makenoise = function() {

    }
    return vehicle;
}

var bus = vehicleConstructor("bus", 5, 10);

bus.pickUpPassengers = function(toPickUp){
    num_passengers += toPickUp;
    return num_passengers;
} 


 bus.pickUpPassengers(5);

我为 pickUpPassengers() 添加了一个全局 num_passengers 以避免它未定义。

但是,我仍然收到总线实例的 pickUpPassegers 方法的 NAN。

这是范围界定问题还是定义问题?

【问题讨论】:

  • 这应该有助于stackoverflow.com/a/13522017
  • num_passengers 永远不会用值初始化。您在pickUpPassengers 中引用的是您在顶部定义的全局变量,而不是您在vehicleConstructor 中添加到对象的车辆实例属性。
  • num_passengers 未定义。
  • inside bus.pickUpPassengers() this.num_passengers 是绑定到 bus 实例的值,如果这就是您要查找的...(即返回 15)

标签: javascript methods javascript-objects nan


【解决方案1】:

查找当前实例只是一个小问题。您只需使用 'this' 定义 num_passengers 所需的实例。

此外,这样您就不需要 num_passengers 的全局变量,这意味着您可以同时拥有多个实例(汽车、公共汽车和摩托车)。这将潜在地避免未来的问题。

function vehicleConstructor(name, num_wheels, num_passengers)
{
    var vehicle = {};
    vehicle.name = name;
    vehicle.num_wheels = num_wheels;
    vehicle.num_passengers = num_passengers;

    vehicle.makenoise = function() {

    }
    return vehicle;
}

var bus = vehicleConstructor("car", 5, 10);

bus.pickUpPassengers = function(toPickUp){
    this.num_passengers += toPickUp;
    return this.num_passengers;
} 

【讨论】:

  • 我会摆脱令人困惑的初始和不需要的var num_passengers;
  • 感谢@AlexK。很好地解决了这个问题。
【解决方案2】:

这是num_passengers 定义的问题。 您应该在开头将其初始化为数字:

var num_passengers = 0;

但是如果你想改变你的bus对象的num_passengers的值,你应该使用this并抛出num_passengers的第一个定义:

bus.pickUpPassengers = function(toPickUp){
    this.num_passengers += toPickUp;
    return this.num_passengers;
}

【讨论】:

  • 如果意图是让车辆的所有实例共享单个累积值,这将是正确的,我认为情况并非如此。
【解决方案3】:

我会这样写你的代码:

function Vehicle (name, options) {
  this.name = name
  this.wheels = options.wheels
  this.passengers = options.passengers
}

Vehicle.prototype.makeNoise = function () {
  console.log('vroom')
  return this
}

var bus = new Vehicle('bus', { wheels: 4, passengers: 10 })

bus.pickUpPassengers = function (toPickUp) {
  this.passengers += toPickUp
  return this
}

bus.pickUpPassengers(5)

这使用了 JavaScript 的原型继承,可以像其他语言中的类一样使用。构造函数以大写字母开头(按照惯例)并以new 调用。使用原型还意味着您不必在每次创建新车辆时都定义 makeNoise 之类的方法,而是所有车辆都引用原型。

我还在方法末尾使用了return this,因为它允许链接:

// Without chaining:
foo.bar()
foo.baz()
foo.qux()

// With chaining:
foo.bar().baz().qux()

Vehicle 构造函数还在选项对象中获取车轮和乘客的数量,这样更容易阅读和理解这些数字的用途。


使用 ES6,它看起来像这样:

class Vehicle {
  constructor (name, { wheels, passengers } = {}) {
    this.name = name
    this.wheels = options.wheels
    this.passengers = options.passengers
  }
  makeNoise () {
    console.log('vroom')
    return this
  }
}

class Bus extends Vehicle {
  constructor (options) {
    super('bus', options)
  }
  pickUpPassengers (toPickUp) {
    this.passengers += toPickUp
    return this
  }
}

const bus = new Bus({ wheels: 4, passengers: 10 })
bus.pickUpPassengers(10)

(这里我选择将Bus 设为Vehicle 的子类,因为使用 ES6 更容易。如果您想创建多个总线,它也会为您提供帮助。)

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    相关资源
    最近更新 更多