Why can't i access the variable HTML in the constructor function using the prototype method .nextSlide?
function test(root){
var HTML = getAllHTML();
function getAllHTML(){
var boss, expoHTML;
var boss = document.querySelector(root);
expoHTML = {
slides: boss.querySelectorAll(".slide"),
prev: boss.querySelector(".control.prev"),
next: boss.querySelector(".control.next"),
current: boss.querySelector(".slide-current"),
total: boss.querySelector(".slide-total")
}
return expoHTML;
}
}
EXPOjs.prototype.nextSlide = function(){
alert(HTML.current)
}
var newTEST = new test(".ieps");
newTEST.nextSlide();
It's a "scope" problem; every variable in Javascript has a scope, which means: "who can see this variable"?
In your case, HTML
is defined in the function test()
. This means that it will be visible:
test()
test()
That's it. Outside test()
, HTML will be empty.
Now, I can see that you are using test() as a constructor function. With this, you enter the wonderful world of object creation and Javacript. Take a deep breath :D
When you do this:
function Person( age ){
this.age = age;
}
And then you do:
var pavlo = new Person( 23 );
Basically "new" has the effect of:
this
points to the newly created objectpavlo
This trickery means that you can do
var pavlo = new Person( 23);
console.log( pavlo.age );
And then there are prototype functions. If you define a function like this:
Person.prototype.setAge = function( newAge){
this.age = newAge();
}
Any function (or any variable for that matter) defined in Person's
prototype
object will also be accessible to any object created using that constructor. Plus, the this
variable will be the object making that call.
So, if you have:
function Person( age ){
this.age = age;
}
Person.prototype.setAge = function( newAge){
//`this` at this point is the object "calling" <-- This will throw an error if left uncommented.
this.age = newAge();
}
var pavlo = new Person( 23 );
console.log( pavlo.age );
// pavlo is making the call. So, within `setAge()`, `this` will be `pavlo`
pavlo.setAge( 26 );
So, for your solution:
function test(root){
this.HTML = getAllHTML();
// etc.
}
And then your alert should be:
test.prototype.nextSlide = function(){
alert(this.HTML.current);
}
Note that in Javascript you should have constructor functions starting with a capital letter (see: Test
rather than test
).
If you don't want HTML to be accessible from the outside, convention says that you normally put an underscore in front of the variable's name (call it _HTML
).
There are other ways of doing it, if you absolutely have to keep that variable hidden away from the developers. However, it's not exactly straightforward and -- most developers would say -- definitely not worth the effort.
A couple of good reads (but, I must say that I read them when I was starting with JS, and they confused the hell out of me at the time :D )
UPDATE: This is another fantastic article on this matter: https://blog.jcoglan.com/2012/01/19/the-cost-of-privacy
Enjoy!