passing JSON with functions via AJAX - javascript

Quite simply, I'd like to "re-hydrate" functions which are passed from AJAX, as follows:
//AJAX response:
{"foo":"bar","baz":"function(){console.log('I am back working as a function!');}"}
And obviously, baz should be a function and not a string. How would I do this?

As Jozef already suggested you can use eval().
But, if you go through Google you will see that the use of that function is NOT recommended:
https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
When is JavaScript's eval() not evil?
https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
Why is using the JavaScript eval function a bad idea?
As this blog suggests (http://2ality.com/2014/01/eval.html) I would recommend you, to use this:
let json = {"foo":"bar","baz":"function(){console.log('I am back working as a function!');}"};
let func = new Function("console.log('I am back working as a function!');");
func();
If you don't have the possibility to change your json you can simply use str.replace().
Please keep in mind that arbitrary code could be executed!
I would strongly recommend that you do e.g. sth. like this instead of just responding with a function. By doing the following you would do some sort of whitelisting. So, no matter if the http-response has been manipulated, the attacker can only execute the pre-defined javascript functions.
function func1() {
console.log('I am back working as a function!');
}
function func2() {
console.log('another code block');
}
let json = {"foo":"bar","baz":"1"};
switch(json.baz) {
case "1": func1();break;
case "2": func2();break;
default: console.error("Invalid response");
}
I hope this helps.

It's possible, but of course we must use the evil eval .. use at your own risk!!
var ajaxResponse = {"foo":"bar","baz":"function(){console.log('I am back working as a function!')}", "lambda": "() => console.log('Hello i\\'m a lambda')"};
function isAFunction(v) {
try {
eval("var f = " + v);
return typeof f === "function";
} catch (e) {
return false;
}
}
var result = Object.entries(ajaxResponse).reduce((obj, [key,value]) => {
if (isAFunction(value)) {
eval("obj[key] = " + value);
} else {
obj[key] = value;
}
return obj;
}, {});
result.baz();
result.lambda();

Related

Async function not working

I'm using redis using node (node_redis module) and am trying to wrap my retrieval code for debugging and DRY, and having trouble understanding why the following function isnt' working.
I am a bit new to more than basic async with javascript, so I don't think this has anything to do with anything other than bad js.
This works fine but having a wrapper is pretty pointless:
// wrapper
function asyncLoad(className, id, callback) {
redisClient.hget(className, id, callback);
}
// execution
asyncLoad('Person',1234,function(err,res) {
if (err) {
console.log(err);
} else {
var obj = JSON.parse(res);
console.log(obj);
}
});
I thought it would be useful for debugging and repetition if I could do this, but I'm definitely doing something wrong...
// wrapper
function asyncLoad2(className, id, callback) {
redisClient.hget(className, id, function(err,res,callback) {
console.log(callback);
if (err) {
console.log(err);
} else {
var obj = JSON.parse(res);
callback(obj);
}
});
}
// execution
asyncLoad2('Person',1234,function(obj) {
//simpler way to get back a parsed object with error handling already done
}
Thanks in advance!
PS - I'm aware that this is really lame error handling; I'm not expecting to use it all the time, just for select things and especially during debugging.
function asyncLoad2(className, id, callback) {
redisClient.hget(className, id, function(err,res,callback) {
Here you expect the redisClient to pass you the callback - but it doesn't, it just will pass the two err and res arguments. The callback parameter shadows the callback variable from the asyncLoad2 function, you will not be able to access it. Remove the parameter:
function asyncLoad2(className, id, callback) {
redisClient.hget(className, id, function(err,res) {
// now refer to the actual `callback` that was passed into `asyncLoad2`
For reference, here's the final function; error logging is automatic and you can do something else with the errors if you want, and you always get back a parsed hash, which is nice DRY:
// wrapper
function asyncLoad(className, id, callback) {
redisClient.hget(className, id, function(e,r) {
if (e || !r) {
console.log('Error retrieving from database: ');
console.log(e);
callback(e,r);
} else {
var parsed = JSON.parse(r);
callback(e,parsed);
}
});
}
// use
asyncLoad('Person',1234, function(e,r) {
if (e) {
// do something besides just log
} else {
// the rest of your stuff here
}
});
And I even figured I could metaprogram reconstruction of the full object (since jsonified strings lack prototypes or functions), although this technique relies on the way I've written (and thoroughly tested!) my constructors and should be used extremely carefully:
...
var parsed = JSON.parse(r);
var obj = reconstructObj(className, parsed);
callback(e,obj);
...
function reconstructObj(className,hash) {
//instantiate a new object of the correct class
var obj = eval('new ' + className + '()');
//overwrite the properties from the hash values
for (prop in hash) {
obj[prop] = hash[prop];
}
return obj;
}

Need to run alert a string using javascript code

I want to alert is it executed well? after following line is executed in javascript
window["is"]("it")("executed")("well")("?")
window here means a global object. I have no idea what that above line is in javascript.
window.is = function(it){
return function(executed){
return function(well){
return function(questionMark){
alert("is "+it+" "+executed+" "+well+" "+questionMark);
}
}
}
}
window["is"]("it")("executed")("well")("?")​
strange question. there's probably a more efficient way of doing it...
demo: http://jsfiddle.net/jd3uM/
Evil recursion :)
arguments.callee refers to the function you are currently calling.
window.is = (function(len){
var buffer = ["is"];
return function(str) {
buffer.push(str);
if(buffer.length === len) {
alert(buffer.join(" "));
}
else {
return arguments.callee;
}
}
}(5));
http://jsfiddle.net/tarabyte/wf8ag/
The following works, although I can't think of any possible use for something that ugly.
window["is"] = function (it) {
return function (executed) {
return function (well) {
return function (questionMark) {
alert("is " + it + " " + executed + " " + well + questionMark);
}
}
}
}
The first thing is to add the is element to the window array (oh my…) and then keep returning functions that will be called.

Is there any possibility to have JSON.stringify preserve functions?

Take this object:
x = {
"key1": "xxx",
"key2": function(){return this.key1}
}
If I do this:
y = JSON.parse( JSON.stringify(x) );
Then y will return { "key1": "xxx" }. Is there anything one could do to transfer functions via stringify? Creating an object with attached functions is possible with the "ye goode olde eval()", but whats with packing it?
json-stringify-function is a similar post to this one.
A snippet discovered via that post may be useful to anyone stumbling across this answer. It works by making use of the replacer parameter in JSON.stringify and the reviver parameter in JSON.parse.
More specifically, when a value happens to be of type function, .toString() is called on it via the replacer. When it comes time to parse, eval() is performed via the reviver when a function is present in string form.
var JSONfn;
if (!JSONfn) {
JSONfn = {};
}
(function () {
JSONfn.stringify = function(obj) {
return JSON.stringify(obj,function(key, value){
return (typeof value === 'function' ) ? value.toString() : value;
});
}
JSONfn.parse = function(str) {
return JSON.parse(str,function(key, value){
if(typeof value != 'string') return value;
return ( value.substring(0,8) == 'function') ? eval('('+value+')') : value;
});
}
}());
Code Snippet taken from Vadim Kiryukhin's JSONfn.js or see documentation at Home Page
I've had a similar requirement lately. To be clear, the output looks like JSON but in fact is just javascript.
JSON.stringify works well in most cases, but "fails" with functions.
I got it working with a few tricks:
make use of replacer (2nd parameter of JSON.stringify())
use func.toString() to get the JS code for a function
remember which functions have been stringified and replace them directly in the result
And here's how it looks like:
// our source data
const source = {
"aaa": 123,
"bbb": function (c) {
// do something
return c + 1;
}
};
// keep a list of serialized functions
const functions = [];
// json replacer - returns a placeholder for functions
const jsonReplacer = function (key, val) {
if (typeof val === 'function') {
functions.push(val.toString());
return "{func_" + (functions.length - 1) + "}";
}
return val;
};
// regex replacer - replaces placeholders with functions
const funcReplacer = function (match, id) {
return functions[id];
};
const result = JSON
.stringify(source, jsonReplacer) // generate json with placeholders
.replace(/"\{func_(\d+)\}"/g, funcReplacer); // replace placeholders with functions
// show the result
document.body.innerText = result;
body { white-space: pre-wrap; font-family: monospace; }
Important: Be careful about the placeholder format - make sure it's not too generic. If you change it, also change the regex as applicable.
Technically this is not JSON, I can also hardly imagine why would you want to do this, but try the following hack:
x.key2 = x.key2.toString();
JSON.stringify(x) //"{"key1":"xxx","key2":"function (){return this.key1}"}"
Of course the first line can be automated by iterating recursively over the object. Reverse operation is harder - function is only a string, eval will work, but you have to guess whether a given key contains a stringified function code or not.
You can't pack functions since the data they close over is not visible to any serializer.
Even Mozilla's uneval cannot pack closures properly.
Your best bet, is to use a reviver and a replacer.
https://yuilibrary.com/yui/docs/json/json-freeze-thaw.html
The reviver function passed to JSON.parse is applied to all key:value pairs in the raw parsed object from the deepest keys to the highest level. In our case, this means that the name and discovered properties will be passed through the reviver, and then the object containing those keys will be passed through.
This is what I did https://gist.github.com/Lepozepo/3275d686bc56e4fb5d11d27ef330a8ed
function stringifyWithFunctions(object) {
return JSON.stringify(object, (key, val) => {
if (typeof val === 'function') {
return `(${val})`; // make it a string, surround it by parenthesis to ensure we can revive it as an anonymous function
}
return val;
});
};
function parseWithFunctions(obj) {
return JSON.parse(obj, (k, v) => {
if (typeof v === 'string' && v.indexOf('function') >= 0) {
return eval(v);
}
return v;
});
};
The naughty but effective way would be to simply:
Function.prototype.toJSON = function() { return this.toString(); }
Though your real problem (aside from modifying the prototype of Function) would be deserialization without the use of eval.
I have come up with this solution which will take care of conversion of functions (no eval). All you have to do is put this code before you use JSON methods. Usage is exactly the same but right now it takes only one param value to convert to a JSON string, so if you pass remaning replacer and space params, they will be ignored.
void function () {
window.JSON = Object.create(JSON)
JSON.stringify = function (obj) {
return JSON.__proto__.stringify(obj, function (key, value) {
if (typeof value === 'function') {
return value.toString()
}
return value
})
}
JSON.parse = function (obj) {
return JSON.__proto__.parse(obj, function (key, value) {
if (typeof value === 'string' && value.slice(0, 8) == 'function') {
return Function('return ' + value)()
}
return value
})
}
}()
// YOUR CODE GOES BELOW HERE
x = {
"key1": "xxx",
"key2": function(){return this.key1}
}
const y = JSON.parse(JSON.stringify(x))
console.log(y.key2())
It is entirely possible to create functions from string without eval()
var obj = {a:function(a,b){
return a+b;
}};
var serialized = JSON.stringify(obj, function(k,v){
//special treatment for function types
if(typeof v === "function")
return v.toString();//we save the function as string
return v;
});
/*output:
"{"a":"function (a,b){\n return a+b;\n }"}"
*/
now some magic to turn string into function with this function
var compileFunction = function(str){
//find parameters
var pstart = str.indexOf('('), pend = str.indexOf(')');
var params = str.substring(pstart+1, pend);
params = params.trim();
//find function body
var bstart = str.indexOf('{'), bend = str.lastIndexOf('}');
var str = str.substring(bstart+1, bend);
return Function(params, str);
}
now use JSON.parse with reviver
var revivedObj = JSON.parse(serialized, function(k,v){
// there is probably a better way to determ if a value is a function string
if(typeof v === "string" && v.indexOf("function") !== -1)
return compileFunction(v);
return v;
});
//output:
revivedObj.a
function anonymous(a,b
/**/) {
return a+b;
}
revivedObj.a(1,2)
3
To my knowledge, there are no serialization libraries that persist functions - in any language. Serialization is what one does to preserve data. Compilation is what one does to preserve functions.
It seems that people landing here are dealing with structures that would be valid JSON if not for the fact that they contain functions. So how do we handle stringifying these structures?
I ran into the problem while writing a script to modify RequireJS configurations. This is how I did it. First, there's a bit of code earlier that makes sure that the placeholder used internally (">>>F<<<") does not show up as a value in the RequireJS configuration. Very unlikely to happen but better safe than sorry. The input configuration is read as a JavaScript Object, which may contain arrays, atomic values, other Objects and functions. It would be straightforwardly stringifiable as JSON if functions were not present. This configuration is the config object in the code that follows:
// Holds functions we encounter.
var functions = [];
var placeholder = ">>>F<<<";
// This handler just records a function object in `functions` and returns the
// placeholder as the value to insert into the JSON structure.
function handler(key, value) {
if (value instanceof Function) {
functions.push(value);
return placeholder;
}
return value;
}
// We stringify, using our custom handler.
var pre = JSON.stringify(config, handler, 4);
// Then we replace the placeholders in order they were encountered, with
// the functions we've recorded.
var post = pre.replace(new RegExp('"' + placeholder + '"', 'g'),
functions.shift.bind(functions));
The post variable contains the final value. This code relies on the fact that the order in which handler is called is the same as the order of the various pieces of data in the final JSON. I've checked the ECMAScript 5th edition, which defines the stringification algorithm and cannot find a case where there would be an ordering problem. If this algorithm were to change in a future edition the fix would be to use unique placholders for function and use these to refer back to the functions which would be stored in an associative array mapping unique placeholders to functions.

Can you alter a Javascript function after declaring it?

Let's say I have var a = function() { return 1; }. Is it possible to alter a so that a() returns 2? Perhaps by editing a property of the a object, since every function is an object?
Update: Wow, thanks for all the responses. However, I'm afraid I wasn't looking to simply reassign a variable but actually edit an existing function. I am thinking along the lines of how you can combine partial functions in Scala to create a new PartialFunction. I am interested in writing something similar in Javascript and was thinking that the existing function could perhaps be updated, rather than creating an entirely new Function object.
You can do all kinds of fun stuff with javascript, including redefining functions:
let a = function() { return 1; }
console.log(a()); // 1
// keep a reference
let old = a;
// redefine
a = function() {
// call the original function with any arguments specified, storing the result
const originalResult = old.apply(old, arguments);
// add one
return originalResult + 1;
};
console.log(a()); // 2
Voila.
Edit: Updated to show this in a crazier scenario:
let test = new String("123");
console.log(test.toString()); // logs 123
console.log(test.substring(0)); // logs 123
String.prototype.substring = function(){ return "hahanope"; }
console.log(test.substring(0)); // logs hahanope
You can see here that even though "test" is defined first, and we redefine substring() afterwards, the change still applies.
Side note: you really should reconsider your architecture if you're doing this...you're going to confuse the crap out of some poor developer 5 years down the road when s/he's looking at a function definition that's supposed to return 1, but seems to always return 2....
So you want to modify the code of a function directly, in place, and not just reassign a different function to an existing variable.
I hate to say it, but as far as I have been able to figure it out - and I have tried -, it can't be done. True, a function is an object, and as such it has methods and properties which can be tweaked and overwritten on the object itself. Unfortunately, the function body is not one of them. It is not assigned to a public property.
The documentation on MDN lists the properties and methods of the function object. None of them gives us the opportunity to manipulate the function body from the outside.
That's because according to the spec, the function body is stored in the internal [[Code]] property of the function object, which can't be accessed directly.
I used something like this to modify an existing function whose declaration was not accessible to me:
// declare function foo
var foo = function (a) { alert(a); };
// modify function foo
foo = new Function (
"a",
foo.toSource()
.replace("alert(a)", "alert('function modified - ' + a)")
.replace(/^function[^{]+{/i,"") // remove everything up to and including the first curly bracket
.replace(/}[^}]*$/i, "") // remove last curly bracket and everything after<br>
);
Instead of toSource() you could probably use toString() to get a string containing the function's declaration. Some calls to replace() to prepare the string for use with the Function Constructor and to modify the function's source.
let a = function() { return 1; }
console.log(a()) // 1
a = function() { return 2; }
console.log(a()) // 2
technically, you're losing one function definition and replacing it with another.
How about this, without having to redefine the function:
var a = function() { return arguments.callee.value || 1; };
alert(a()); // => 1
a.value = 2;
alert(a()); // => 2
I am sticking to jvenema's solution, in which I don't like the global variable "old". It seems better to keep the old function inside of the new one:
function a() { return 1; }
// redefine
a = (function(){
var _a = a;
return function() {
// You may reuse the original function ...
// Typical case: Conditionally use old/new behaviour
var originalResult = _a.apply(this, arguments);
// ... and modify the logic in any way
return originalResult + 1;
}
})();
a() // --> gives 2
All feasible solutions stick to a "function wrapping approach".
The most reliable amongst them seems to be the one of rplantiko.
Such function wrapping easily can be abstracted away. The concept / pattern itself might be called "Method Modification". Its implementation definitely belongs to Function.prototype. It would be nice to be backed
one day by standard prototypal method modifiers like before, after, around, afterThrowing and afterFinally.
As for the aforementioned example by rplantiko ...
function a () { return 1; }
// redefine
a = (function () {
var _a = a;
return function () {
// You may reuse the original function ...
// Typical case: Conditionally use old/new behaviour
var originalResult = _a.apply(this, arguments);
// ... and modify the logic in any way
return originalResult + 1;
};
})();
console.log('a() ...', a()); // --> gives 2
.as-console-wrapper { min-height: 100%!important; top: 0; }
... and making use of around, the code would transform to ...
function a () { return 1; }
console.log('original a ...', a);
console.log('a() ...', a()); // 1
a = a.around(function (proceed, handler, args) {
return (proceed() + 1);
});
console.log('\nmodified a ...', a);
console.log('a() ...', a()); // 2
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
(function(d){function f(a){return typeof a==e&&typeof a.call==e&&typeof a.apply==e}function g(a,b){b=null!=b&&b||null;var c=this;return f(a)&&f(c)&&function(){return a.call(b||null!=this&&this||null,c,a,arguments)}||c}var e=typeof d;Object.defineProperty(d.prototype,"around",{configurable:!0,writable:!0,value:g});Object.defineProperty(d,"around",{configurable:!0,writable:!0,value:function(a,b,c){return g.call(a,b,c)}})})(Function);
</script>
This is a Clear Example based on a control timepicker eworld.ui
www.eworldui.net
Having a TimePicker eworld.ui where JavaScript is unreachable from outside, you can't find any js related to those controls. So how can you add a onchange event to the timepicker ?
There is a js function called when you Select a time between all the options that the control offer you. This function is: TimePicker_Up_SelectTime
First you have to copy the code inside this function.
Evaluate...quikwatch...TimePicker_Up_SelectTime.toString()
function TimePicker_Up_SelectTime(tbName, lblName, divName, selTime, enableHide, postbackFunc, customFunc) {
document.getElementById(tbName).value = selTime;
if(lblName != '')
document.getElementById(lblName).innerHTML = selTime;
document.getElementById(divName).style.visibility = 'hidden';
if(enableHide)
TimePicker_Up_ShowHideDDL('visible');
if(customFunc != "")
eval(customFunc + "('" + selTime + "', '" + tbName + "');");
eval(postbackFunc + "();");
}
Now
Using the code that you have saved before reassign the same source code but add whatever you want..
TimePicker_Up_SelectTime = function (tbName, lblName, divName, selTime, enableHide, postbackFunc, customFunc) {
document.getElementById(tbName).value = selTime;
if (lblName != '')
document.getElementById(lblName).innerHTML = selTime;
document.getElementById(divName).style.visibility = 'hidden';
if (enableHide)
TimePicker_Up_ShowHideDDL('visible');
if (customFunc != "")
eval(customFunc + "('" + selTime + "', '" + tbName + "');");
eval(postbackFunc + "();");
>>>>>>> My function >>>>> RaiseChange(tbName);
}
I've added My Function to the function so now I can simulate an onchange event when I select a time.
RaiseChange(...) could be whatever you want.
If you're debugging javascript and want to see how changes to the code affects the page, you can use this Firefox extension to view/alter javascripts:
Execute JS firefox extension:
https://addons.mozilla.org/en-US/firefox/addon/1729
You can change functions like other objects
var a1 = function(){return 1;}
var b1 = a1;
a1 = function(){
return b1() + 1;
};
console.log(a1()); // return 2
// OR:
function a2(){return 1;}
var b2 = a2;
a2 = function(){
return b2() + 1;
};
console.log(a2()); // return 2
Can you not just define it again later on? When you want the change try just redefining it as:
a = function() { return 2; }
const createFunction = function (defaultRealization) {
let realization = defaultRealization;
const youFunction = function (...args) {
return realization(...args);
};
youFunction.alterRealization = function (fn) {
realization = fn;
};
return youFunction;
}
const myFunction = createFunction(function () { return 1; });
console.log(myFunction()); // 1
myFunction.alterRealization(function () { return 2; });
console.log(myFunction()); // 2

"method overloading" in javascript

So I admit that I'm new to javascript and that I come from a C.+ background ("Hi, I'm Bob, I'm a class-based static language user", chorus "hi Bob!").
I find that I often end up writing functions like:
function someFunc()
{
if (arguments.length === 0 ){
...
} else {
...
}
}
(where there might be three such cases). Or, alternatively, I write the difference into the name:
function someFuncDefault() { ... };
function someFuncRealArg(theArg) { ... };
(Substitute "RealArg" for some semantically contentful phrase).
Is there a better pattern for this kind of thing?
Have a look at this post.
I don't know that I would do it this way, but it seems like it might make your code mildly less unmanageable:
function someFunc() {
switch (arguments.length) {
case 0: noArgs();
case 1: oneArg(arguments[0]);
case 2: twoArgs(arguments[0], arguments[1]);
}
function noArgs() {
// ...
}
function oneArg(a) {
// ...
}
function twoArgs(a, b) {
// ...
}
}
Another example might be:
function someFunc(a, b) {
if ('string' == typeof a) {
// ...
} else if ('number' == typeof a) {
// ...
}
}
And of course you can probably create something quite unmanageable by combining both examples (using conditions to determine behaviour based on number of arguments and types of arguments).
This is overloading, not overriding no?
Javascript is weakly typed, so method signatures and native support is out. My recommendation is to pass an extensible object as the solitary argument. Inspect and handle the existance of properties on the param object as you wish.
What advantage does this have over arguments? Well it lets you be explicit about your intentions where you call, and unambiguous about the meaning of arg1 and arg2 where you recieve, and it lets you abstract to a custom data object class you can extend functionality to.
function someFunc(params)
{
var x = params.x || defaultX;
var y = params.y || defaultY;
//businesslogic
}
someFunc({x:'foo',y:'bar'});
someFunc({y:'baz'});
In Javascript, all arguments are optional.
You might try something like:
Edit (better method that doesn't break for values whose 'truthiness' is false):
function bar(arg1, arg2) {
if(arg1 === undefined) { set default }
if(arg2 === undefined) { set default }
//do stuff here
}
Old method that breaks for falsey values:
function foo(arg1, arg2) {
if(!arg1) { set default }
if(!arg2) { set default }
//do stuff here
}
A great place to start with javascript are Douglas Crockford's javascript lectures: http://video.yahoo.com/search/?p=javascript
Javascript lets you get really lazy with this (not quite as lazy as Python, but pretty lazy).
function someFunc(arg1, arg2)
{
if(typeof(arg1) == "undefined") {
arg1 = default;
}
...
}
So you don't really need to overload. Javascript won't yell at you for passing the wrong number of parameters.
Everyone came close, I think that the real issue here is that in JavaScript you shouldn't change behavior based on parameters being passed in.
Since JavaScript makes all parameters optional you could follow the concise method of using this convention:
function foo(bar, baz) {
bar = bar || defaultBar;
baz = baz || defaultBaz;
.
.
.
}
Personally, I prefer to write the most complex function that would be performed, and then document it in comments so that others know that they do not have to send all the arguments.
//concat(str1, str2 [,str3 [,str4 [,str5]]])
function concat(str1, str2, str3, str4, str5) {
var str = str1 + str2;
if(str3 != undefined)
str += str3;
if(str4 != undefined)
str += str4;
if(str5 != undefined)
str += str5;
return str;
}
I have also found situations where the argument order would matter in a normal function, but sometimes I would want to sent the arguments seperately (i.e. I would want to send str3 and str5 but not str4). For this, I use an object and test the known properties
//concat({str1:string, str2:string, str3:string, str4:string, str5:string})
//str3, str4, and str5 are optional
function concat(strngs) {
var str = strngs.str1 + strngs.str2;
if(strngs.str3 != undefined)
str += strngs.str3;
if(strngs.str4 != undefined)
str += strngs.str4;
if(strngs.str5 != undefined)
str += strngs.str5;
return str;
}
A little more comprehensive overloading mechanism is offered by bob.js:
var notify = new bob.fn.overloadFunction([
{
condition: function(msg) { return bob.utils.isString(msg); },
overload: function(msg) {
console.log(msg);
}
},
{
condition: function(bSayHello) { return bob.utils.isBoolean(bSayHello); },
overload: function(bSayHello, msg) {
msg = bSayHello ? 'Hello: ' + msg : msg;
console.log(msg);
}
}
]);
Calling the overloaded function:
notify('Simple sentence.');
// Output:
// Simple sentence.
notify(true, 'Greeting sentence.');
// Output:
// Hello: Greeting sentence.
notify(123);
// JavaScript Error:
// "No matching overload found."

Categories

Resources