calling a string as function call in javascript - javascript

What is wrong in this ?? I want to call a string as a function. Could someone please help me on this
var wnameSpace = (function(){
var privateVar = '';
privateVar = "dummyFunction";
dummyFunction = function(){
console.log("hurray dummyFunction called here");
};
return {
publicFunction:function() {
console.log(window[wnameSpace])
}
}
})();
wnameSpace.publicFunction();

Well, you're accessing window[wnameSpace] but I think you meant to use window[privateVar]. Also, you probably meant to invoke the function rather than just log it. Try this:
var wnameSpace = (function(){
var privateVar = "dummyFunction";
dummyFunction = function(){
console.log("hurray dummyFunction called here");
};
return {
publicFunction:function() {
window[privateVar](); // "hurray dummyFunction called here"
}
}
})();
wnameSpace.publicFunction();
However, I wouldn't recommend using this kind of code in production. It's hard to tell what you want, exactly, but I'm pretty sure there is a better way to accomplish it.

var wnameSpace = (function(){
var privateVar = '';
privateVar = "dummyFunction";
dummyFunction = function(){
console.log("hurray dummyFunction called here");
};
return {
publicFunction:function(){
var fn = window[privateVar]; if (typeof fn === "function") fn();
}
}
})();
wnameSpace.publicFunction();
Will also work.. Thank you for all the anwsers

Related

Javascript execution error in Sublime

I am learning JavaScript and this is my 1st week :)
var Module = (function () {
// code
var publicMethod = {};
var privateMethod = function(someStringToBePassed) {
debug("I love USA. "+someStringToBePassed);
}
publicMethod.someFunction = function() {
privateMethod("USA is sexy");
}
return publicMethod;
})();
debug(Module.someFunction());
I am executing this in Sublime. I am seeing the following result.
--> I love USA. USA is sexy
--> undefined
Please explain why I am seeing undefined here.
[Finished in 0.0s]
Please tell me why I am seeing "undefined" in the results
You're not returning anything from someFunction. Try this:
Now someFunction returns the value of privateMethod. privateMethod returns the constructed string.
var Module = (function () {
// code
var publicMethod = {};
var privateMethod = function(someStringToBePassed) {
return "I love USA. "+someStringToBePassed;
}
publicMethod.someFunction = function() {
return privateMethod("USA is sexy");
}
return publicMethod;
})();
debug(Module.someFunction());
var Module = (function () {
//code
var publicMethod = {};
var privateMethod = function(someStringToBePassed) {
return ("I love USA. "+someStringToBePassed);
}
publicMethod.someFunction = function() {
return privateMethod("USA is sexy");
}
return publicMethod;
})();
var sample = Module;
console.log(sample.someFunction())

Extending existing Object to add additional JavaScript Prototype methods

