2016-06-08 79 views
2

我遇到一些麻煩THH以下代碼:的Javascript:實例方法返回NAN

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); 

我添加了一個全球num_passengers的pickUpPassengers(),以避免它是不確定的。

但是,我仍然收到總線實例的pickUpPassegers方法的NAN。

這是一個範圍界定或定義問題嗎?

+0

這應該有助於http://stackoverflow.com/a/13522017 – Dhiraj

+0

'num_passengers'永遠不會初始化一個值。 'pickUpPassengers'內引用的是您在頂部定義的全局變量,而不是您添加到'vehicleConstructor'中的對象的車輛實例屬性。 – AtheistP3ace

+0

'num_passengers'未定義。 – Xufox

回答

1

這是一個num_passengers定義的問題。 你應該初始化它爲一個數字開頭:

var num_passengers = 0; 

但是,如果你想改變你的bus對象num_passengers值,你應該使用this,扔掉的num_passengers第一個定義:

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

如果意圖是所有車輛實例共享一個累積值,那麼這將是真實的,我不認爲是這種情況。 –

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; 
} 
+3

我會擺脫那個令人困惑的初始和不需要的'var num_passengers;' –

+0

Thanks @AlexK。好的呼籲,修復。 –

1

這是我會怎麼寫代碼:

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() 

車輛的構造也需要車輪和乘客的數量在選擇對象,這使得它更易於閱讀並瞭解數字的用途。


隨着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) 

(這裏我選擇了把BusVehicle一個子類,因爲它與ES6容易它還可以幫助你,如果你想創建一個以上。一個總線。)