How to access public property of parent function in javascript? - javascript

I am trying to write some javascript functions for a web application.
Following the advice from here: How do I declare a namespace in JavaScript?
I am trying to make the code unobtrusive by wrapping everything in named functions, however I am running into difficulty accessing properties in the parent function when inside a child anonymous function.
For example:
var title_picker = new function(){
// This property should be public
this.callback=function(){};
var ok=function(){
var title = $('input#title').val();
callback(title) // <---
}
...
When inside the "ok" function, what is the best way to reference the "callback" property?

With the code as written, no there isn't.
You can access variables from the scope of the parent, unless they are overwritten in the narrower scope.
this is always overwritten.
You can copy this to another variable that remains in scope though:
var title_picker = new function(){
var self = this; // Copy this to a variable that stays in scope
// This property should be public
this.callback = function(){};
var ok=function(){
var title = $('input#title').val();
self.callback(title) // self is still in scope
}
...

Perhaps something like this:
var title_picker = new function(){
// This property should be public
this.callback=function(){};
var that = this;
var ok=function(){
var title = $('input#title').val();
that.callback(title) // <---
}
...
Though there are many frameworks that do this kind of thing for you (yui, dojo, prototype...)

Related

javascript typeerror it's not a constructor

There is a javascript file with require js framework
init: function(){
var self = this;
self.commonSolutionManager = new solution.CommonSolutionManager();
},
I am creating jasmine test cases for testing the above code . I am creating an object for the above file with this constructor
function solution()
{
CommonSolutionManager = function(){};
}
but it's throwing error "TypeError: solution.CommonSolutionManager is not a constructor"
This block of code places your constructor inside a closure which scopes the constructor to ONLY be accessible with in the closure.
function solution()
{
CommonSolutionManager = function(){};
}
This block of code tries to access the constructor as if it where a property of solution; but it's not, it's more like a private variable with in the solution function.
self.commonSolutionManager = new solution.CommonSolutionManag();
You probably wanted your constructor to be defined in the following way.
// create the solution object and store it in the global namespace
solution = window.solution || {};
// create the constructor
solution.CommonSolutionManag = function() {};
// now you can use the constructor
var csm = new solution.CommonSolutionManag();
NOTE: If you're using requireJS, then this probably isn't the approach you want to take. See RequireJS: How to define a constructor?
You're using solution as an object but it's a function. Not clear on how it should work but the following should fix the problem:
var solution = new function() {
this.CommonSolutionManager = function(){};
}
And you can then use new solution.CommonSolutionManager()

MooTools get Classname in Class (not CSS)?

I'm using the JavaScript Framework MooTools in which it is possible to create classes similar to Object-Orientation.
I dont know if it is somehow possible to alert the classname 'TestClass' within the class.
var TestClass = new Class({
Extends: Module,
initialize: function() {
//constructor which is called and should alert the Classname itself
alert(this.classname); (pseudocode)
}
});
Someone has an idea?
Thx in advance!
This is pretty easy as a workaround but a Class can be anonymous (like a function) and reflection is meaningless then.
Compare the(a) host object's enumerables with the instance's constructor. Not a cheap thing but still. Won't work very well if you use deep namespaces, for example: window.App.admin.controllers.view.Login since you'd need to either recursively look for it or know it's hosted by window.App.admin.controllers.view
// define the class in the current scope / global object
this.foo = new Class();
// directly into scope
var Foo = new Class();
// define the class in a namespace
var namespace = {
bar: new Class()
};
// get the variable class name we need to use from any source into a variable...
var dynamic = 'foo';
// make the instances
var instance1 = new this[dynamic]();
var instance2 = new namespace.bar();
var instance3 = new Foo();
function getClassNameOfInstance(mootoolsClassInstance, context) {
// query the context (this or custom object) for the instance we are working with
return Object.keyOf(context || this, mootoolsClassInstance.constructor);
}
// use it on the global object
console.log("instance1 is: ", getClassNameOfInstance(instance1)); // foo
// use it on the namespace object
console.log("instance2 is: ", getClassNameOfInstance(instance2, namespace)); // foo
// use it on the current scope.
console.log("instance3 is: ", getClassNameOfInstance.call(this, instance3)); // Foo
see it work here: http://jsfiddle.net/dimitar/c8pR4/
here is an example anonymous Class, a useful pattern if you don't plan on instantiating something more than once:
var instance = new (new Class({ ... }))(args);
I did write about this a while ago - http://fragged.org/working-with-dynamic-class-names-in-mootools_1395.html
A better / more sensible approach will be to manually give IDs to all Classes that need them, eg:
var Request.CORS = new Class('Request.CORS', { ... });
var i = new Request.CORS();
i.$className; // 'Request.CORS'
this is a pattern common in AMD (define('id', [deps], fn)), DOJO (declare('id', [deps], obj)) etc.
To extend your MooTools to support that you could do something like this:
http://jsfiddle.net/rnbW6/5/ - which will add a Request.JSON.prototype.$className property or getter (via Object.defineProperty config if avail).
If you go that route, you can even do a Class factory so your dependency resolution can be like Class.require('Request.CORS') and you won't ever need to save your definitions into global variables outside of the reference in your Class closure.

Is this a good structure for my jQuery scripts?

I want to keep my scripts organized in one .js file for all my site (I have a mess right now), something like namespaces and classes in C#...
(function ($) {
//private variables
$.divref = $("#divReference");
//Namespaces
window.MySite = {};
window.MySite.Home = {};
window.MySite.Contact = {};
//Public function / method
window.MySite.Home.Init = function(params){
alert("Init");
MySite.Home.PrivateFunction();
$.divref.click(function(){
alert("click");
});
};
//private function / method
MySite.Home.PrivateFunction = function(){
alert("Private");
};
})(jQuery);
Is this an idiomatic layout in jQuery and JScript?
I'll go ahead and post my comment as an answer, though I'm not 100% it addresses your questions about c# namespaces and their parallels in JavaScript (I'm no c# programmer). You're not actually creating private variables because you're attaching them to the $ Object that will exist after this function finishes. If you want private variables you need to use a closure. Those look something like this:
var myObject = function () {
var innerVariable = 'some private value';
return {
getter: function () {
return innerVariable;
}
}
}()
If you attempt to access myObject.innerVariable it will return undefined but if you call myObject.getter() it will return the value correctly. This concept is one you will want to read up on in JavaScript, and for programming in general. Hope that helps.
This is more how I would implement the pattern you are trying to do:
// MySite.Home Extension
window.MySite =
(function ($, root) {
//private variables
var $divref = $("#divReference");
//private function / method
var privateFunction = function(){
alert("Private");
};
root.Home = {};
// Public variable
root.Home.prop = "Click"
//Public function / method
root.Home.Init = function(params){
alert("Init");
private();
$divref.click(function(){
alert(root.Home.prop);
});
};
return root;
})(jQuery, window.MySite || {} );
// MySite.Contact Extension
window.MySite =
(function ($, root) {
root.Contact = {};
// More stuff for contact
return root;
})(jQuery, window.MySite || {} );
The first change is splitting each "namespace" into its own Module pattern, so private variables wont bleed from namespace to namespace (if you do intend them to be private to the namespace, which would be more C# esque). Second is rather than accessing window.MySite, pass in the object that you want to extend (in this case I'm calling it root). This will give you some flexibility.
Your private methods weren't really private. To make a private method, you just want to make a function var that it bound in the closure, but not assigned to a property on the externally visible object. Lastly, you probably don't want to use $.somegarbage. Like mentioned in a comment, you are adding a property to the $ object, which will still be there when the closure is done. If you wanted something close, I would just use $somegarbage which some people seem to like to do, but any variable name will work for private variables, just as long as the variable is bound in the closures scope (not somewhere else)
You are on the right track...
you might want to read up on the Module pattern (more) and closures in javascript to prevent polluting the global namespace.

accessing my public methods from within my namespace

I am in the process of making my own namespace in JavaScript...
(function(window){
(function(){
var myNamespace = {
somePublicMethod: function(){
},
anotherPublicMethod: function(){
}
}
return (window.myNamespace = window.my = myNamespace)
}());
})(window);
I'm new to these kinds of advanced JavaScript techniques and i'm trying to figure out the best way to call public methods from within my namespace. It appears that within my public methods this is being set to myNamespace.
Should I call public methods like...
AnotherPublicMethod: function(){
this.somePublicMethod()
}
or...
AnotherPublicMethod: function(){
my.somePublicMethod();
}
is there any difference?
The way I see it, if you use this you're using a direct reference to the object, whereas if you use my, the interpreter would need to traverse the scope chain until it finds my as a property of window.
But there may be arguments the other way as well.
EDIT:
I should note that since this is determined by how the function is called, it would require that the Activation object be that object.
So this would work:
my.anotherPublicMethod();
But this would not:
var test = my.anotherPublicMethod;
test();
If that's a possibility, then you should use my, or some other direct reference to the object. You could reduce the scope chain traversal by maintaining a reference to the object. Your myNamespace variable should work.
A little off topic, but I'd also note that your code won't work the way it is.
This line:
return (window.myNamespace = window.my = myNamespace)
...doesn't have access to the myNamespace variable.
Perhaps you meant something more like this?
(function(window){
window.myNamespace = window.my = (function(){
var myNamespace = {
somePublicMethod: function(){
},
anotherPublicMethod: function(){
}
}
return myNamespace;
}());
})(window);

Javascript: Access the right scope "under" apply(...)

This is a very old problem, but I cannot seem to get my head around the other solutions presented here.
I have an object
function ObjA() {
var a = 1;
this.methodA = function() {
alert(a);
}
}
which is instantiated like
var myObjA = new ObjA();
Later on, I assign my methodA as a handler function in an external Javascript Framework, which invokes it using the apply(...) method.
When the external framework executes my methodA, this belongs to the framework function invoking my method.
Since I cannot change how my method is called, how do I regain access to the private variable a?
My research tells me, that closures might be what I'm looking for.
You already have a closure. When methodA is called the access to a will work fine.
Object properties are a different thing to scopes. You're using scopes to implement something that behaves a bit like ‘private members’ in other languages, but a is a local variable in the parent scope, and not a member of myObjA (private or otherwise). Having a function like methodA retain access to the variables in its parent scope is what a ‘closure’ means.
Which scopes you can access is fixed: you can always access variables in your parent scopes however you're called back, and you can't call a function with different scopes to those it had when it was defined.
Since a is not a property of this, it doesn't matter that this is not preserved when calling you back. If you do need to get the correct this then yes, you will need some more work, either using another closure over myObjA itself:
onclick= function() { myObjA.methodA(); };
or using Function#bind:
onclick= myObjA.methodA.bind(myObjA);
yes, you're right. Instead of a method reference
var myObjA = new ObjA();
libraryCallback = myObjA.methodA
pass a closure
libraryCallback = function() { myObjA.methodA() }
If you are using jQuery javascript framework, easiest way is to use proxy:
$('a').click($.proxy(myObjA, 'methodA'));
I'd do this:
function ObjA() {
this.a = 1;
this.methodA = function() {
alert(this.a);
}
}
function bindMethod(f, o) {
return function(){
return f.apply(o, arguments);
}
}
var myObjA = new ObjA();
myObjA.methodA = bindMethod(myObjA.methodA, myObjA);
...
Where bindMethod binds the methodA method to always be a method of myObjA while still passing on any arguments which function() {myObjA.methodA()} doesn't do.

Categories