Let's say I have a function like the one below that creates a very simple micro-library:
var microLib = function(selector) {
var el;
var selectorEngine = function(selector)
{
var selector_value = selector.slice(1);
return document.getElementById(selector_value);
};
el = selectorEngine(selector);
Element.prototype.func_1 = function(){
return 'first';
};
Element.prototype.func_2 = function(){
return 'second';
};
return el;
};
window._$ = microLib;
This script will allow me to write code like this:
var elem = _$("#div_with_id"); //some element on my web page
console.log(elem.func_2()); //outputs 'second' in the console
So now, I'm looking for a way to extend _$ in a supplementary piece of code to add additional Element.prototype methods, which will allow me to write:
console.log(elem.func_3()); //to output 'third' in the console
The reason I need to do this is because this extension needs to take place in another JavaScript file, otherwise I would I have just added another method and be done with it.
How can I do this?
Here's an example of the approach that I am suggesting: http://jsfiddle.net/rbxssmx8/.
JS:
var toArray = Function.prototype.call.bind(Array.prototype.slice);
var qAll = document.querySelectorAll.bind(document);
var _$ = (function() {
function dom(selector) {
if(!(this instanceof dom)) {
return new dom(selector);
}
this.elements = toArray(qAll(selector));
}
dom.prototype.iterate = function(func) {
this.elements.forEach(func);
return this;
};
dom.prototype.addClass = function() {
var klasses = arguments;
return this.iterate(function(element) {
element.classList.add.apply(element.classList, klasses);
});
};
dom.extend = function(name, func) {
this.prototype[name] = func;
};
dom.ready = function(func) {
document.addEventListener("DOMContentLoaded", func);
};
return dom;
})();
_$.extend("removeClass", function() {
var klasses = arguments;
return this.iterate(function(element) {
element.classList.remove.apply(element.classList, klasses);
});
});
_$("div").addClass("gray");
var $el = _$("div:last-of-type");
$el.removeClass("gray");
So I read this post on What's wrong with extending the DOM and the alternative suggested by the author was to use Object Wrappers. A quick search on that led me to this post on SO: Using object wrappers to extend the JavaScripts DOM?
Coupled with some insight from #DRD's answer, I updated my code:
(function() {
var microLib = function (selector){
return new Dom(selector);
};
function Dom(selector)
{
var selector_value = selector.slice(1);
this.element = document.getElementById(selector_value);
}
Dom.prototype.func_1 = function(){
return 'first';
};
Dom.prototype.func_2 = function(){
return 'second';
};
microLib.extend = function(name, func){
Dom.prototype[name] = func;
};
window._$ = microLib;
})();
And then whenever you want to extend and add another function, do this afterwards:
_$.extend('func_3', function(){ //this is inline with my earlier question
return 'third';
});
Works like a charm! And definitely the safer option compared to extending Element.prototype.

JavaScript - What is the best method when creating chainable functions?

EDIT
Here is an attempt to make my question simpler.
return this.someFunc(); == return { XXX:this.someFunc() };
What do I have to put in for XXX to make this statement true?
I'm trying to create a function that can be chained. Let me write some hypothetical code. (Any syntax errors just ignore, I'm typing this fast and this is just concept code.) Assume that all functions are either defined locally or globally. :)
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
return this.someFunc();
}
This function allows me to chain: test().retest();
But what I want to do is return more than one item.
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
return { XXX:this.someFunc(), //What do I put for XXX
next:this };
}
I want to do this to access another function that test() offers: test().next.someFunc2();
So my problem is this:
I still want to be able to chain like this: test().retest();
But I have to do it like this: test().XXX.retest();
In my code, what is the name that I can put instead of XXX to accomplish this? And is this even possible? I have tried 0 and default already. Thanks for the help.
You can make a chainable functions like this:
var test = function(){
var self = {};
console.log('test called')
function someFunc() {
console.log('someFunc')
return self;
}
function someOtherFunc() {
console.log('someOtherFunc')
return self;
}
self.someFunc = someFunc;
self.someOtherFunc = someOtherFunc;
return self;
}
test().someFunc().someOtherFunc();
Hope this helps
function test() {
// when test() is called as a regular function
// it's `this` will be `undefined` (in strict mode) or will refer to a global object
// when test() is called with `new` operator
// it's `this` will be an instance of `test` object
if(!(this instanceof test)) {
// create a new object
return new test();
}
else {
// this is a `new object` creation
console.log('new Test created');
}
}
// declare functions which will be accessible on test object
test.prototype.someFunc = function() {
console.log('someFunc');
return this;
};
test.prototype.someFunc2 = function() {
console.log('someFunc2');
return this;
};
// declare a `chaining` function - will create a new `test` object
test.prototype.test = function() {
return new test(); // new instance will be created
};
With this code you are now able to run the following code
test().someFunc().someFunc2().test().someFunc().someFunc().test().test()
The following string will be written at the console
new Test created
someFunc
someFunc2
new Test created
someFunc
someFunc
new Test created
new Test created
you have a scope problem -- you can't refer to the _NAME "test" in the function, because you don't know, how it's called.
if you do it statically, you just can do:
test = function(){
this.someFunc = function(){ // blaaa
};
//...code
return {
OUTPUT: this.someFunc(), //What do I put for XXX
test: this
};
}
will result into:
test().test().test().test().OUTPUT (or something like this)
Okay, so I think I understand your question, but I'm not sure (and it's super late at night here, so give me some credit on that). I think you want to have behavior like this:
test(); //is ["result1"]
test().retest(); //is ["result1", "result2"]
test().retest().retest(); //is ["result1", "result2", "result3"]
You might want to return objects instead of strings, but it's the same general idea. And the code turns out to be pretty simple:
var test = (function() {
var results = ["result1"],
i = 1;
results.retest = (function() {
results.push("result" + (++i));
return results;
});
return results;
});
test(); //is ["result1"]
test().retest(); //is ["result1", "result2"]
test().retest().retest(); //is ["result1", "result2", "result3"]
Not sure if that's what you're looking for, but maybe it gets you on the right track.
test = function(){
var someFunc = function(){
//...code
}
return {
someFunc:someFunc,
next:this
}
}
EDIT - Updated to reflect your question update, for clarity.
Do this
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
var ret = this.somefunc();
ret.next = this;
return ret;
}
EDIT: Here's a better, functioning, version
test = function(){
var ret;
var func = function() {
console.log("test func");
}
ret = function(){
func();
return ret;
}
ret.test = ret;
ret.next = ret; // You can define an arbitrary number of members here
ret.XXX = func(); // Like this, and you can still chain it like your question
return ret;
}
Not sure what your intention is, but this would be a chainable Test function:
function Test(){
Test.retest = Test.retest || function(){console.log('retested'); return Test;}
return Test;
}
Test().retest().retest().retest().retest();
/* => result
retested
retested
retested
retested
*/
// and
log(Test() === Test); //=> true
Since your example does not work the way you posted it I suppose you meant following:
test = function(){
this.someFunc = function(){
this.retest = function(){
//...code
}
//...code
}
this.someFunc2 = function(){
//...code
}
return new this.someFunc();
}
Mind the new in the return.
Now, to still be able to chain your functions you have to return this:
return {retest: new this.someFunc().retest, next:this};
Doing so will then allow you to call test().retest();
I hope this helps.

