Hello everyone. I'm testing a way I've seen to cache the results of a function within the function itself. But there's a thing I don't understand. First, this is the function:
PHP Code:
function isPrime( num ) {
if (isPrime.cache[num] != null) return isPrime.cache[num];
var prime = num != 1; // Everything but 1 can be prime
for ( var i = 2; i < num; i++ ) {
if ( num % i == 0 ) {
prime = false;
break;
}
}
isPrime.cache[num] = prime;
return prime;
}
isPrime.cache = {}; // defining the function property
isPrime(5); // returns the calculated value (true)
isPrime(5); // returns the value (true) from cache
isPrime.cache[5]; // A way to directly access the cached value
Well, the question is:
why this won't work if I replace isPrime with this within the function? It gives an error like "Cannot set property '5' of undefined". I can't still grasp the difference. this is the function itself, and isPrime is the function too!
this is the function itself, and isPrime is the function too!
isPrime and arguments.callee refer to the function itself. i don't think i've ever seen "this" refer to the actual surrounding function...
"this" always refers to the object holding the function, in your case window.
you can specify "this" using .call(), .bind(), and .apply(), and [].map() and [].filter() accept a 2nd argument that sets "this" within the mapped function.
but again, "this" never really refers to the function itself.
you can say something like this.isPrime.cache[7], but if you want "this" set to an object, you need an object.
not to make it more confusing, but a function is an object, so it can have methods as properties, and within whose methods, "this" will refer to the function being used as an object: String.fromCharCode(), Date.parse() Array.isArray(), etc. these are not the same as prototype methods, those used w/ "new ", which have "this" bound to a blank object.
Hello, thanks for your replies! This is where I got the code by the way: http://ejohn.org/apps/learn/#21 (you may edit it on the fly for testing)
I think one of the things that confused me about what this refers to is the constructors, like this:
PHP Code:
function Foo() { this.name = 'foo'; }
Originally Posted by rnd me
you can say something like this.isPrime.cache[7]
Using this.isPrime.cache[7] generates an error "Cannot set property 'cache' of undefined".
ok, now I think I see it anyway. But still there are tests I've made that confuse me. I've added a log(this) within the function, and in the previous case the output was [object Window]. Window is the containing object of the function (the context of the function). No problem at this point, it's just as you said.
If I do this instead of the previous calls:
PHP Code:
var checkPrime = new isPrime(5);
the output is [object Object], which as I understand after your last paragraph, is the function object, that is isPrime, isn't it? However I can't do this.cache within the function either.
the output is [object Object], which as I understand after your last paragraph, is the function object, that is isPrime, isn't it? However I can't do this.cache within the function either.
This really confuses me more. I thought checkPrime would be just a reference to the object isPrime... but you say that, so I must be totally wrong. I'm afraid of becoming even more confused.
A simple question to rule out one of the things I was confused about, and I think I have clear thanks to your examples:
PHP Code:
function foo() { console.log(this); }
/* calling foo as a regular function this === window (the function is being executed within the context in which has been put into) */ foo();
/* calling foo as a constructor (creating a new object obj) this === obj (the function is being executed within the obj context) */ var obj = new foo();
Is this correct?
Last edited by Jazztronik; 09-21-2012 at 11:25 AM.
This really confuses me more. I thought checkPrime would be just a reference to the object isPrime... but you say that, so I must be totally wrong. I'm afraid of becoming even more confused.
checkPrime is not a reference to isPrime
checkPrime is a newly created object
A simple question to rule out one of the things I was confused about, and I think I have clear thanks to your examples:
PHP Code:
function foo() {
console.log(this);
}
/*
calling foo as a regular function
this === window (the function is being executed within the context in which has been put into)
*/
foo();
/*
calling foo as a constructor (creating a new object obj)
this === obj (the function is being executed within the obj context)
*/
var obj = new foo();
Is this correct?
when calling foo as a constructor
this will refer to the newly
created object so yes
i beleive
calling foo as a constructor (creating a new object obj)
this === obj (the function is being executed within the obj context)
is a correct statement
So, having that part of context clear, there is something still clouding my comprehension.
Going back to the first example, why if I do
PHP Code:
var checkPrime = new isPrime(5);
this within isPrime() refers to an object called checkPrime instead of isPrime? I thought checkPrime would be a variable referencing an object. So if I do this:
PHP Code:
var testPrime = checkPrime;
am I copying the object instead of referencing the same?
So, having that part of context clear, there is something still clouding my comprehension.
Going back to the first example, why if I do
PHP Code:
var checkPrime = new isPrime(5);
this within isPrime() refers to an object called checkPrime instead of isPrime? I thought checkPrime would be a variable referencing an object. So if I do this:
PHP Code:
var testPrime = checkPrime;
am I copying the object instead of referencing the same?
Code:
function isPrime(){var greet="hiyas";}
checkPrime = isPrime;
alert(checkPrime)//alerts function isPrime(){var greet="hiyas";}
so it seems
checkPrime and isPrime
refference the same object
here is proof that is true
(get ready for some real confusion)
Code:
function isPrime(){var greet="hiyas";}
checkPrime = isPrime;
alert(checkPrime)//alerts function isPrime(){var fareWell="seeya";}
function isPrime(){var fareWell="seeya";}
Last edited by DaveyErwin; 09-21-2012 at 05:29 PM.
Since function declarations are executed before other statements, the conclusion from above example doesn't seem right to me.
The javascript interpreter runs it like:
Code:
function isPrime(){var greet="hiyas";}
function isPrime(){var fareWell="seeya";}
checkPrime = isPrime;
alert(checkPrime) //alerts function isPrime(){var fareWell="seeya";}
this within isPrime() refers to an object called checkPrime instead of isPrime? I thought checkPrime would be a variable referencing an object.
>>> this within isPrime() refers to an 'anonymous' (can't really call it anonymous, since we have a reference to it) object, which is refered to by the variable checkPrime.
When call isPrime as a constructor, using the 'new' keyword it creates an instance of an object.
Code:
var testPrime = checkPrime;
am I copying the object instead of referencing the same?
>>> It doesn't create a copy, but a reference.
Code:
function Base(val){
this.val = val;
};
var a = new Base('AAA');
var b = a;
b.val = 'BBB';
alert(a.val); // BBB
Another way to create a function with cache is to wrap it into a closure:
Code:
var isPrime = (function(){
var cache = [];
function isPrime(num){
if(cache[num] != null){
return cache[num];
}
var prime = num != 1; // Everything but 1 can be prime
for(var i=2; i<num; i++){
if(num % i == 0){
prime = false;
break;
}
}
cache[num] = prime;
return prime;
}
return isPrime;
}());
So, summarizing, and please correct me if I'm wrong:
1 - Variables are references actually. The exception is when using primitive types (integer, float, boolean, string). I'm still not sure of the last statement (language mess in my head).
2 - "this" references:
a - the container object when a function is called as usually, the Window object in this case.
b - using the "new" keyword: an object which is referenced by the instance name (checkPrime). I still haven't clear the object. I've just made this test:
PHP Code:
function isPrime( num ) { console.log(this); ...... }
var checkPrime = new isPrime(5); // console: isPrime
So the referenced object would be isPrime, but again: why can't I use "this" to access its properties, such as isPrime.cache? I already have it clear if I use isPrime as a normal function, since this would refer to Window, but not when used as a constructor
Last edited by Jazztronik; 09-22-2012 at 05:00 AM.
That console is a little confusing. The referenced object is an instance of the isPrime constructor. A contructor could be seen as a template to create objects.
PHP Code:
function Person(name){
this.name = name;
console.log(this.name) // when john is created, this refers to the john object/instance, when lucy is created it points to the lucy object
};
var john = new Person('John'); // john = {name: 'John'}
var lucy = new Person('Lucy'); // lucy = {name: 'Lucy'}
// a constructor also has a prototype chain, in which properties shared by all instances are stored.
// Person.prototype, and also the inherited Function.prototype and Object.prototype.
// Only if a property is not on the constructor, it will be looked for down the prototype chain
Person.prototype.sayHello = function(){console.log('Hello, I\'m ' + this.name)}; // this points to object/instance which is calling sayHello
Bookmarks