what's wrong in the member 'dydt' in methods?

Y

Yun

Hi, Javascriptists!

I wrote a code with Javascript and I am annoyed by the member 'dydt'
called from the member 'rk2'. I can not get the value of this.rho,
with the error message that this.rho is undefined.

However when dydt is an inner function or outer function, the value of
rho can be correctly obtained.

I guess that it may be the enclosure problem but I could not find a
reasonable explanation about it.

If I insist to use the dydt as the member of methods, how should I do
in order to obtained the value of rho in the methods?

Thanks a lot in advance.

Here is the source code?
-----------------------------------------------------------------------------------------------

<html>
<head>
<title>Test</title>
</head>
<body>

<textarea id="results" cols="100" rows="10" style="clear:float">OK</
textarea>



<script>
function RK() {}
RK.prototype.rk2 = function(ynref, dydtref, t, dt) {
var gamma = 0.75; // Ralston's minimisation of error bounds
var alpha = 0.5 / gamma;
var beta = 1.0 - gamma;

var alphadt = alpha * dt;
var betadt = beta * dt;
var gammadt = gamma * dt;

var ny = ynref.length;

var ynp1 = [],
dydtn = [],
ynpalpha = [],
dydtnpalpha = [];

alert("rk2: "+ "t="+t + "ynref = "+ ynref);

dydtn = dydtref(t, ynref);

var i;
for (i = 0; i < ny; i++) {
ynpalpha = ynref + alphadt * dydtn;
}

dydtnpalpha = dydtref(t + alphadt, ynpalpha);

for (i = 0; i < ny; i++) {
ynp1 = ynref + betadt * dydtn + gammadt * dydtnpalpha
;
}
return [t + dt, ynp1];
};



/////////////////////////////////////////////////////////////////////////////////////////////
var methods = {
n: 5,

//final time to terminate the calculation.
t_final: 0.5,

set_dt: function() {
return this.dt = this.t_final / this.n;
},

//thermal properties
rho: 100,

//
get_dt: function() {
return this.dt;
},

// initial condition
t: 0,
y: [0],

// time interval
dt: 1,

//????????????????????????????????????????????????????
// I could not get the members in dydt when dydt is called from
rk2.
dydt : function(t, y) {
var dydt_arr = [];

//?????????????????????????????????????????????????????????????????????????????

alert("dydt: " + "this.rho = " + this.rho ); // why here
this.rho is undefined?

//?????????????????????????????????????????????????????????????????????????????

dydt_arr[0] = 10 - 10 * y[0];

return dydt_arr;
},


//////////////////////////////////////////
rk2: function() {
alert("rk2: " + "this.dt="+ this.dt);

var i;
var n = this.n;

var data = "";
var tmp = [];

// set dt
this.set_dt();


//////////////////////////////////////////
var that = this;
var dydt = function(t, y) {
var dydt_arr = [];

//?????????????????????????????????????????????????????????????????????????????

alert("dydt: " + "methods.rho = " + that.rho ); // OK

//?????????????????????????????????????????????????????????????????????????????

dydt_arr[0] = 10 - 10 * y[0];

return dydt_arr;
};

var rk = new RK();


for (i = 1; i <= n; i++) {

// tmp = rk.rk2(this.y, dydt, this.t, this.dt ); //OK

// the following is wrong?
tmp = rk.rk2(this.y, this.dydt, this.t, this.dt ); //
wrong

this.t = tmp[0];
this.y = tmp[1];

data += this.t + "\t" + "\t" + this.y[0] + "\n";
}

document.getElementById("results").value = data;
alert(data);
}

};

methods.rk2();
</script>

</body>
</html>
 
T

Tim Down

Hi, Javascriptists!

I wrote a code with Javascript and I am annoyed by  the member 'dydt'
called from the member 'rk2'.  I can not get the value of this.rho,
with the error message that this.rho is undefined.

However when dydt is an inner function or outer function, the value of
rho can be correctly obtained.

I guess that it may be the enclosure problem but I could not find a
reasonable explanation about it.

If I insist to use the dydt as the member of methods, how should I do
in order to obtained the value of rho in the methods?

Thanks a lot in advance.

Here is the source code?


The reason is that when you pass the dydt method in this line of
methods.rk2

tmp = rk.rk2(this.y, this.dydt, this.t, this.dt );

.... this.dydt is just a reference to the function you've assigned to
methods.dydt. It's not bound to the "methods" object in any way. When
it's executed in the following line of RK.prototype.rk2:

dydtn = dydtref(t, ynref);

.... "this" in methods.dydt isn't "methods", it's a reference to the
global object (window).

You could use a closure to get the behaviour you want. In methods.rk2,
add the following after the "var rk = new RK();" line:

var this_dydt = function(t, y) {
return that.dydt(t, y);
};

.... and use it function instead of "this.dydt":

tmp = rk.rk2(this.y, this_dydt, this.t, this.dt);

Tim
 
Y

Yun

On Jun 2, 9:42 am, Yun <[email protected]> wrote:

Hi, Tim,

Thank you very much for your quickly answering my question.

The reason is that when you pass the dydt method in this line of
methods.rk2

tmp = rk.rk2(this.y, this.dydt, this.t, this.dt );

... this.dydt is just a reference to the function you've assigned to
methods.dydt. It's not bound to the "methods" object in any way. When
it's executed in the following line of RK.prototype.rk2:

dydtn = dydtref(t, ynref);

... "this" in methods.dydt isn't "methods", it's a reference to the
global object (window).

It is so hardly understood for me that "this" in methods.dydt isn't
'methods' but it's a reference to the global object (window).

However "this" in other methods like "methods.set_dt" or
"methods.rk2", "this" represents the object "methods".

I confirmed with following "alert" in "methods.set_dt".

set_dt: function() {

alert("set_dt: " + "this="+ this+ " this.rho="+ this.rho);

return this.dt = this.t_final / this.n;
}

I am still confused. The mystery enclosure in Javascript is so
difficult to master.

You could use a closure to get the behaviour you want. In methods.rk2,
add the following after the "var rk = new RK();" line:

var this_dydt = function(t, y) {
return that.dydt(t, y);
};

... and use it function instead of "this.dydt":

tmp = rk.rk2(this.y, this_dydt, this.t, this.dt);

Thanks a lot for your suggested modification. It really works as I
expected.

But is any way not to do such extra work?

Yun
 
T

Tim Down

Hi, Tim,

Thank you very much for your quickly answering my question.






It is so hardly understood for me that "this" in methods.dydt isn't
'methods' but it's a reference to the global object (window).


The short answer is that it depends on how the function is called. If
you have a reference to a function stored in a variable and call it by
adding parentheses to that variable name, "this" inside that function
defaults to the global object. If you have a reference to the same
function stored as a method of an object and call the method, "this"
is then a reference to the object. For example:

var func = function() {
window.alert( this.testProp );
};

var o = {
testProp: "A property",
method: func
};

func(); // Alerts 'undefined'
o.method(); // Alerts 'A property'

You can also explicitly specify the object you wish to be assigned to
"this" by using the call() method (or the similar apply() method)
method of all functions (caveat: IE 5 does not have these methods):

func.call(o); // Alerts 'A property'
However "this" in other methods like "methods.set_dt" or
"methods.rk2", "this" represents the object "methods".

I confirmed with following "alert" in "methods.set_dt".

set_dt: function() {

alert("set_dt: " + "this="+ this+ " this.rho="+ this.rho);

return this.dt = this.t_final / this.n;
}

I am still confused. The mystery enclosure in Javascript is so
difficult to master.

<snip>

I suggest the FAQs for a detailed explanation of closures.
http://www.jibbering.com/faq/faq_notes/closures.html

Tim
 
Y

Yun

The short answer is that it depends on how the function is called. If
you have a reference to a function stored in a variable and call it by
adding parentheses to that variable name, "this" inside that function
defaults to the global object. If you have a reference to the same
function stored as a method of an object and call the method, "this"
is then a reference to the object. For example:

var func = function() {
window.alert( this.testProp );
};

var o = {
testProp: "A property",
method: func
};

func(); // Alerts 'undefined'
o.method(); // Alerts 'A property'

You can also explicitly specify the object you wish to be assigned to
"this" by using the call() method (or the similar apply() method)
method of all functions (caveat: IE 5 does not have these methods):

func.call(o); // Alerts 'A property'







<snip>

I suggest the FAQs for a detailed explanation of closures.http://www.jibbering.com/faq/faq_notes/closures.html

Tim

Hi, Tim

I very appreciate your kind explanations and the materials about the
weird closures in Javascript.
I have to do more exercises to be familiar to it.

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,088
Latest member
JeremyMedl

Latest Threads

Top