Javascript: Acceptable way to referencing `this` from given two snippets

var me = null;
var testFn = (function() {
me = this;
return {
me1: me,
fn1 : function() {
me = this;
return {
me2 : me,
fn2 : function() {
me = this;
return {
me3: me
}
}
}
}
}
})();
OR:
var testFn = (function() {
var me = this;
return {
me1: me,
fn1 : function() {
var me = this;
return {
me2 : me,
fn2 : function() {
var me = this;
return {
me3: me
}
}
}
}
}
})();
Between two segments given above, which one is best way to referencing this. Is there any other way best, please suggest.
Thanks.....
I would recommend using the second approach because me is declared inside a closure so iot doesn't pollute context where it is not needed. It is also clearer to which context me belongs too.
I prefer the second one, as it is destroyed when the this is, which makes more sense (they're in the same scope).
Not entirely related, but most people call the variable that: e.g. var that = this;

jQuery type function as a variable

can I create a variable that is a function of this type:
jQuery.fn.appendValueToTextArea = function(txt){
return this.each(function(){
this.value += txt;
});
};
?
I tried putting a var in front of it but I get a error.
If you want to call a method on an element like you wrote in the comment, you definitely have to extend jQuery.func.
Maybe you just want to store the name in a variable?
var name = 'appendValueToTextArea';
element[name]('text');
The only other way is to store a reference to the function and use .call() or .apply():
var func = jQuery.fn.appendValueToTextArea = function(txt) {
// ...
};
func.call(element, 'text');
Or (as I am not sure what you really want) you can assign the function to a variable first and then assign it to jQuery.fn.appendValueToTextArea:
var func = function(txt) {
// ...
};
jQuery.fn.appendValueToTextArea = func;
What happens if you define the variable after the function has been defined?
i.e.
jQuery.fn.appendValueToTextArea = function(txt){
return this.each(function(){
this.value += txt;
});
};
var fn = jQuery.fn.appendValueToTextArea;
jQuery.fn.appendValueToTextArea = function(txt){
return this.each(function(){
this.value += txt;
});
};
//This would put the function above in a variable.
//However, I'm not exactly sure what this gains you
var myfunction = jQuery.fn.appendValueToTextArea;

Categories

Resources