Passing information between JavaScript methods - javascript

I have an object with two different sets of objects inside:
var myObj;
(function (myObj) {
var myFunction = (function () {
function myFunction(){
this.myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
myObj.myFunction = myFunction;
var myFunction2 = (function () {
function myFunction2() {
}
myFunction2.prototype.something = function () {
var a = myFunction.getValue();
}
return myFunction2;
})();
myObj.myFunction2 = myFunction2;
})(myObj || (myObj = {}));
Every time I run myFunction2.something(), a is assigned: undefined.
How can I get the value from myFunction into myFunction2.something()?

There is quite a mixup of scopes and design patterns in your code. Having 2 functions named the same way on inside the other creates different scopes for that name depending on where you call them. This quickly gets out of control. Like in this part:
var myFunction = (function () { // this guy is named myFunction
function myFunction(){ // this guy is also named myFunction
this.myValue = "something"; // 'this' here most certainly refers to 'window', not myFunction. Unless you do a 'new myFunction()' a la prototype
}
myFunction.getValue = function () {
var _this = this;// same here
return _this.myValue;
}
return myFunction;// here you are returning a function, not an object with methods
})();
Also I noticed that you are handling some logic with prototypes and other with closures, this also is kinda confusing when someone else (or you in a couple of months) need to refactor this code.
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
You could go all prototypes or all closures. I prefer closures so here is what I would do.
var myObj;
(function (myObj) {
// in this closure, we create a scope and return only the public methods
var myFunction = (function () {
// define properties here
var myValue = 'default value';
// define your methods, here we return
// myValue declared on the parent scope
function getValue() {
return myValue;
}
// this acts as a constructor, it autoexecutes
(function init(){
myValue = "something";
})();
// return all the functions in this scope
// you want to expose
return {
getValue: getValue
};
})();
// we then put myFunction into myObj
// at this point myFunction is an object with a method called getValue()
myObj.myFunction = myFunction;
var myFunction2 = (function () {
function something() {
// once this guy is called, we get the value from the other 'class'
var a = myFunction.getValue();
alert(a);// voila!
}
(function myFunction2() {
// do your init stuff here
})();
return {
something: something
};
})();
myObj.myFunction2 = myFunction2;
})(myObj || (myObj = {}));
// at this point myObj is an object with 2 'classes', each 'class' has its own methods
// we can proceed and call the desired method
myObj.myFunction2.something();
Demo: http://jsfiddle.net/bzw9kse7/

I've stepped through your code and just noticed a couple small things you're doing wrong.
You appear to be misdefining myFunction slightly, because it's not going to have myValue as a member variable, just a temporary variable that quickly falls out of scope. (And because it becomes undefined, it gets assigned to a, which is then unassigned).
So, replace these lines:
var myFunction = (function () {
function myFunction(){
var myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
With this:
var myFunction = (function () {
var myFunction = {};
myFunction.myValue = "something";
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();

EDIT Sorry, got this all wrong. It returns undefined because getValue is a static method of myFunction Object, not an instance method. That means that the this is not the same as in myFunction constructor.
Moreover you are not even attaching myValue to the this anywhere...
Edit 2 I added getMyValue to the myFunction prototype.
Try this:
....
var myFunction = (function () {
function myFunction(){
this.myValue = "something";
}
myFunction.prototype.getValue = function () {
return this.myValue;
}
// this creates the instance of the myFunction class.
return new myFunction();
})();
myObj.myFunction = myFunction;
...
// now you should be able to see the right result
var a = myFunction.getValue();
This is one of the craziest code I have ever seen, but the answer is this:
var a = myFunction.getValue(); is undefined because your 2nd definition of myFunction returns undefined, as in here:
function myFunction(){
var myValue = "something";
}
Your 2nd definition of myFunction actually replaces the 1st. See the comments below:
var myFunction = (function () {
// this definition replaces the one above
function myFunction(){
var myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
// which makes this return to not be taking in account when you are
// calling myFunction()
return myFunction;
})();

Related

Access of function in jQuery scope

I want to build a function outside a jQuery scope:
(function($) {
function MyObject() {
console.log('foo');
};
}(jQuery));
var $my_object = new MyObject();
But function MyObject is not accessible :
ReferenceError: MyObject is not defined
However, if i build my function in the scope, it's working:
(function($) {
function MyObject() {
console.log('foo');
};
var $my_object = new MyObject();
}(jQuery));
foo
How access to MyObject outside the scope ?
I would probably not recommend it but you can basically do what you want by returning the functions as part of an object and assigning the IIFE to a variable like this
var library = (function ($) {
var exports = {};
var private = 'see you cant get this';
var MyObject = exports.MyObject = function (_in) {
console.log(_in);
};
var another_func = exports.sum = function (a, b) {
console.log(a + b);
};
return exports;
}(jQuery));
library.MyObject('foobar'); // "foobar"
library.sum(3, 5); // 8
console.log(private); // Uncaught ReferenceError: private is not defined
Although I don't know why you want to do it.. Maybe this helps
// Define Class globally
// window.MyObject also works
var MyObject = (function($) {
// Passes jQuery in
return function () {
console.log('foo');
};
}(jQuery));
var $my_object = new MyObject();

Private Member To Object Containing Function

In javascript, I have an object containing a function and want to add to it a private member.
How can I do that?
function function1 () {
var function2 = function () {
console.log("This is an actual function.");
}
function2.publicMember = 5;
function2.privateMember = 7;
return function2;
}
I want privatMember to be inaccessible to the user of function1.
I found this question but I can't quite translate it to my situation because my object is a function:
How to add private variable to this Javascript object literal snippet?
thanks!
Wrap it into one more function to create new scope (i.e. using iife):
function function1 () {
var function2 = (function(){
var privateMember = 7;
return function () {
privateMember ++; // do something with really private member
console.log("This is an actual function.");
}
})();
function2.publicMember = 5;
return function2;
}
Declare the vars inside the function that needs access to them:
function function1 () {
var publicMember = 5;
var function2 = function () {
var privateMember = 7;
console.log("This is an actual function.");
}
return function2;
}
So function2 can see the vars inside its own closure (privateMember) and any parent scope.

How to access from 'private method' to 'public variable', in Javascript class

First, See my code plz.
function test(){
this.item = 'string';
this.exec = function(){
something();
}
function something(){
console.log(this.item);
console.log('string');
}
}
And I made class and call 'exec function', like this code
var t = new test();
t.exec();
But result is...
undefined
string
I wanna access from something function to test.item.
Have you any solution?
You need to call something with apply so that this is properly set inside of something:
function test(){
this.item = 'string';
this.exec = function(){
something.apply(this);
}
function something(){
console.log(this.item);
console.log('string');
}
}
As #aaronfay pointed out, this happens because this doesn't refer to the object that new test() created. You can read more about it here, but the general rule is:
If a function is invoked on an object, then this refers to that object. If a function is invoked on its own (as is the case in your code), then this refers to the global object, which in the browser is window.
You have many choices, but I recommend the last one.
var item = 'string'
or
this.exec = function(){
something.apply(this, []);
}
or
var that = this;
function something(){
console.log(that.item);
console.log('string');
}
this.item in something() isn't what you think it is.
The this value is different. In this case, it's the global object.
The best solution, in my opinion, is to declare a variable with a reference to this, that can be accessed inside the inner function.
function test() {
var that = this; // a reference to 'this'
function something() {
console.log(that.item); // using the outer 'this'
console.log('string');
}
this.item = 'string';
this.exec = function(){
something();
}
}
Why not just define something like this:
Fiddle
function test(){
this.item = 'string';
this.exec = function(){
this.something();
}
this.something = function(){
console.log(this.item);
console.log('string');
}
}
var t = new test();
t.exec();
// output:
// string
// string

How to extend an object inside an anonymous function

I want to add another function called myFunction() into the CoreTeamObject, which is declared as local inside the anonymous function. Is this possible?
!function ($) {
var CoreTeamObject = function () {
var coreTeamVar1; // ...
this.someState = false; // ...
coreTeamFunction: function () { /* ... */ }
};
}(window.jQuery);
Normally, I'd use prototype with something like:
CoreTeamObject.prototype.myFunction = function(){
return
};
But I simply don't know how to access the object.
You simply can't. Variables within a function are private and cannot be accessed from the outside.
! function () {
var foo = 1;
}();
// Calling `foo` will throw a referenceError here.
// It doesn't even work with classes...
var foo = function () {
var bar = 2;
};
var bax = new foo();
// `bax.bar` doesn't exist.
However, there are workarounds. You could store them in a global variable (bad idea, though):
! function (w) {
w.foo = 3;
}(window);
// window.foo = 3
// foo = 3
Or if you can rewrite it to a class:
var foo = function () {
this.bar = 4;
};
var bax = new foo();
// bax.bar = 4
I hope this helps.

Call jQuery defined function via string

I'd like to call functions I've defined within the document ready function of jQuery, but am having a bit of trouble. I have the following code:
jQuery(document).ready( function($) {
function test1() {
alert('test1');
}
function test2() {
alert('test2');
}
var test_call = '2';
var fn = 'test' + test_call;
// use fn to call test2
});
I don't want to use eval, and window[fn] doesn't seem to be working. The two test functions don't appear to be indices in the window variable. I appreciate the help and knowledge.
All I can think of that doesn't use eval() or some form of eval (passing a string to setTimeout() is a form of eval()), is to register the relevant function names on an object and then look up the function name on that object:
jQuery(document).ready( function($) {
function test1() {
alert('test1');
}
function test2() {
alert('test2');
}
// register functions on an object
var funcList = {};
funcList["test1"] = test1;
funcList["test2"] = test2;
var test_call = '2';
var fn = 'test' + test_call;
if (fn in funcList) {
funcList[fn]();
}
});
or the registration could be done in the definition of the functions. If they were global functions, they would be implicitly registered on the window object, but these are not global as they are scoped inside the document.ready handler function:
jQuery(document).ready( function($) {
var funcList = {};
funcList.test1 = function test1() {
alert('test1');
}
funcList.test2 = function test2() {
alert('test2');
}
var test_call = '2';
var fn = 'test' + test_call;
if (fn in funcList) {
funcList[fn]();
}
});
Or, you could move the functions to the global scope so they are automatically registered with the window object like this:
function test1() {
alert('test1');
}
function test2() {
alert('test2');
}
jQuery(document).ready( function($) {
var test_call = '2';
var fn = 'test' + test_call;
if (fn in window) {
window[fn]();
}
});
The best way, if not Eval, would be to use setTimeout with zero milliseconds, as you can specify the function as a string.
setTimeout('myfunction()',0,);

Categories

Resources