How to determine if a function is empty - javascript

I want to be able to check whether a given function is empty or not. That is, there is nothing in its body, eg:
function foo() {}
function iAmEmpty(a) {
// yep, empty
}
With some initial playing around, I've got something which I think might be ok, by using toString() and some regexes.
function foo(a, b, c) {}
/^function[^{]+\{\s*\}/m.test(foo.toString()); // true
function bar(a, b, c) { var d; }
/^function[^{]+\{\s*\}/m.test(bar.toString()); // false
I was just wondering if there was a better approach? Are there any problems with the above you can see?

This isn't advisable. There is no standard determining precisely what a function's toString() method should return, so even if you get this working in current browsers, future browsers may justifiably change their implementation and break your code.
Kangax has written briefly about this: http://perfectionkills.com/those-tricky-functions/

Arrow functions...
As I am sure you are aware, javascript supports arrow functions which are really succinct but unfortunately don't work with your neat regex.
I quickly converted your nice regex into its own function which takes a function as an input and returns whether or not it is empty for simplicity later. Just to demonstrate how arrow functions can be widely used, I put it in one:
isEmpty = f => /^function[^{]+\{\s*\}/m.test(f.toString())
Now, we can easily test an empty function:
function eF() {}
which as we would expect with isEmpty(eF) returns true.
And once more with an actual function:
function retOne() {return 1;}
which again as expected with isEmpty(retOne) returns false.
However, the issue I encountered was with arrow functions so to initialize an empty one again, we have a shorter syntax of the original:
eF = () => {}
and the 'stringified'version of that is quite different to the one before:
"() => {}"
so of course in this case the call isEmpty(eF) returns false when we want true. I'm not sure if you require to test if all functions (i.e. including arrow functions) are empty but if you do, your regexwill need modifying...
I am not great at writing them myself, but have attempted a couple and one further thing that you might want to consider is the lenient nature of the arrow functions especially this part of the documentation:
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalent to: (param1, param2, …, paramN) => { return expression; }
// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }
which shows how the curly brackets {...} are not always necessary. So this function:
retOne = () => 1
is valid and could make forming a new regex more difficult. One workaround I thought of is to just remove all curly brackets from f.toString() using:
str.replace(/[{}]/g, '').
and then work with a regex test from there.
Hopefully this is something helpful to consider if you want arrow functions to also be able to be tested.

The best thing you can try, to fit the maximum possibilities (as this is pretty hard to achieve), is to add acorn or esprima (works with arrow functions too) libraries and process the JavaScript function. It will tokenize it for you to parse, so you can process it to your likings, checking if there's actually zero code inside, or there's only variable declarations without any calculation nor return, etc...
Is pretty straightforward to implement:
function check(f) {
console.log("");
console.log("Checking", f);
var syntax = esprima.parse(f);
if (syntax.body.length != 1) {
console.log("Weird process");
} else {
function processBody(body) {
if (!body || body.length == 0) {
console.log("Body seems empty. YAY!");
} else {
for (var i = 0, command; command = body[i]; i++) {
if (command.type != "VariableDeclaration") {
console.log("Body has a", command.type, ", so is not empty.");
return;
}
}
console.log("Body has only variable declarations, so is empty! (or not, whatever fit your needs)");
}
}
function process(dec) {
if (dec.type != "FunctionDeclaration") {
console.log("Weird declaration");
} else {
console.log("Function", dec.id.name, "has", dec.params.length, "params");
processBody(dec.body.body);
}
}
process(syntax.body[0]);
}
}
check("function hasReturn(arg1, arg2) {var a = arg1 + arg2;return a;}");
check("function hasArgumentsButNoBody(arg1, arg2) {}");
check("function isCompletelyEmptyWithSpacesAndTabsAndLinefeeds() { \t \t \r\n \r\n }");
check("function hasOnlyVariables() {var a, b = 2; var c = 1 + b;}");
<script src="https://cdnjs.cloudflare.com/ajax/libs/esprima/2.7.3/esprima.min.js"></script>
This will not run the functions, just parse them, so is safe to run with non-secure functions.

I don't see the use for this, but you could make it simpler by anchoring the pattern to the end of the string.
/[^{\s]\s*\}$/.test(String(bar))

Function.prototype.hasBody = function() {
return !/{\s*}$/.test(this.toString());
};

It's simple just check the function contain and then check the contain if it's empty or not .
check this Plunker
here's full working code:
function foo(a, b, c) {}
function bar(a, b, c) {
var d;
}
function isEmpty(value) {
return (value == null || value.length === 0);
}
function check(test) {
var entire = test.toString();
var body = entire.slice(entire.indexOf("{") + 1, entire.lastIndexOf("}"));
return body;
}
console.log(isEmpty(check(foo)), isEmpty(check(bar))); //return true false

Related

Best approach to avoid multiple check conditions in Javascript

In order to write quality code with good readability, I'm adopting currying functions approach and making pure helper functions for most of the repetitive code snippets. I just observed that I’m having an existence/type check everywhere in my project to avoid any possible errors like type of undefined.
The checks are like:
if (param){
action...
}
I'm thinking to create a global helper function that should take two parameters; param that need to be checked and the action function to perform the action in case the check passes. Something like:
function isExist(param, action){
if (param){
action();
}
}
This functions is not ideally working for all snippets/cases. How can i make it efficient and globally functional for all cases? Also is this the right approach. If not then what is the best approach that i should follow to achieve my aim here?
Example:
if (userInput){
saveToDB(userInput);
}
if (valueFromDB){
performSomeAction();
}
if (username && password){
validate(username, password)
}
I want all of these checks at different points in my code to be replaced by single helper function to somewhat like:
isExist( userInput, saveToDB(userInput) );
isExist( valueFromDB, performSomeAction );
isExist( (username && password), validate(username, password) );
In this way we've replaced this 9 lines of code with just three lines. This is what I wanna achieve.
Well, if you try to think of a good name for
function isExist(param, action){
if (param){
action();
}
}
Then I think one good candidate would be conditionalExecute(condition, codeToExecute). Does this kind of work sound familiar? Are you sure you're not just reinventing the if-statement itself?
Maybe I'm missing your point, but I can't personally see the benefit of encapsulating the logic of the if-statement more than it already is.
Edit: It should be noted that within the context of Javascript the code
if(someVariable){
// do something
}
already reads like "If someVariable is truthy (which undefined is not) then....
But sure, if you only want to check for existance (a variable not being undefined) I won't argue against you if you say it's preferable to have a named function that makes that clear.
In that case I think it's clearer to only encapsulate the actual existence check (or what ever you want to check), not the conditional nature (because for that we already have the if-statement). So something like
function exists(x) {
return x !== undefined; // or something like that
}
function isNotNull(x) {
//TODO:
}
Then your code would become more explicit and readable, and you could combine the functions if you wanted
function neitherUndefinedNorNull(x){
return exists(x) && isNotNull(x);
}
if(neitherUndefinedNorNull(X)){
// your "regular" code here
}
If the code inside of the if-statement is repeated, then extract that as a function as well.
function myRepeatedCode() {
// do stuff
}
function someAlternativeCondition(x){
// test
}
if(neitherUndefinedNorNull ){
myRepeatedCode();
} else if(someAlternativeCondition(x)) {
myRepeatedCode();
}
// OR combine them in the same if-statement
if(neitherUndefinedNorNull(x) || someAlternativeCondition(x)){
myRepeatedCode();
}
Last edit: If you're chasing characters you could even write
// because of short-circuiting, myFunc1 and myFunc2 will only
// execute if myCond1 resp myCond2 is true (or truthy).
myCond1(x) && myFunc1(x)
myCond2(y) && myFunc2(y)
This is the perfect place to use Maybe:
const enumerable = true;
// data Maybe a = Nothing | Just a
const Maybe = {};
const Nothing = Object.create(Maybe);
const Just = value => Object.create(Maybe, {value: {enumerable, value}});
// instance Functor Maybe where
Nothing.map = _ => Nothing;
Maybe.map = function (fun) { return Just(fun(this.value)); };
// instance Applicative Maybe where
Maybe.of = Just;
Nothing.ap = _ => Nothing;
Maybe.ap = function (maybe) { return maybe.map(this.value); };
// instance Monad Maybe where
Nothing.chain = _ => Nothing;
Maybe.chain = function (kleisli) { return kleisli(this.value); };
Maybe follows the Fantasy Land Specification[1]. Using Maybe allows you to write code like this:
// userInput :: Maybe Data
// saveToDB :: Data -> Something
userInput.map(saveToDB); // :: Maybe Something
// valueFromDB :: Maybe Data
// performSomeAction :: Data -> Maybe Something
valueFromDB.chain(performSomeAction); // :: Maybe Something
// username :: Maybe String
// password :: Maybe Password
// validate :: String -> Password -> Something
Maybe.of(validate).ap(username).ap(password); // :: Maybe Something
Anyway, if you're really interested in functional programming then I suggest that you Learn You A Haskell.
[1] I don't agree with the Fantasy Land Specification on flipping the arguments of ap.
how about this, it can process the parameters at same time.
function test(a,b,c)
{
console.log("%s,%s,%s",a,b,c)
}
function check_and_run(param,action){
var args = Array.prototype.slice.call(arguments); //turn arguments to array
args.shift(); //remove param and action
args.shift();
if(param)
action.apply(this,args)
}
check_and_run(1,test,1,2,3) //this will invoke test(1,2,3)
check_and_run(0,test,1,2,3) //this will do nothing
Perhaps something like this:
function conFun(fnCondition, fnCall, defaultResult=undefined) {
return (...rest) => {
if( fnCondition(...rest) ) {
return fnCall(...rest)
}
return defaultResult;
}
}
const add = conFun(
(...rest) => rest.every(n => typeof n === 'number'),
(...rest) => rest.reduce((a, n) => a+n),
NaN);
add("1", "2"); //=> NaN
add(1, 2); //=> 3
So in your question you might be after the first argument not being undefined:
const firstDefined = (v) => typeof v !== 'undefined';
const cSomeFun = conFun(firstDefined, someFun, "");
cSomeFun(); // ==> ""
cSomeFun("test"); // ==> whatever someFun("test") returns
If you are just looking to call something based on non undefined arguments you can simply define it like this:
function callDefined(fn, ...rest) {
if( rest.every(firstDefined) ) {
return fn(...rest)
}
return undefined;
}
callDefined( saveToDB.bind(this, userInput), userInput);
callDefined( performSomeAction, valueFromDB);
callDefined( calidate.bind(this, username, password), username, password);

Why use parentheses when returning in JavaScript?

In the Restify framework code I found this function:
function queryParser(options) {
function parseQueryString(req, res, next) {
// Some code goes there
return (next());
}
return (parseQueryString);
}
Why would the author write return (next()); and return (parseQueryString);? Does it need parentheses there and if so, why?
Using parentheses when returning is necessary if you want to write your return statement over several lines.
React.js offers a useful example. In the return statement of the render property in a component you usually want to spread the JSX you return over several lines for readability reasons, e.g.:
render: function() {
return (
<div className="foo">
<h1>Headline</h1>
<MyComponent data={this.state.data} />
</div>
);
}
Without parentheses it results in an error!
More generally, not using parentheses when spreading a return statement over several lines will result in an error. The following example will execute properly:
var foo = function() {
var x = 3;
return (
x
+
1
);
};
console.log(foo());
Whereas the following (without the parentheses) will throw errors:
var foo = function() {
var x = 3;
return
x
+
1
;
};
console.log(foo());
It doesn't need to be that way, but it's valid JavaScript code. Actually it's quite uncommon to see such syntax. I guess it's a personal preference of the author.
Parenthesis are used for two purposes in a return statement.
To support multi-line expression as mentioned in #Andru Answer.
To allow returning object in arrow function like the below:
() => ({ name: 'Amanda' }) // Shorthand to return an object
This is equivalent to
() => {
return { name : 'Amanda' }
}
For more information, please check this article.
https://medium.com/#leannezhang/curly-braces-versus-parenthesis-in-reactjs-4d3ffd33128f
// Create a component named MessageComponent
var MessageComponent = React.createClass({
render: function() {
return (
<div>{this.props.message}</div>
);
}
});
NOTE Why do we need the parentheses around the return statement (line
3)? This is because of JavaScript's automatic semicolon insertion.
Without the parentheses, JavaScript would ignore the following lines
and return without a value. If the JSX starts on the same line as the
return, then parentheses are not needed.
Taken from here.
Just to add to what others have said.
Using brackets around the return value is valid JavaScript, but mostly a bad thing to do.
Mostly bad because it doesn't add anything yet increases the size of the JavaScript which means that there is more to download to the browser. Yes most people have fast broadband connections, but don't lose sight of the fact that everything you put in the JavaScript file needs to be downloaded so avoid unnecessary code bloat. This probably doesn't matter if you use a tool to compact your code (minifier has already been mentioned), but not everyone does.
Sometimes it might aid readability. Hard pressed to think of an example in this case, but if the use of brackets makes your JavaScript clearer to you as the developer and thus easier to maintain then use them - even if it goes against what I said about code bloat.
Why would the author write return (next()); ... ?
Regarding next():
Probably because his function is something like this:
function next()
{
var i=0;
return function (){
// Do something with that closured i....
}
}
Regarding (xxx);:
It is unnecessary. Every minifier will remove it.
Example (uglifyJS):
becomes:
I tried:
var a = function() {
return true || true
}
console.log(a());
//return: true
var a = function() {
return
true || true
}
console.log(a());
//return: undefined
var a = function() {
return (
true || true
)
}
console.log(a());
//return: true
While Andru's answer is popular, it is wrong that parantheses are required for multiline return statement. Here, you can see an object of foo and bar is returned with no parantheses needed.
function foo () {
return {
foo: 'foo',
bar: 'bar',
}
}
console.log(foo())
As long as the return line is not just empty space or linebreak, you can have a multiline return just fine. Otherwise Automatic Semicolon Insertion takeover and break your return statement as demonstrated by Andru.
Regarding your question, I am onboard with Darin's answer.
This may be old but the return () can be used in this way:
function parseQueryString(req, res, next) {
var id = req.param('id');
return (id ? "Foo" : "Bar");
}
Less code, easy to read :)

Force missing parameters in JavaScript

When you call a function in JavaScript and you miss to pass some parameter, nothing happens.
This makes the code harder to debug, so I would like to change that behavior.
I've seen
How best to determine if an argument is not sent to the JavaScript function
but I want a solution with a constant number of typed lines of code; not typing extra code for each function.
I've thought about automatically prefixing the code of all functions with that code, by modifying the constructor of the ("first-class") Function object.
Inspired by
Changing constructor in JavaScript
I've first tested whether I can change the constructor of the Function object, like this:
function Function2 () {
this.color = "white";
}
Function.prototype = new Function2();
f = new Function();
alert(f.color);
But it alerts "undefined" instead of "white", so it is not working, so I've don't further explored this technique.
Do you know any solution for this problem at any level? Hacking the guts of JavaScript would be OK but any other practical tip on how to find missing arguments would be OK as well.
If a function of yours requires certain arguments to be passed, you should check for those arguments specifically as part of the validation of the function.
Extending the Function object is not the best idea because many libraries rely on the behavior of defaulting arguments that are not passed (such as jQuery not passing anything to it's scoped undefined variable).
Two approaches I tend to use:
1) an argument is required for the function to work
var foo = function (requiredParam) {
if (typeof requiredParam === 'undefined') {
throw new Error('You must pass requiredParam to function Foo!');
}
// solve world hunger here
};
2) an argument not passed but can be defaulted to something (uses jQuery)
var foo = function (argumentObject) {
argumentObject = $.extend({
someArgument1: 'defaultValue1',
someArgument2: 'defaultValue2'
}, argumentObject || {});
// save the world from alien invaders here
};
As others have said, there are many reasons not to do this, but I know of a couple of ways, so I'll tell you how! For science!
This is the first, stolen from Gaby, give him an upvote! Here's a rough overview of how it works:
//example function
function thing(a, b, c) {
}
var functionPool = {} // create a variable to hold the original versions of the functions
for( var func in window ) // scan all items in window scope
{
if (typeof(window[func]) === 'function') // if item is a function
{
functionPool[func] = window[func]; // store the original to our global pool
(function(){ // create an closure to maintain function name
var functionName = func;
window[functionName] = function(){ // overwrite the function with our own version
var args = [].splice.call(arguments,0); // convert arguments to array
// do the logging before callling the method
if(functionPool[functionName].length > args.length)
throw "Not enough arguments for function " + functionName + " expected " + functionPool[functionName].length + " got " + args.length;
// call the original method but in the window scope, and return the results
return functionPool[functionName].apply(window, args );
// additional logging could take place here if we stored the return value ..
}
})();
}
}
thing(1,2 ,3); //fine
thing(1,2); //throws error
The second way:
Now there is another way to do this that I can't remember the details exactly, basically you overrride Function.prototype.call. But as it says in this question, this involves an infinite loop. So you need an untainted Function object to call, this is done by a trick of turning the variables into a string and then using eval to call the function in an untainted context! There's a really great snippet out the showing you how from the early days of the web, but alas I can't find it at the moment. There's a hack that's required to pass the variables properly and I think you may actually lose context, so it's pretty fragile.
Still, as stated, don't try and force javascript to do something against its nature, either trust your fellow programmers or supply defaults, as per all the other answers.
You can imitate something like Python’s decorators. This does require extra typing per function, though not extra lines.
function force(inner) {
return function() {
if (arguments.length === inner.length) {
return inner.apply(this, arguments);
} else {
throw "expected " + inner.length +
" arguments, got " + arguments.length;
}
}
}
var myFunc = force(function(foo, bar, baz) {
// ...
});
In general this sounds like a bad idea, because you’re basically messing with the language. Do you really forget to pass arguments that often?
You could use the decorator pattern. The following decorator allows you to specify minimum and maximum number of arguments that need to be passed and an optional error handler.
/* Wrap the function *f*, so that *error_callback* is called when the number
of passed arguments is not with range *nmin* to *nmax*. *error_callback*
may be ommited to make the wrapper just throw an error message.
The wrapped function is returned. */
function require_arguments(f, nmin, nmax, error_callback) {
if (!error_callback) {
error_callback = function(n, nmin, nmax) {
throw 'Expected arguments from ' + nmin + ' to ' + nmax + ' (' +
n + ' passed).';
}
}
function wrapper() {
var n_args = arguments.length;
console.log(n_args, nmin, nmax);
console.log((nmin <= 0) && (0 <= nmax));
if ((nmin <= n_args) && (n_args <= nmax)) {
return f.apply(this, arguments);
}
return error_callback(n_args, nmin, nmax);
}
for (e in f) {
wrapper[e] = f[e];
}
return wrapper;
}
var foo = require_arguments(function(a, b, c) {
/* .. */
}, 1, 3);
foo(1);
foo(1, 2);
foo(1, 2, 3);
foo(1, 2, 3, 4); // uncaught exception: Expected arguments from 1 to 3 (4 passed).
foo(); // uncaught exception: Expected arguments from 1 to 3 (0 passed).

jQuery/Javascript: How can I evaluate the validity of function arguments efficiently with a range of valid types?

I've got a rather large plugin that I am currently writing in jQuery which is using a lot of internal functions that can accept varying arguments depending on the function.
I caught myself constantly writing the following in every function to stop the code from running if an argument hasn't been supplied or isn't valid:
add : function(args) {
if (args===undefined) return;
// function code;
},...
I was hoping that in a DRY type of sense it would be a good idea to write a little internal helper function that would do this for me.
Is this actually a good idea and most importantly what is the best/secure way to check for a varied range of acceptable arguments?
There are a lot of functions with multiple arguments in this plugin, for example:
load : function( filename , path , excludeFromRandom , callback ) {}
where filename is a string,
path is a string,
excludeFromRandom is a boolean and
callback can be a function or a string.
What is a good way to check for the existence and validity of these types of arguments without rewriting the same code over and over?
Any suggestions and ideas would be great.
Thanks for reading.
It depends to what extent you want to do this. In idea would be to create a validation function which takes a argument -> rule mapping. E.g.:
function foo(somestring, somenumber) {
var rules = {
'somestring': Validator.rules.isString,
'somenumber': Validator.rules.inRange(5,10);
};
}
Validator would contain the basic logic and some helper functions (rules):
var Validator = {
valid: function(args, rules) {
for(var name in rules) {
if(!rules[name](args[name])) {
return false;
}
}
return true;
},
rules: {
isString: function(arg) {
return (typeof arg === 'string');
},
inRange: function(x,y) {
return function(arg) {
return !isNaN(+arg) && x <= arg && arg <= y;
}
}
}
}
This is just a sketch, it certainly can be extended (like accepting multiple rules per argument), but it should give you some idea.
That said, you don't have to check every argument. Provide decent documentation. If people use your plugin in a wrong way, i.e. passing wrong argument types, then your code will throw an error anyway.
Update:
If want to do this very often, then a good idea is to write a wrapper function and you just pass the function and the rules to it:
function ensure(func, rules, context) {
context = context || this;
return function() {
if(Validator.valid(arguments, rules)) {
return func.apply(context, arguments);
}
return null; // or throw error, whatever you want
}
}
Then you can define your function normally as:
var foo = function(somestring, somenumber) {
// ...
};
and just add validation to it:
var rules = {...};
foo = ensure(foo, rules);
You could even consider to make ensure accept a callback which gets called on error or success of the function, instead of returning a value. There are a lot of possibilities.

Overriding a JavaScript function while referencing the original

I have a function, a(), that I want to override, but also have the original a() be performed in an order depending on the context. For example, sometimes when I'm generating a page I'll want to override like this:
function a() {
new_code();
original_a();
}
and sometimes like this:
function a() {
original_a();
other_new_code();
}
How do I get that original_a() from within the over-riding a()? Is it even possible?
Please don't suggest alternatives to over-riding in this way, I know of many. I'm asking about this way specifically.
You could do something like this:
var a = (function() {
var original_a = a;
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})();
Declaring original_a inside an anonymous function keeps it from cluttering the global namespace, but it's available in the inner functions.
Like Nerdmaster mentioned in the comments, be sure to include the () at the end. You want to call the outer function and store the result (one of the two inner functions) in a, not store the outer function itself in a.
The Proxy pattern might help you:
(function() {
// log all calls to setArray
var proxied = jQuery.fn.setArray;
jQuery.fn.setArray = function() {
console.log( this, arguments );
return proxied.apply( this, arguments );
};
})();
The above wraps its code in a function to hide the "proxied"-variable. It saves jQuery's setArray-method in a closure and overwrites it. The proxy then logs all calls to the method and delegates the call to the original. Using apply(this, arguments) guarantees that the caller won't be able to notice the difference between the original and the proxied method.
Thanks guys the proxy pattern really helped.....Actually I wanted to call a global function foo..
In certain pages i need do to some checks. So I did the following.
//Saving the original func
var org_foo = window.foo;
//Assigning proxy fucnc
window.foo = function(args){
//Performing checks
if(checkCondition(args)){
//Calling original funcs
org_foo(args);
}
};
Thnx this really helped me out
You can override a function using a construct like:
function override(f, g) {
return function() {
return g(f);
};
}
For example:
a = override(a, function(original_a) {
if (condition) { new_code(); original_a(); }
else { original_a(); other_new_code(); }
});
Edit: Fixed a typo.
Passing arbitrary arguments:
a = override(a, function(original_a) {
if (condition) { new_code(); original_a.apply(this, arguments) ; }
else { original_a.apply(this, arguments); other_new_code(); }
});
The answer that #Matthew Crumley provides is making use of the immediately invoked function expressions, to close the older 'a' function into the execution context of the returned function. I think this was the best answer, but personally, I would prefer passing the function 'a' as an argument to IIFE. I think it is more understandable.
var a = (function(original_a) {
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})(a);
The examples above don't correctly apply this or pass arguments correctly to the function override. Underscore _.wrap() wraps existing functions, applies this and passes arguments correctly. See: http://underscorejs.org/#wrap
In my opinion the top answers are not readable/maintainable, and the other answers do not properly bind context. Here's a readable solution using ES6 syntax to solve both these problems.
const orginial = someObject.foo;
someObject.foo = function() {
if (condition) orginial.bind(this)(...arguments);
};
I had some code written by someone else and wanted to add a line to a function which i could not find in the code. So as a workaround I wanted to override it.
None of the solutions worked for me though.
Here is what worked in my case:
if (typeof originalFunction === "undefined") {
originalFunction = targetFunction;
targetFunction = function(x, y) {
//Your code
originalFunction(a, b);
//Your Code
};
}
I've created a small helper for a similar scenario because I often needed to override functions from several libraries. This helper accepts a "namespace" (the function container), the function name, and the overriding function. It will replace the original function in the referred namespace with the new one.
The new function accepts the original function as the first argument, and the original functions arguments as the rest. It will preserve the context everytime. It supports void and non-void functions as well.
function overrideFunction(namespace, baseFuncName, func) {
var originalFn = namespace[baseFuncName];
namespace[baseFuncName] = function () {
return func.apply(this, [originalFn.bind(this)].concat(Array.prototype.slice.call(arguments, 0)));
};
}
Usage for example with Bootstrap:
overrideFunction($.fn.popover.Constructor.prototype, 'leave', function(baseFn, obj) {
// ... do stuff before base call
baseFn(obj);
// ... do stuff after base call
});
I didn't create any performance tests though. It can possibly add some unwanted overhead which can or cannot be a big deal, depending on scenarios.
So my answer ended up being a solution that allows me to use the _this variable pointing to the original object.
I create a new instance of a "Square" however I hated the way the "Square" generated it's size. I thought it should follow my specific needs. However in order to do so I needed the square to have an updated "GetSize" function with the internals of that function calling other functions already existing in the square such as this.height, this.GetVolume(). But in order to do so I needed to do this without any crazy hacks. So here is my solution.
Some other Object initializer or helper function.
this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(
this.viewerContainer)
var viewer = this.viewer;
viewer.updateToolbarButtons = this.updateToolbarButtons(viewer);
Function in the other object.
updateToolbarButtons = function(viewer) {
var _viewer = viewer;
return function(width, height){
blah blah black sheep I can refer to this.anything();
}
};
Not sure if it'll work in all circumstances, but in our case, we were trying to override the describe function in Jest so that we can parse the name and skip the whole describe block if it met some criteria.
Here's what worked for us:
function describe( name, callback ) {
if ( name.includes( "skip" ) )
return this.describe.skip( name, callback );
else
return this.describe( name, callback );
}
Two things that are critical here:
We don't use an arrow function () =>.
Arrow functions change the reference to this and we need that to be the file's this.
The use of this.describe and this.describe.skip instead of just describe and describe.skip.
Again, not sure it's of value to anybody but we originally tried to get away with Matthew Crumley's excellent answer but needed to make our method a function and accept params in order to parse them in the conditional.

Categories

Resources