I have a question about how javascript stores functions internally.
Given this code:
var makesomething = function (x) {
var thing = {
x: x
};
thing.do = function () {
this.x++;
};
return thing;
};
var x1 = makesomething(1);
var x2 = makesomething(2);
Since I called the makesomething function twice, does that mean that there are essentially two copies of the "do" function or do the objects have reference to the same function but get called with different closure?
There are two copies, one created each time you called makesomething().
You'll notice that x1.do === x2.do is false.
If instead you do this:
var doIt = function() {
this.x++;
};
var makesomething = function (x) {
var thing = {
x: x
};
thing.do = doIt;
return thing;
};
var x1 = makesomething(1);
var x2 = makesomething(2);
Then both refer to the same function, and x1.do === x2.do will be true.
Related
I've made a function "ADD" which modifies the value of a variable :
function ADD(xs, n)
{
var nom_variable = xs;
var XS = eval(xs);
nouvelle_valeur = eval(nom_variable + "=XS+n");
}
var x = 5 ;
ADD("x",5); // now x = 10
I would like that the first argument of the function ADD is x, not "x". Is this possible ?
I want my students to write algorithms in a way similar to natural language.
Thanks !
You can't pass x as if it were a reference, but you could construct a functional reference (or Lens) although you are still not passing x but a variable that is a reference of x.
var x = 5;
var xRef = {
get : function(){
return x;
},
set : function(val){
x = val;
}
}
function add(ref, n){
var oldVal = ref.get();
ref.set(oldVal+n);
}
add(xRef, 5);
console.log(x);
It's definitely not pretty though.
Let say we have a function that returns a function and bounds arguments to it:
function A(x, y){
return function(x, y){...}.bind(this, x, y);
}
And now we want to know if function A binds arguments correctly:
var resultedFunction = A();
var spy = sinon.spy(resultedFunction);
spy();
The question - is it possible to know if arguments are bound correctly? I've tried this, but it is an empty array
spy.firstCall.args
spy.getCall(0).args
I've finally come to some trick. If the returning function will be not an anonymous then we can spy it and check arguments later:
var obj = {
B: function(){
...
},
A: function(x, y){
return this.B.bind(this, x, y);
}
}
var x = 1, y = 2;
var spy = sinon.spy(obj, "B");
var resultedFunction = obj.A(x, y);
resultedFunction();
expect(spy.firstCall.args[0]).to.equals(x)
expect(spy.firstCall.args[0]).to.equals(y)
I have this code,
var MyNamespace = MyNamespace || {};
MyNamespace.Calculator = function (eq) {
//state goes here
this.eqCtl = document.getElementById(eq);
};
MyNamespace.Calculator.prototype = function () {
//private members
var add = function (x, y) {
this.eqCtl.innerHTML = x + y;
},
subtract = function (x, y) {
this.eqCtl.innerHTML = x - y;
};
//public members
return {
add: add,
subtract: subtract
};
} ();
Var calc = new MyNamespace.Calculator('eqCtl');
calc.add(2,2);
Questions
Why am I getting exception after adding "MyNamespace" to it ? It works if I remove it...
It's recommended not to use "new" keyword for creating objects by Douglas Crockford Then how can I overcome this solution.
Fiddle: https://jsfiddle.net/bpo50qjg/
You have a typo in:
Var calc = new MyNamespace.Calculator('eqCtl');
It should be:
var calc = ...
I have some Javascript code which works fine so far but I do not understand the how the variable "me" is set in the function "run"?
GameLoop.prototype.run = function() {
this.startTime = new Date().getTime();
var currentTimeMillis = this.startTime;
var loops;
var interpolation=0.0;
this.running=true;
return function(me){
loops = 0;
while (new Date().getTime() > currentTimeMillis && loops < me.MAX_FRAMESKIP) {
me.updateGame();
currentTimeMillis += me.SKIP_TICKS;
loops++;
}
interpolation = parseFloat(new Date().getTime() + me.SKIP_TICKS - currentTimeMillis) / parseFloat(me.SKIP_TICKS);
me.drawGame(interpolation);
}
}
The function is called continuously by the browser's animate function below. Since I do not pass any reference to the call f.run(), i guess the correct reference to me is set implicitly. Can someone explain me or give me some useful links which explains this behaviour?
GameLoop.prototype.recursiveAnim = function() {
var f = this.run();
f.run();
this.animFrame( this.recursiveAnim );
};
By calling run you get a function in return, that function has one parameter and its called me.
For example
var x = function () { return function (me) { return me; } }
// by calling x, you get the function: `function (me) { return me; }
var f = x();
console.log(f(1)); // answer is 1
I thought I have understood the idee of closures, but the following code
behaves surprisingly for me:
function A(x)
{
this.getX1 = function () { return x; }
A.prototype.getX2 = function () { return x; }
}
var a1 = new A(1);
var a2 = new A(2);
console.log ('a1.getX1()=%d', a1.getX1 ()); // 1
console.log ('a2.getX1()=%d', a2.getX1 ()); // 2
console.log ('a1.getX2()=%d', a1.getX2 ()); // 2 ???
console.log ('a2.getX2()=%d', a2.getX2 ()); // 2
I could understand if prototype methods behave differently from
instance methods, but this looks like x has become a static variable.
Changing the order of calls does not change results.
When you change the prototype you're changing the function for all instances of the given class, including those that already exist.
Therefore when you call...
A.prototype.getX2 = function () { return x; }
You're setting that for the existing a1 instance of A. So effectively you're ending up with the following pseudo code:
<all instances of A>.getX2 = function () {
return <latest value of x passed to A constructor>;
}
The static member here is A.prototype.getX2. The second call to A.prototype.getX2 = function () { return x; } (due to var a2 = new A(2);) replaces the first one. To understand it you can reverse the order of instantiations:
var a2 = new A(2);
var a1 = new A(1);
Then you'll have:
a1.getX1()=1
a2.getX1()=2
a1.getX2()=1
a2.getX2()=1
You're defining getX2 twice, each time you create a new A. The result for that function will always be the last X. Considering rewriting your code like this:
function A(x) {
this.x = x;
this.getX1 = function() {
return this.x;
}
}
A.prototype.getX2 = function() {
return this.x;
}
var a1 = new A(1);
var a2 = new A(2);
console.log('a1.getX1()=%d', a1.getX1()); // 1
console.log('a2.getX1()=%d', a2.getX1()); // 2
console.log('a1.getX2()=%d', a1.getX2()); // 1
console.log('a2.getX2()=%d', a2.getX2()); // 2
This way, you only define getX2 once and it works as expected.
You have written
function A(x)
{
this.getX1 = function () { return x; }
A.prototype.getX2 = function () { return x; }
}
This constructor overwrites A.prototype.getX2 each time.
So first
var a1 = new A(1); // This invokes A and adds a function `getX2` to the prototype of `A`which returns `x` that is `1`
var a2 = new A(2); // This invokes A and overwrites the function `getX2` in the prototype of `A` with a function which returns `x` that is `2` now.
So it should be like this
function A(x)
{
this.getX1 = function () { return x; }
}
A.prototype.getX2 = function () { return this.getX1(); }