I've got a simple question about accessing variables in jQuery. Is there are way to access the variable (wrap) when I call the read function on click of 'a'.
(function() {
var Example= {
init: function() {
var wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(wrap)
}
};
Example.init();
})();
There are a few ways to accomplish this. Perhaps the easiest is to change the scope of the 'wrap' variable. Currently, since it's declared with a var inside the init function, it's scoped to the init function and not available outside of init directly. So, you can declare the 'wrap' outside the init (it could be a property of the 'Example' object):
var Example= {
wrap: 'hello world',
init: function() {
var self = this;
$('a').click(function(){
self.read();
});
},
read: function() {
console.log(this.wrap);
}
};
Example.init();
This makes 'wrap' scoped to 'Example' and available as a property of 'Example' throughout any function defined within 'Example'.
(Edit: had to tweak this a bit to properly handle the closure.)
(function() {
var wrap;
var Example= {
init: function() {
wrap = 'hello world';
$('a').on('click', this.read);
...
Because functions have access to all variables visible from their definition scope.
(function() {
var Example= {
init: function() {
this.wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(this.wrap)
}
};
Example.init();
})();
try this: (Fiddle: http://jsfiddle.net/jRJFQ/3/)
(function(){
var Example= {
wrap:null,
init: function() {
this.wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(Example.wrap)
}
};
Example.init();
})();
If you consider using the revealing module pattern you can define which variables are private and which are public like this:
var Example = (function(){
var wrap = 'hello world',
init = function(){
...
},
read = function(){
... // You can use `wrap` here
};
return { // Return public variables and methods
init: init,
read: read
};
})();
Example.init();
yup this should do it:
(function() {
var wrap;
var Example= {
init: function() {
var wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(wrap)
}
};
Example.init();
})();
Related
Where can I accommodate ready function in the name space?
var yourNamespace = yourNamespace || {
foo: function()
{
},
bar: function()
{
}
};
...
yourNamespace.foo();
ready function:
$(function(){
...
});
Here's how I do it:
var MyNamespace = (function(publicAPI) {
var foo = 'I am a private field';
publicAPI.alertFoo = function() {
alert(foo);
};
// DOM ready
$(function() {
$('.test-link').click(function() {
publicAPI.alertFoo();
});
});
return publicAPI;
})(MyNamespace || {});
To call the alertFoo method you would use MyNamespace.alertFoo(); This is a variation of the module pattern. The DOM ready section is used for binding to events.
I am writing some JavaScript code. I am a little confused about this keyword. How do I access logger variable in the dataReceivedHandler function?
MyClass: {
logger: null,
init: function() {
logger = LogFactory.getLogger();
},
loadData: function() {
var dataReceivedHandler = function() {
// how to access the logger variable here?
}
// more stuff
}
};
You can do something like this inside the loadData function to access your object...
MyClass: {
logger: null,
init: function() {
this.logger = LogFactory.getLogger();
},
loadData: function() {
var self = this;
var dataReceivedHandler = function() {
// how to access the logger variable here?
self.logger.log('something');
}
// more stuff
}
};
Assuming loadData is called like so:
MyClass.loadData();
then:
loadData: function() {
var self = this;
var dataReceivedHandler = function() {
self.logger ...
}
// more stuff
}
Because dataReceivedHandler is an anonymous function this will refer to the window object on the global scope. I think of two way you can bypass that.
a) Create a variable inside loadData to hold it's context then use it inside dataReceivedHandler as such:
loadData: function() {
var self = this;
var dataReceivedHandler = function() {
console.log(self.logger);
}
// more stuff
}
b) Change the context of your anonymous function using apply or call.
loadData: function() {
var dataReceivedHandler = function() {
console.log(this.logger);
}
// more stuff
dataReceivedHandler.call(this); // by passing this as the first argument we make sure the context of the excuted function is our current scope's this
}
I prefer option B due to performance and memory usage optimizations, but both would work just fine.
var Foo = (function () {
var foo = function() { };
var privateMethod = function(){ };
foo.prototype = {
init: function() {
console.log(this.privateMethod); //undefined
}
};
return foo;
})();
I know that I can access privateMethod directly without using the this pointer. But since I come from the c# world, I would like to use it for readability purposes.
Is there any way to reference my "private methods" using a pointer?
You can't. You can only use this to refer to "public" methods. If you really want to use a something.method notation, you could use:
var Foo = (function () {
var foo = function() { };
var private = {
privateMethod : function(){ };
}
foo.prototype = {
init: function() {
console.log(private.privateMethod);
}
};
return foo;
})();
privateMethod is not specific to each instance of foo. Just reference it without the this. qualifier—although you probably want to log the results of a function call, not the function itself:
console.log(privateMethod());
Here is a simplified version of my JS:
var myObject = function() {
return {
functionOne: function() {
//some other logic here
},
functionTwo: function() {
var self = this;
//some logic here
//then call functionOne
self.functionOne();
}
};
}
Then I have this in the body of my html:
click me
Why do I get the error Uncaught TypeError: Object [some url] has no method 'functionOne', when I click the link?
The error that you're seeing doesn't reflect the example code you've shown.
That said, in the way that you're using the code, you should be able to reduce it to simply:
var myObject = {
functionOne: function() {
},
functionTwo: function() {
this.functionOne();
}
}
Your myObject is a function that needs to be called in order to get that object
click me
Why not just define myObject as an object:
var myObject = {
functionOne: function() {
//some other logic here
},
functionTwo: function() {
var self = this;
//some logic here
//then call functionOne
self.functionOne();
}
};
What you need is for your function to be executed immediately. Further to that your declarion of the self variable leads me to think that you are trying to create a closure so that you can access functionOne from functionTwo. If that is the case then I think the following is what you were after:
var myObject = (function() {
function func1( ) {
}
function func2( ) {
func1();
}
return {
functionOne: func1,
functionTwo: func2
};
}());
How can I declare a private var inside a literal object? Becasuse I've this code:
var foo = {
self: null,
init: function() {
self = this;
self.doStuff();
},
doStuff: function() {
//stuff here
}
}
This works perfectly, but if I have some objects, the var "self" it will override.. apparently it's a global var.. and I cannot use the restricted word "var" inside this object..
How can I solve this, or make an NameSpace for each object?
Thanks!
You can create a function scope to hide the variable:
var foo = (function() {
var self = null
return {
init: ...,
doStuff: ...
};
})();
Though it is not clear what self is supposed to do here, and how foo is used.
You have to use this:
init: function() {
this.self = this;
this.self.doStuff();
},
edit However, it's still a property of the "foo" object, and it's not super-clear where you're getting instances of "foo" from. In other words, the way your code is written, there's only one object.
Alternatively, you could create your object with a closure:
var foo = function() {
var self = null;
return {
init: function() {
self = this;
self.doStuff();
},
doStuff: function() {
//stuff here
}
};
}();
You are not even using the property that you have created. Instead you create another global variable with the same name. Use the this keyword to access properties:
var foo = {
self: null,
init: function() {
this.self = this;
this.self.doStuff();
},
doStuff: function() {
//stuff here
}
}
(Although saving this in a property is truly pointless...)
If you want a local variable in the object, create a closure for it:
var foo = (function(){
var self = null;
return {
init: function() {
self = this;
self.doStuff();
},
doStuff: function() {
//stuff here
}
};
}());