I've got an enclosed function in JavaScript like so:
var myFunction = function (options) {
function blah() {
var blahString = options.blahString;
//more blah
}
function blah2() {
//blah2
}
return {
blah : function { return blah(); },
blah2 : function { return blah2(); }
}
};
When I'm in my HTML, I'm trying to call myFunction.blah() and it's telling me the object has no method 'blah'.
How do I access the returned functions in the global scope?
Thanks!
This just explains why it doesn't work and how to make it work. For learning things this would be enough. Actually you should explain what you are trying to achieve so that others can guide you in the right direction.
// A scope of a function is activated ONLY when it is invoked
// Let us define a function
var myFunction = function (options) {
function blah() {
alert("I am blah");
}
function blah2() {
//blah2
}
alert("I am active now and I am returning an object");
return {
blah: function () {
return blah();
},
blah2: function () {
return blah2();
}
};
};
myFunction.blah3 = function () {
alert("I am blah3");
};
// myFunction is not invoked, but justed used as an identifier.
// It doesn't have a method blah and gives error
myFunction.blah();
// blah3 is a static method of myFunction and can be accessed direclty using myFunction
myFunction.blah3();
// myFunction is invoked, which returns an object
// it contains the function blah
myFunction().blah();
// or
var myObject = myFunction();
myObject.blah();
myObject.blah2();
var myFunction = (function (options) {
function blah() {
return options.a;
}
function blah2() {
//blah2
}
return {
blah: function() { return blah(); },
blah2: function() { return blah2(); }
};
});
alert(myFunction({a:1, b:2}).blah());
This works fine. Note blah: function <-- needs ()
see http://jsfiddle.net/kw6fJ/1
Related
Let's say I have a function made up of private and public methods, like this:
(function () {
var private_var = "hey";
function private_function () {
// stuff
}
stuff = {
public_var: "hey",
public_function: function () {
// this can be called from the outside with no prob.
},
do_this_now_and_later: (function dothis() {
// i could call this from the namespace "dothis()"
// but not the method name, stuff.do_this_now_and_later()
})()
}
})(window.load = window.load || {});
i want to execute the function do_this_now_and_later() as soon as it's rendered, but again later as well.
if i wrote this example code correctly, one should be able to call that function by the namespace dothis(), but is it possible to call that function by its method?
Try to return dothis() in your function.
(function () {
var private_var = "hey";
function private_function () {
// stuff
}
stuff = {
public_var: "hey",
public_function: function () {
// this can be called from the outside with no prob.
},
do_this_now_and_later: (function dothis(v) {
alert(v);
return dothis;
// i could call this from the namespace "dothis()"
// but not the method name, stuff.do_this_now_and_later()
})('foo')
}
stuff.do_this_now_and_later('bar');
})(window.load = window.load || {});
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
};
}());
I have the following piece of code:
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
}
Is there any way I can call the validate() function outside the initValidation() function? I've tried calling validate() but I think it's only visible inside the parent function.
function initValidation()
{
// irrelevant code here
function validate(_block){
console.log( "test", _block );
}
initValidation.validate = validate;
}
initValidation();
initValidation.validate( "hello" );
//test hello
Hope that you are looking for something like this
function initValidation()
{
// irrelevant code here
this.validate = function(_block){
// code here
}
}
var fCall = new initValidation()
fCall.validate(param);
This will work.
Hope this addresses your problem.
You can call validate from within initValidation. Like this.
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
return validate(someVar);
}
validate is not visible to anything outside of initValidation because of its scope.
Edit: Here's my suggestion of a solution.
(function() {
function validate(_block){
// code here
}
function initValidation()
{
// irrelevant code here
return validate(someVar);
}
function otherFunctions() {
// ...
}
// initValidation = function
}());
// initValidation = undefined
All of your functions will be hidden to anything outside the function wrapper but can all see each other.
This invocation will return function statement, which is function validate.
So you can invoke directly after the first invocation.
function initValidation() {
// irrelevant code here
return function validate(_block) {
// code here
}
}
initValidation()();
I know this is an old post but if you wish to create a set of instances that you wish to work with that reuse the code you could do something like this:
"use strict";
// this is derived from several posts here on SO and ultimately John Resig
function makeClassStrict() {
var isInternal, instance;
var constructor = function(args) {
if (this instanceof constructor) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
instance = new constructor(arguments);
isInternal = false;
return instance;
}
};
return constructor;
}
var MyClass = makeClassStrict();// create "class"
MyClass.prototype.init = function(employeeName, isWorking) {
var defaultName = 'notbob';
this.name = employeeName ? employeeName : defaultName;
this.working = !!isWorking;
this.internalValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
};
MyClass.prototype.getName = function() {
return this.name
};
MyClass.prototype.protoValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
var instanceBob = MyClass("Bob", true);// create instance
var instanceFred = MyClass("Fred", false);// create instance
var mything = instanceFred.internalValidate();// call instance function
console.log(mything.check + ":" + mything.who);
var myBobthing = instanceBob.protoValidate();
console.log(myBobthing.check + ":" + myBobthing.who);
I know this thread's been here for quite some time but I thought I'd also leave my 0.02$ on how to call inner functions from outside their scope (might benefit somebody).
Note that in any place, a better design decision should be taken into consideration rather than some hackish workaround which will bite you back later.
How about using function expressions instead of function statements and making use of the global scope.
var innerFn;
function outerFn() {
innerFn = function(number) {
return number ** 2;
}
}
outerFn();
console.log(innerFn(5));
// if there's more complex code around and you could write this defensively
if (typeof innerFn !== 'undefined') {
console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
} else {
console.log('function is undefined');
}
Or, you can make use of closures:
function outer() {
// initialize some parameters, do a bunch of stuff
let x = 5, y = 10;
function inner() {
// keeps references alive to all arguments and parameters in all scopes it references
return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
}
return inner;
}
innerFn = outer(); // get a reference to the inner function which you can call from outside
console.log(innerFn());
Create a variable outside the parent function, then in the parent function store your required function in the variable.
Var Store;
Function blah() {
Function needed() {
#
}
Store = needed;
}
As a minor variation of Esailija's answer, I did this:
function createTree(somearg) {
function validate(_block) {
console.log( "test", _block );
}
if (somearg==="validate") { return validate; } // for addNodes
// normal invocation code here
validate(somearg);
}
function addNodes() {
const validate = createTree("validate");
//...
validate( "hello" );
}
createTree("create");
addNodes();
//validate("illegal");
so validate() is now perfectly shared between createTree() and addNodes(), and perfectly invisible to the outside world.
Should work.
function initValudation() {
validate();
function validate() {
}
}
Function definition:
function initValidation() {
// code here
function validate(_block){
// code here
console.log(_block);
}
return validate;
}
Call it as below:
initValidation()("hello");
function initValidation()
{
function validate(_block){
console.log(_block)
// code here
}
// you have to call nested function
validate("Its Work")
}
// call initValidation function
initValidation()
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'm having trouble figuring out why the following is not working:
My custom JS library
(function ($, undefined) {
var expenses = expenses || {};
expenses.report = function () {
var deleteReport = function () {
alert('test');
};
return {
deleteReport: deleteReport
};
};
window.expenses = expenses;
})(jQuery);
How I am calling it on the page:
$(function() { expenses.report.deleteReport() };
The error:
Uncaught TypeError: Object function () {
var deleteReport = function () {
alert('test');
};
return {
deleteReport: deleteReport
};
} has no method 'deleteReport'
I'm still familiarizing myself with javascript and jquery so I'm sure there is something simple in the design that I am leaving out. I just can't figure out what it is.
expenses.report
is a function.
expenses.report()
is the return value of that function, which is the object you defined here:
{
deleteReport: deleteReport
};
So if you want to call deleteReport, you need to go like this:
expenses.report().deleteReport()
Currently, expenses.report is a function, which returns an object with a deleteReport method:
expenses.report().deleteReport();
If you instead wanted expenses.report.deleteReport(), you have a few options:
1) Change the function to auto-execute and return the object right away.
expenses.report = (function () {
var deleteReport = function () {
alert('test');
};
return {
deleteReport: deleteReport
};
})();
2) Set the object and function directly if you don't really need the closure or deleteReport as a separate variable.
expenses.report = {
deleteReport: function () {
alert('test');
}
};
expenses.report is a function that returns an object when executed. Since it is never executed, the object containing deleteReport does not exist. I would make your expenses.report function self invoking, ie:
expenses.report = (function () {
var deleteReport = function () {
alert('test');
};
return {
deleteReport: deleteReport
};
})();
now you will be able to call expenses.report.deleteReport()