Calling a function from a Object Literal
var runApp = {
init: function(){
this.validate();
},
run: function() {
var myStr = "My Name";
var abc = function()
{
return myStr;
}
},
validate: function() {
var val = this.run().abc(); // It Gives "Uncaught TypeError: Cannot call method 'abc' of undefined "
alert(val);
}
};
runApp.init();
How to Call the function abc() inside the function validate?
Function abc is defined within the scope of "run" on thus will not be accessible from another function. If you really want this, you could make "abc" available on the "this" scope.
var runApp = {
init: function(){
this.validate();
},
run: function() {
var myStr = "My Name";
this.abc = function() {
return myStr;
}
},
validate: function() {
this.run(); // run this one first so function abc exists
var val = this.abc();
alert(val);
}
}
runApp.init();
So in short: you cannot do this without modifying the code itself.
You can return abc function from run function inside an object:
run: function() {
var myStr = "My Name";
var abc = function() {
return myStr;
}
return { abc : abc };
}
and then this.run().abc() will work.
Since your run method does not return an object which contains the abc function you are not able to call it. It returns undefined instead.
One solution to this is if you return an object which has a method named abc.
Related
I have an Javascript object following the Module Pattern
var foo = (function() {
var obj = (function() {
var $button = $('#myButton');
var init = function() {
$button.hide();
};
return {
init: init
};
})();
return { obj: obj };
})();
If I call foo.obj.init(), the button should be hidden, and this does not occur.
I saw different questions here about the assignment of an element to a variable, but I think that the problem is with the object. Can't I access a private variable from a public method?
From my comment:
Do it as part of init... you can just declare the var in order to isolate the scope, and then modify it to actually set the button as part of init
Example:
var foo = (function() {
var obj = (function() {
var $button; //$('#myButton');
var init = function() {
if (typeof $button === 'undefined') {
// i would probably make the selector an argument to `init`
// if i were you.
$button = $('#myButton');
}
$button.hide();
};
return {
init: init
};
})();
return { obj: obj };
})();
I've an object looks like this:
var obj ={
property : '',
myfunction1 : function(parameter){
//do stuff here
}
}
I need to set some private properties and functions, which can not be accessed/seen from outside of the object. It is not working with
var property:, or var myFunction1
Next question is, if I call a function within or outside the object, I always have to do this with obj.myfunction(). I would like to asign "this" to a variable. Like self : this. and call inside the object my functions and variables with self.property and self.myfunction.
How? :)
There are many ways to do this. In short: If dou define a function inside another function, your inner function will be private, as long as you will not provide any reference to if.
(function obj(){
var privateMethod = function() {};
var publicMethod = function() {
privateMethod();
...
};
return {
pubMethod: publicMethod
}
}());
var obj = (function() {
var privateProperty;
var privateFunction = function(value) {
if (value === void 0) {
return privateProperty;
} else {
privateProperty = value;
}
};
var publicMethod = function(value) {
return privateFunction(value);
}
return {
getPrivateProperty: function() {
return privateFunction();
},
setPrivateProperty: function(value) {
privateFunction(value);
}
}
})();
obj.setPrivateProperty(3);
console.log(obj.getPrivateProperty());
// => 3
console.log(obj.privateProperty);
// => undefined
obj.privateFunction();
// => TypeError: undefined is not a function
Use closures. JavaScript has function scope, so you have to use a function.
var obj = function () {
var privateVariable = "test";
function privateFunction() {
return privateVariable;
}
return {
publicFunction: function() { return privateFunction(); }
};
}();
this is my code:
window.myApp= window.myApp|| {};
myApp.jira = (function () {
var getId = function () {
return ...;
}
var init = function() {
var id = myApp.jira.getId();
}
})();
$(document).ready(function () {
myApp.jira.init(); // here jira is null and getting undefined
});
when the page is loaded it says jira is undefined.
Try this:
window.myApp= window.myApp|| {};
// Function here is being immediately invoked. No "return" statement
// in your code is equivalent to "return undefined;".
myApp.jira = (function () {
var getId = function () {
return ...;
}
var init = function() {
var id = myApp.jira.getId();
// Bonus note: you can simplify this:
// var id = getId();
}
// If we return an object with functions we want
// to expose (to be public), it'll work,
return {
init: init,
getId: getId
};
})(); // <-- here you'll invoking this function, so you need return.
$(document).ready(function () {
// Without 'return' above, myApp.jira evaluated to undefined.
myApp.jira.init();
});
Working DEMO
Or you can use object literal pattern instead:
var myApp = {};
myApp.jira = {
getId: function () {
return ...;
},
init: function() {
var id = this.getId();
}
};
How come this doesn't alert "http://127.0.0.1/sendRequest"? (Available at http://jsfiddle.net/Gq8Wd/52/)
var foo = {
sendRequest: function() {
alert(bar.getUrl());
}
};
var bar = {
getUrl: function() {
return 'http://127.0.0.1/' + arguments.callee.caller.name;
}
};
foo.sendRequest();
Putting a value in an object literal, as you're doing, doesn't affect the value at all.
var foo = {
sendRequest: ...
The function value is only affected by the function expression, which doesn't contain a name.
... function() {
alert(bar.getUrl());
}
You need to include the name you want in the function expression itself [fiddle].
var foo = {
sendRequest: function sendRequest() {
If you do this:
var foo = {
sendRequest: function() {
alert(bar.getUrl());
}
};
var bar = {
getUrl: function() {
return arguments.callee;
}
};
foo.sendRequest();
You will notice that the function doesn't have name which is true:
function() {
This is anonymous function.
You can name you method : sendRequest: function myMethodName() {
Although the function is stored under the object property foo.sendRequest, and thus can be invoked via foo.sendRequest(), that function itself doesn't actually have a name. That's why arguments.callee.caller.name is empty.
Because the function that is calling the function being called is an anonymous function (and hence, has no name).
Try:
function sendRequest() {
alert(bar.getUrl());
}
var foo = {
sendRequest: sendRequest
};
var bar = {
getUrl: function() {
return 'http://127.0.0.1/' + arguments.callee.caller.name;
}
};
foo.sendRequest();
I've got a big Javascript project that I'm trying to refactor into pseudo-classes:
jsFiddle: http://jsfiddle.net/waitinforatrain/7T42w/
var MyNameSpace = {}
MyNameSpace.MyClass = function() {
this.doSomething = function () {
return "hello";
}
this.doSomething2 = function() {
var x = this.doSomething() + " world";
alert(x);
}
this.doSomething2(); //Works fine
$("#mydiv").click ( this.doSomething2 ); //Doesn't work
}
var class = new MyNameSpace.MyClass();
The reason the click event causes an error is that this refers to the #mydiv element.
How am I supposed to design the above so that I can access the element that was clicked but can also call doSomething()?
You need to cache the context reference and wrap the call in a closure:
var MyNameSpace = {}
MyNameSpace.MyClass = function() {
var context = this;
context.doSomething = function () {
return "hello";
}
context.doSomething2 = function() {
var x = context.doSomething() + " world";
alert(x);
}
// You can do this:
context.doSomething2();
// Or this:
$("#mydiv").click(function(e) {
context.doSomething2();
});
}
this.doSomething2 = $.proxy(function() {
var x = this.doSomething() + " world";
alert(x);
}, this);
$.proxy binds the this scope to the context variable inside said function.
Save a reference to this in the outer scope:
MyNameSpace.MyClass = function() {
var that = this;
this.doSomething = function () {
return "hello";
}
this.doSomething2 = function() {
var x = that.doSomething() + " world";
alert(x);
}
this.doSomething2(); //Works fine
$("#mydiv").click ( this.doSomething2 ); //Doesn't work
}
The function assigned to doSomething2 is said to "close over" the variables in its lexical scope and so has access to their values even once MyClass has returned. This allows us to access the doSomething method through the reference to the instance we assigned to that.