This is my first attempt to javascript prototyping. I am using the Espruino(javascript interpreter for microcontrollers) to get data from environment sensors. I am trying to pause my code for 1000ms, then execute the getSensorReading() method which is(I think) located inside of another method. How do I execute getSensorReading() method? I believe the error is cause by this:
setTimeout(function (e) { this.getSensorReading(); }, w); //Attempting to execute getSensorReading()
I am receiving this error:
Uncaught Error: Function "getSensorReading" not found! at line 1 col 8 { this.getSensorReading(); }
^ in function called from system
Code:
I2C1.setup({scl:b6, sda:b7});
function Sensor (theType, theAddress) {
this.type = theType; //i.e. PH
this.address = theAddress; //i2c Address
this.sensorResult = 0; //Store sensor result
this.cmdTable = {
"Calibrate" : { //List of Calibration commands and timeout value.
"clear" : { "cmd" : "Cal,Clear", "wait" : 300 },
"mid" : { "cmd" : "Cal,mid,7.00", "wait" : 1300 },
"low" : { "cmd" : "Cal,low,4.00", "wait" : 1300 },
"high" : { "cmd" : "Cal,high,10.00", "wait" : 1300 },
"query" : { "cmd" : "Cal,?", "wait" : 300 }
},
"Information" : { //Device Information
},
"LED" : { //Enable / Disable or Query the LEDs
"L0" : { "cmd" : "L,0", "wait" : 300 },
"L1" : { "cmd" : "L,1", "wait" : 300 },
"L?" : { "cmd" : "L,?", "wait" : 300 }
},
"Reading" : { //Takes a single reading
"R" : { "cmd" : "R,25.6", "wait" : 1000 } //Takes a single temperature compensated reading
},
"Serial" : { //Switch back to UART mode
},
"Sleep" : { //Enter low power sleep mode
},
"Status" : { //Retrieve status information
},
"Temperature" : { //Set or Query the temperature compensation
"T" : { "cmd" : "T,19.5", "wait" : 300 }, //Where the temperature is any value; floating point, or int, in ASCII form
"T?" : { "cmd" : "T,?", "wait" : 300 } //Query the set temerature
},
"Factory" : { //Factory reset
},
};
}
Sensor.prototype = {
constructor: Sensor,
getSensorType:function () {
return this.type; //Get Sensor type
},
getSensorAddress:function () {
return this.address; //Get Sensor address
},
getSensorReading:function() {
a = this.getSensorAddress;
console.log("i2c Address: " + a);
//d = I2C1.readFrom(a, 7);
return d;
},
getSensorResult:function () {
a = this.getSensorAddress;
c = this.cmdTable.Reading.R.cmd;
w = this.cmdTable.Reading.R.wait;
//I2C1.writeTo(a, c);
setTimeout(function (e) { this.getSensorReading(); }, w); //Attempting to execute getSensorReading()
},
storeSensorResult:function () {
},
updateResTemp:function (temp) {
console.log("Before: " + this.cmdTable.Reading.R.cmd);
this.cmdTable.Reading.R.cmd = "R," + temp;
console.log("After: " + this.cmdTable.Reading.R.cmd);
}
};
var ph = new Sensor("ph", 0x63);
ph.updateResTemp(90.5);
ph.getSensorResult();
In your code "this" in setTimeout
callback refers the parent function getSensorResult
. That function doesn't have a function called getSensorReading
. That's the reason for the error... Also as you are using global variables inside function unexpected results may occur by overbidding the variables. Make them global with var
keyword. Try changing like this..
getSensorReading:function() {
var a = this.getSensorAddress;
console.log("i2c Address: " + a);
//var d = I2C1.readFrom(a, 7);
return d;
},
getSensorResult:function () {
var a = this.getSensorAddress;
var c = this.cmdTable.Reading.R.cmd;
var w = this.cmdTable.Reading.R.wait;
var that = this;
//I2C1.writeTo(a, c);
setTimeout(function (e) { that.getSensorReading(); }, w); //Attempting to execute getSensorReading()
}
Declare global method foo
and sub-method bar
and refer to sub-method as function in itself, you can use this
keyword inside sub-method by addressing previously declared variable, and then declare the return variable as the sub-method process.
Foo: function()
{
var a='a';
var ret='b';
var Bar = function()
{
this.a='a';
return 'a';
}
ret=Bar();
return ret;
}
Agreed with looking into this
, Function.prototype.bind
, and also the prototype chain in general. Also, javascript is a dynamically bound language. You can re-bind this
.
you can either store a reference to this as a closure variable, or bind the function literal that you're passing to setTimeout
to the context you want ( Sensor.prototype
or this
in that context)
EDIT: In lieu of having bind
available, you can accomplish the same thing with apply, call, or closures.
getSensorResult:function () {
a = this.getSensorAddress;
c = this.cmdTable.Reading.R.cmd;
w = this.cmdTable.Reading.R.wait;
//I2C1.writeTo(a, c);
setTimeout((function(_this) {
return function (e) {
_this.getSensorReading();
}
})(this), w); //Attempting to execute getSensorReading()
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.