2016-02-17 16 views
5

Tôi đang tiếp cận việc học JavaScript từ nền Ruby, vì vậy tôi gặp khó khăn trong việc hiểu (và đặt từ này thành từ) tại sao mã của tôi không tạo được kết quả nhu cầu. Tôi đã thực hiện điều này tại pythontutor.com để xem hướng dẫn từng bước về những gì đang xảy ra và nó xác nhận sự nghi ngờ của tôi. Tuy nhiên, tôi không chắc chắn chính xác lý do tại sao đây là trường hợp.Chức năng Javascript và nguyên mẫu - vấn đề định tuyến cơ bản thông qua các phương thức gọi

Tôi đang xây dựng bộ ổn nhiệt và phải trả lại 'màu xanh' khi nhiệt độ dưới 18dC. Trên đường áp chót của tôi, console.log là 17 là chính xác, tuy nhiên khi tôi gọi thermostat.displayColor trên dòng cuối cùng nó vẫn nói màu vàng. Mã kết thúc ở đó, và không quay trở lại thông qua this.displayColor = this.currentColor() mà tôi mong đợi nó (vì nó đã làm điều này trong lần chạy đầu tiên để xác định màu bắt đầu là 'vàng'.

Mã hoạt động chính xác và trả về 'xanh' nếu tôi thay đổi mã để gọi trực tiếp phương thức mẫu thử nghiệm this.currentColor(), tuy nhiên tôi chỉ muốn biết tại sao nó không cho phép tôi thực hiện theo cách tôi đã viết bên dưới:

Tôi không chắc chắn về thuật ngữ để mô tả điều này vấn đề, vì vậy xin lỗi trước cho tiêu đề của tôi không chính xác.

var DEFAULT_TEMP = 20; 

function Thermostat(){ 
    this.temperature = DEFAULT_TEMP; 
    this.maxTemp = 25; 
    this.powerMode = 'on'; 
    this.displayColor = this.currentColor() 
}; 

Thermostat.prototype.downButton = function(){ 
    if (this.temperature === 10){ 
    throw new Error('temp cannot be lower than 10dC'); 
    }; 
    this.temperature --; 
}; 

Thermostat.prototype.currentColor = function() { 
    if ((this.temperature >= 18) && (this.temperature < 25)) { 
    return 'yellow' 
    } 
    else if (this.temperature < 18) { 
    return 'green' 
    } 

    else { 
    return 'red' 
    } 
}; 

var thermostat = new Thermostat(); 
for (var i = 1; i <= 3; i++) { 
     thermostat.downButton(); 
     }; 
console.log("spec file test green, temp should be 17 and is:" + thermostat.temperature) 
console.log(thermostat.displayColor); //this should be green, but it is yellow! 

Trả lời

3

Bạn nên gọi phương pháp currentColor(), displayColor chỉ được đặt trong hàm khởi tạo (tại đó nhiệt độ thời gian là 20) và không được cập nhật khi nhiệt độ thay đổi.

Nó có thể làm cho tinh thần để thêm các thiết lập màu sắc với phương pháp downButton:

Thermostat.prototype.downButton = function(){ 
    if (this.temperature === 10){ 
    throw new Error('temp cannot be lower than 10dC'); 
    }; 
    this.temperature --; 
    this.displayColor = this.currentColor(); 
}; 
+0

cảm ơn bạn Rob cho phản ứng nhanh chóng! Có lý do cụ thể nào về lý do tại sao displayColor chỉ được đặt một lần (tại thời điểm khởi tạo)? Tôi muốn đọc thêm về điều này, nó có thể là một khái niệm thực sự cơ bản nhưng tôi không chắc chắn làm thế nào để bắt đầu tìm kiếm này – ugotchi

+1

@ggwc bất cứ khi nào bạn tạo ra thể hiện bạn đang gọi hàm constructor. Đó là lần duy nhất hàm 'Thermostat()' được gọi là 'displayColor()' chỉ được gọi là – Sean

+1

@ggwc Không vấn đề gì. Có lẽ bạn đang nghĩ rằng 'this.displayColor = this.currentColor()' sẽ ràng buộc giá trị của 'displayColor' theo cách nào đó mà nó luôn gọi hàm' currentColor' để lấy giá trị của nó, nhưng đó không phải là điều xảy ra. Hàm khởi tạo ('function Thermostat() {...') được gọi một lần khi bạn khởi tạo 'new Thermostat()' và các giá trị bạn đặt trong constructor là static trừ khi được cập nhật bởi các hàm thành viên khác hoặc bên ngoài. –

2

Như Rob nói, bạn nên gọi hàm tính toán màu sắc hiện tại. Dưới đây là gợi ý của ông cùng với một số cải tiến mã của bạn:

function Thermostat() { 
 
    this.MIN_TEMP = 10; 
 
    this.MAX_TEMP = 25; 
 
    this.temperature = 20; 
 
} 
 

 
Thermostat.prototype.decreaseTemp = function() { 
 
    if (this.temperature > this.MIN_TEMP) this.temperature--; 
 
}; 
 
Thermostat.prototype.increaseTemp = function() { 
 
    if (this.temperature < this.MAX_TEMP) this.temperature++; 
 
}; 
 
Thermostat.prototype.currentColor = function() { 
 
    if (this.temperature < 18) return 'green'; 
 
    if (this.temperature < 25) return 'yellow'; 
 
    return 'red'; 
 
}; 
 

 
var thermostat = new Thermostat(); 
 
for (var i = 1; i <= 3; i++) { 
 
    thermostat.decreaseTemp(); 
 
} 
 

 
// no errors mean all assertions pass 
 
thermostat.temperature.should.equal(17); 
 
thermostat.currentColor().should.equal('green');
<script src="https://cdnjs.cloudflare.com/ajax/libs/should.js/8.2.2/should.min.js"></script>

Các vấn đề liên quan