I would like to override a Javascript built-in function with a new version that calls the original (similarly to overriding a method on a class with a version that calls super in many languages). How can I do this?
For example...
window.alert = function(str) {
//do something additional
if(console) console.log(str);
//super.alert(str) // How do I do this bit?
}
Store a reference to the original function in a variable:
(function() {
var _alert = window.alert; // <-- Reference
window.alert = function(str) {
// do something additional
if(console) console.log(str);
//return _alert.apply(this, arguments); // <-- The universal method
_alert(str); // Suits for this case
};
})();
The universal way is <original_func_reference>.apply(this, arguments) - To preserve context and pass all arguments. Usually, the return value of the original method should also be returned.
However, it's known that alert is a void function, takes only one argument, and does not use the this object. So, _alert(str) is sufficient in this case.
Note: IE <= 8 throws an error if you try to overwrite alert, so make sure that you're using window.alert = ... instead of alert = ....
There is no "super". Anyway, create a closure to "keep" around the original function-object.
Note the "self invoking function" that returns a new function-object (that is assigned to the window.alert property). The new function-object returned creates a closure around the variable original which evaluates to the original value of window.alert that was passed in to the "self invoking function".
window.alert = (function (original) {
return function (str) {
//do something additional
if(console) {
console.log(str)
}
original(str)
}
})(window.alert)
However, I believe some browsers may prevent alert and other built-ins from being modified...
Happy coding.
I'm assuming your question is how do you overwrite a built-in and still be able to call it. First off as a disclaimer, you should never overwrite built ins unless you have a good reason for doing it since it will make it impossible to debug/test.
This is how you would do it:
window._alert = window.alert;
window.alert = function(str) {
if(console) console.log(str);
window._alert(str);
}
How to do simple classical inheritance in Javascript:
SuperClass.call(this) // inherit from SuperClass (multiple inheritance yes)
How to override functions:
this.myFunction = this.myFunction.override(
function(){
this.superFunction(); // call the overridden function
}
);
The override function is created like this:
Function.prototype.override = function(func)
{
var superFunction = this;
return function()
{
this.superFunction = superFunction;
return func.apply(this,arguments);
};
};
Works with multiple arguments.
Fails when trying to override undefined or nonfunctions.
Makes "superFunction" a "reserved" word :-)
JavaScript does not use a classical inheritance model. There is a nice article here which describes a way to write your classes so that a similar syntax can be used, but it's not natively supported.
By using proxy object you can do this.
window.alert = new Proxy(window.alert , {
apply: function(target,that,args){
console && console.log(args.join('\n'));
target.apply(that,args)
}})
Related
How can I access a function name from inside that function?
// parasitic inheritance
var ns.parent.child = function() {
var parent = new ns.parent();
parent.newFunc = function() {
}
return parent;
}
var ns.parent = function() {
// at this point, i want to know who the child is that called the parent
// ie
}
var obj = new ns.parent.child();
In ES6, you can just use myFunction.name.
Note: Beware that some JS minifiers might throw away function names, to compress better; you may need to tweak their settings to avoid that.
In ES5, the best thing to do is:
function functionName(fun) {
var ret = fun.toString();
ret = ret.substr('function '.length);
ret = ret.substr(0, ret.indexOf('('));
return ret;
}
Using Function.caller is non-standard. Function.caller and arguments.callee are both forbidden in strict mode.
Edit: nus's regex based answer below achieves the same thing, but has better performance!
ES6 (inspired by sendy halim's answer below):
myFunction.name
Explanation on MDN. As of 2015 works in nodejs and all major browsers except IE.
Note: On bound functions this will give "bound <originalName>". You will have to strip the "bound " if you want to get the original name.
ES5 (inspired by Vlad's answer):
If you have a reference to the function, you can do:
function functionName( func )
{
// Match:
// - ^ the beginning of the string
// - function the word 'function'
// - \s+ at least some white space
// - ([\w\$]+) capture one or more valid JavaScript identifier characters
// - \s* optionally followed by white space (in theory there won't be any here,
// so if performance is an issue this can be omitted[1]
// - \( followed by an opening brace
//
var result = /^function\s+([\w\$]+)\s*\(/.exec( func.toString() )
return result ? result[ 1 ] : '' // for an anonymous function there won't be a match
}
I have not run unit tests on this, or verified implementation
differences, but in principle it should work, if not leave a comment.
Note: won't work on bound functions
Note: that caller and callee are considered deprecated.
[1] I include it here because it is legal and often enough syntax highlighting tools fail to take into account the white space between function name and parenthesis. On the other hand, I'm not aware of any implementation of .toString() that will include white space here, so that's why you can omit it.
As an answer to the original question, I would drop parasitic inheritance and go for some more traditional OOP design patterns. I wrote a TidBits.OoJs to comfortably write OOP code in JavaScript with a feature set mimicking C++ (not yet complete, but mostly).
I see from the comments that you would like to avoid passing information parent needs to it's constructor. I must admit that traditional design patterns won't save you from that one though, since it is generally a considered a good thing to make your dependencies obvious and enforced.
I would also suggest to steer away from anonymous functions. They only make debugging and profiling a PITA because everything just shows up as "anonymous function", and there is no benefit to them that I'm aware of.
what you're doing is assigning unnamed function to a variable. you probably need named function expression instead ( http://kangax.github.com/nfe/ ).
var x = function x() {
console.log( arguments.callee.name );
}
x();
however I'm not sure how much cross-browser that is; there's an issue with IE6 that makes you function's name leak to the outer scope. also, arguments.callee is kind of deprecated and will result in error if you're using strict mode.
It looks like the most stupid thing, that I wrote in my life, but it's funny :D
function getName(d){
const error = new Error();
const firefoxMatch = (error.stack.split('\n')[0 + d].match(/^.*(?=#)/) || [])[0];
const chromeMatch = ((((error.stack.split('at ') || [])[1 + d] || '').match(/(^|\.| <| )(.*[^(<])( \()/) || [])[2] || '').split('.').pop();
const safariMatch = error.stack.split('\n')[0 + d];
// firefoxMatch ? console.log('firefoxMatch', firefoxMatch) : void 0;
// chromeMatch ? console.log('chromeMatch', chromeMatch) : void 0;
// safariMatch ? console.log('safariMatch', safariMatch) : void 0;
return firefoxMatch || chromeMatch || safariMatch;
}
d - depth of stack. 0 - return this function name, 1 - parent, etc.;
[0 + d] - just for understanding - what happens;
firefoxMatch - works for safari, but I had really a little time for testing, because mac's owner had returned after smoking, and drove me away :'(
Testing:
function limbo(){
for(let i = 0; i < 4; i++){
console.log(getName(i));
}
}
function lust(){
limbo();
}
function gluttony(){
lust();
}
gluttony();
Result:
Chrome:
Fitefox:
This solution was creating only just for fun! Don't use it for real projects. It does not depend on ES specification, it depends only on browser realization. After the next chrome/firefox/safari update it may be broken.
More than that there is no error (ha) processing - if d will be more than stack length - you will get an error;
For other browsers error's message pattern - you will get an error;
It must work for ES6 classes (.split('.').pop()), but you sill can get an error;
Any constructor exposes a property name, which is the function name. You access the constructor via an instance (using new) or a prototype:
function Person() {
console.log(this.constructor.name); //Person
}
var p = new Person();
console.log(p.constructor.name); //Person
console.log(Person.prototype.constructor.name); //Person
This might work for you:
function foo() { bar(); }
function bar() { console.log(bar.caller.name); }
running foo() will output "foo" or undefined if you call from an anonymous function.
It works with constructors too, in which case it would output the name of the calling constructor (eg "Foo").
More info here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller
They claim it's non-standard, but also that it's supported by all major browsers: Firefox, Safari, Chrome, Opera and IE.
You can't. Functions don't have names according to the standard (though mozilla has such an attribute) - they can only be assigned to variables with names.
Also your comment:
// access fully qualified name (ie "my.namespace.myFunc")
is inside the function my.namespace.myFunc.getFn
What you can do is return the constructor of an object created by new
So you could say
var obj = new my.namespace.myFunc();
console.info(obj.constructor); //my.namespace.myFunc
You could use this, for browsers that support Error.stack (not nearly all, probably)
function WriteSomeShitOut(){
var a = new Error().stack.match(/at (.*?) /);
console.log(a[1]);
}
WriteSomeShitOut();
of course this is for the current function, but you get the idea.
happy drooling while you code
You could use Function.name:
In most implementations of JavaScript, once you have your constructor's reference in scope, you can get its string name from its name property (e.g. Function.name, or Object.constructor.name
You could use Function.callee:
The native arguments.caller method has been deprecated, but most browsers support Function.caller, which will return the actual invoking object (its body of code):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fcaller
You could create a source map:
If what you need is the literal function signature (the "name" of it) and not the object itself, you might have to resort to something a little more customized, like creating an array reference of the API string values you'll need to access frequently. You can map them together using Object.keys() and your array of strings
You can use name property to get the function name, unless you're using an anonymous function
For example:
var Person = function Person () {
this.someMethod = function () {};
};
Person.prototype.getSomeMethodName = function () {
return this.someMethod.name;
};
var p = new Person();
// will return "", because someMethod is assigned with anonymous function
console.log(p.getSomeMethodName());
now let's try with named function
var Person = function Person () {
this.someMethod = function someMethod() {};
};
now you can use
// will return "someMethod"
p.getSomeMethodName()
You can use constructor name like:
{your_function}.prototype.constructor.name
this code simply return name of a method.
as part as ECMAScript 6 you can use Function.name method
function doSomething() {}
alert(doSomething.name); // alerts "doSomething"
I know this is a old question but lately I've been facing some similar issue while trying to decorate some React Component's methods, for debugging purposes. As people already said, arguments.caller and arguments.callee are forbidden in strict mode which is probably enabled by default in your React transpiling. You can either disable it, or I've been able to come up with another hack, because in React all class functions are named, you can actually do this:
Component.prototype.componentWillMount = function componentWillMount() {
console.log('Callee name: ', this.__proto__.constructor.toString().substr(0,30));
...
}
This worked for me.
function AbstractDomainClass() {
this.className = function() {
if (!this.$className) {
var className = this.constructor.toString();
className = className.substr('function '.length);
className = className.substr(0, className.indexOf('('));
this.$className = className;
}
return this.$className;
}
}
Test code:
var obj = new AbstractDomainClass();
expect(obj.className()).toBe('AbstractDomainClass');
I had a similar problem and I solved it as follows:
Function.prototype.myname = function() {
return this.toString()
.substr( 0, this.toString().indexOf( "(" ) )
.replace( "function ", "" );
}
This code implements, in a more comfortable fashion, one response I already read here at the top of this discussion.
Now I have a member function retrieving the name of any function object.
Here's the full script ...
<script language="javascript" TYPE="text/javascript">
Function.prototype.myname = function() {
return this.toString()
.substr( 0, this.toString().indexOf( "(" ) )
.replace("function ", "" );
}
function call_this( _fn ) { document.write( _fn.myname() ); }
function _yeaaahhh() { /* do something */ }
call_this( _yeaaahhh );
</script>
If I understood what you wanted to do, this is what I do inside a function constructor.
if (!(this instanceof arguments.callee)) {
throw "ReferenceError: " + arguments.callee.name + " is not defined";
}
This will work in ES5, ES6, all browsers and strict mode functions.
Here's how it looks with a named function.
(function myName() {
console.log(new Error().stack.split(/\r\n|\r|\n/g)[1].trim());
})();
at myName (<anonymous>:2:15)
Here's how it looks with an anonymous function.
(() => {
console.log(new Error().stack.split(/\r\n|\r|\n/g)[1].trim());
})();
at <anonymous>:2:15
A simple solution to dynamically retrieve function names [like magic variables] is the use of scoped variables.
{
function parent() {
console.log(a.name);
}; let a = parent
}
{
function child() {
console.log(a.name)
}; let a = child
};
parent();//logs parent
child();//logs child
Note: Nested functions cease to be source elements, and are hence not hoisted.
Also, this technique cannot work with anonymous functions.
Just try Function.name
const func1 = function() {};
const object = {
func2: function() {}
};
console.log(func1.name);
// expected output: "func1"
console.log(object.func2.name);
// expected output: "func2"
look here: http://www.tek-tips.com/viewthread.cfm?qid=1209619
arguments.callee.toString();
seems to be right for your needs.
Easy way to get function name from within fuction you are running.
function x(){alert(this.name)};x()
you can use Error.stack to trace the function name and exact position of where you are in it.
See stacktrace.js
I have seen usage like var f1=new Function(); but no more than that. Tried to search in Google regarding Function-class but nothing returned what I needed.
What is its significance?
Please suggest me how and when to use it. If possible give me some genuine link to study about it.
Best practice suggest you should never use a base type constructor functions. In a lot of case, use new with a base type will break the usage of typeof.
But, new Function() is valid JavaScript. Just not recommended, and not useful in most cases (var a= function() {} is equivalent).
Not that you can use the Function constructor as an eval call like so new Function('var a = 1; return a + a;'). But this can be dangerous, so use carefully.
There isn't necessarily a beneficial reason to use new Function() since you could simply create a blank function like so:
var f1 = function () {
// my function code here;
};
// calling the function
f1();
Each one will have the prototypes of Function attached to it either way.
new Function() (also new Array(), etc) should typically be avoided since it has to eval.
Technically, there really isn't a difference between these two bits of JavaScript (other answers have covered this):
var f1 = new Function();
and
var f1 = function () { };
What you can do, however, is use Function to check against the types of your variables:
var f1 = 'cat';
console.log(typeof(f1) === typeof(Function)); // false
var f2 = function () { return 'cat'; };
console.log(typeof(f2) === typeof(Function)); // true
Function objects created with the Function constructor are parsed when the function is created. This is less efficient than declaring a function and calling it within your code, because functions declared with the function statement are parsed with the rest of the code.
from MDN
EDIT
With the number of responses saying "you can make private things!" below, I'm going to add this to the top as well:
I know you can emulate private variables within a closure. That is not what I'm asking. I'm asking, given the two examples below where I'm "exporting" EVERYTHING from the closure, what is the fundamental difference between these two examples.
Given these two methods of creating objects/methods:
var test = {}
test = (function(){
var a_method = function(print_me){
return "hello "+print_me;
}
return {print_me: a_method};
})();
test.print_me2 = function(print_me2){
return "hello "+print_me2;
}
test.print_me('world');
>>> returns "hello world"
test.print_me2('world');
>>> returns "hello world"
I understand that the first method allows for private variables (which as a python developer at heart i don't really care to use), but both seem rather equivilent to me, only the first one looks "cooler" (as in all the big javascript people seem to be doing it that way) and the second way looks very passé.
So, like, what is the difference?
I've looked through the closure questions here -- most of them center around what or why do you use them; I understand their utility, I just want to know why you'd do the first over the second and what benefits it has.
I'd prefer hard evidence over conjecture -- not looking for a "this is how the cool kids are doing it" or "i heard that mozilla does better memory usage when you use a closure", but rather qualitative evidence towards one being 'better' than the other.
The difference between the methods is the anonymous function wrapper that creates a closure, but also that the first method replaces the entire object while the second method just sets a property in the existing method.
There are different ways of adding methods to an object. You can put them there when you create the object:
var test = {
print_me: function(text) { return "hello " + text; }
};
You can add a method as a property to an existing object:
var test = {};
test.print_me = function(text) { return "hello " + text; };
You can make a constructor function, and add methods to its prototype:
function Test() {}
Test.prototype.print_me = function(text) { return "hello " + text; };
var test = new Test();
As Javascript has a prototype based object model, the last one is how methods were intended to be created. The other ways are just possible because an object property can have a function as value.
You can use a function wrapper around any code where you want local variables, so you can do that with the second way of setting the property:
test.print_me2 = (function(){
var method = function(print_me2) {
return "hello "+print_me2;
}
return method;
})();
In the first example, the closure is used to keep local variables out of the global scope.
var thisIsGlobal = 2;
var test = (function () {
var thisIsLocal = 3;
return function () {
return thisIsLocal;
};
}());
What you get is a function test which when invoked returns the value of the local variable thisIsLocal. There is no way to change the value of the variable. You can be look at it as to a private variable.
The first method you present (an anonymous function which is executed immediately) keeps your program out of the global scope. Within that private scope you can decide what properties you want to expose as your API:
(function(win){
var a, b, c = 1;
function init(){
return aa(b);
}
function exit(){
if(cc()){
return a;
}
}
function aa(){
}
function bb(){
}
function cc(){
}
win.myProgram = {init: init,
exit: exit };
})(window);
// We now have access to your API from within the global namespace:
myProgram.init();
//etc
Is there a way in JavaScript to call a function without parentheses?
For example in jQuery:
$('#wrap').text("asdf"); will work and so will $.ajax(ajaxOptions);
I'm mapping a function (class) to window.$ that has a set of functions I want to be able to call with or without parentheses. Like jQuery.
Here's a code example:
function Test(asdf) {
this.test = function(testVar) { return testVar + ' asdf'; }
}
And I map Test() to $:
window.$ = new Test();
I have to call the function (class) like this:
$('asfd').test('ASDF');
But I want to be able to call it like this:
$.test('asdf');
JavaScript is extremely flexible since objects are basically a map and can contain any number of key value pairs, where the value itself can be an object and thus you get nesting. Another interesting aspect of JavaScript is that functions are themselves first class objects, so in a key value pair, you can have a function as a value.
To get something like jQuery then becomes very simple. You start off with a function (constructor function, or class if you will),
function myFunction() {
// do some awesome web 2.0 stuff
}
Since myfunction is a function and also an object, so you attach key value pairs to it as well which is what jQuery does. To verify that myFunction is also an object, do an instanceof check:
myFunction instanceof Function; // true
myFunction instanceof Object; // true
So we can add properties to a function which could be simple values, or functions themselves.
// adding a simple property that holds a number
myFunction.firstPrime = 2;
// adding a function itself as a property to myFunction
myFunction.isPrime = function(number) {
// do some magic to determine if number is prime
};
But if that is not your question, and you really want to know if you can literally call a function without using parentheses, then the answer is yes, you can, using the additions in ECMAScript 5th ed.
Here's an example of calling a function without using parentheses using Object.defineProperty and defining it as a getter:
var o = {};
Object.defineProperty(o, "helloWorld", {
get: function() {
alert("hello world");
},
set: undefined
});
o.helloWorld; // will alert "hello world"
Try this example in Chrome or Safari, or Firefox nightly.
new
You can call a function using new. The twist is, within the function this becomes an object being constructed by the function instead of whatever it would normally be.
function test () { alert('it worked'); }
...
new test; // alerts "it worked"
call and apply
You can use call or apply to call a function indirectly. You'll still need parentheses (unless you use new), but you won't be directly invoking the function with parentheses.
function message() {return "Hello crazy world!"; }
Function.prototype.toString = function() { return this.call(this); };
alert(message);
The difference in those examples is that .text() is a function on jQuery objects (instances of them, wrappers of elements), it's on $.fn (jQuery's prototype shortcut) so it's specifically for jQuery objects.
$.ajaxSetup() is a method on the jQuery object/variable itself.
If you look at the API it's easy to tell which methods are where, the jQuery.something() methods are methods on the jQuery variable/object, not related to an element set, everything else that's just .something() are the methods to run against element sets (on jQuery object instances).
For what you want to do, yes it is possible, but it doesn't make much sense, for example:
$.myFuntion = $.fn.myFunction = function() { alert('hi'); };
You should place your methods where it makes sense, if it's for a set of elements, use $.fn.myFunction and this refers to the set of elements inside. If it's a static method unrelated to an element set place it outside separately or possibly at $.myFunction.
You can try something like this
var test = {
method1 : function(bar) {
// do stuff here
alert(bar);
},
method2 : function(bar) {
// do stuff here
alert(bar);
}
};
test.method1("foo");
test.method2("fooo");
You can make a function reference, but you won't be able to pass arguments:
function funky() { alert("Get down with it"); }
obj.onclick = funky;
Use template literals:
alert`WOW`
It is cleaner and shorter, without having to rely on jQuery, call, etc.
I'm trying to get the name of the currently running function. From what I've read, this should be possible using:
(arguments.callee.toString()).match(/function\s+(\[^\s\(]+)/)
However, when I run this in Firefox and Safari (latest versions on Mac) the name is not returned.
console.log( arguments.callee ) returns the source of the function, but not the assigned name. arguments.callee.name returns an empty string.
My sample code is as follows:
var testobj = {
testfunc: function(){
console.log( (arguments.callee.toString()).match(/function\s+(\[^\s\(]+)/) );
}
}
testobj.testfunc();
You declared an anonymous function with
function(){
You should declare it as
function testfunc(){
to get the name printed.
The typical arguments.callee hacks don't work here because what you've done is assigned an anonymous function as the value for the object's 'testfunc' key. In this case the hacking even gets worse, but it can be done, as follows:
var testobj = {
testfunc: function(){
for (var attr in testobj) {
if (testobj[attr] == arguments.callee.toString()) {
alert(attr);
break;
}
}
}
}
testobj.testfunc();
On firefox 3.5, Safari 5, and Chrome 6.0 you can use:
function myFunctionName() {
alert("Name is " + arguments.callee.name );
}
myFunctionName();
You can also get the function that called the current one using arguments.callee.caller.
/function\s+(\[^\s\(]+)/
What's with the backslash before [? I don't think you want a literal square bracket here. Without that it should work.
Although I'd strongly recommend against anything to do with sniffing function name or especially sniffing caller function. Almost anything you might do using these hideous hacks will be better done using some combination of closures and lookups.
I think there's a much cleaner and elegant solution to all this. Assuming the function is a member of some higher-level object—and that's always going to be the case, even if the function's owner is "window" or some other global object, we can access the global object via the this keyword, we can access the function itself via arguments.callee and we can access all the parent's object (function) names via for (var o in this), so you should be able to get the desired information fairly easily as...
returnMyName = function() {
for (var o in this) {
if (arguments.callee===this[o]) return o;
}
};
That should be robust and avoid any weird IE browser behaviors accessing named functions, etc.
Function.prototype.getName = function(fn) {
if(Function.name || Function.prototype.name) return this.name;
return this.toString().match(/^function\s+(\w+)\s*\(/)[1];
};
First of all, the function doesn't have a name. The function name is what you put in-between function and the arguments list (...). Here's how to get a function's name (don't use the name property, as it can be changed):
var fName = arguments.callee.toString(0).match(
/^function\s*(?:\s+([\w\$]*))?\s*\(/
);
fName = (fName ? fName[1] : "");
I found that if you simply log the function object, like so:
console.log(arguments.callee)
or
console.debug(arguments.callee)
that you simply get the function name in the console log with some options.