Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I copy/clone a function in JavaScript?

Tags:

I'm using jQuery with the validators plugin. I would like to replace the "required" validator with one of my own. This is easy:

jQuery.validator.addMethod("required", function(value, element, param) {     return myRequired(value, element, param); }, jQuery.validator.messages.required); 

So far, so good. This works just fine. But what I really want to do is call my function in some cases, and the default validator for the rest. Unfortunately, this turns out to be recursive:

jQuery.validator.addMethod("required", function(value, element, param) {     // handle comboboxes with empty guids     if (someTest(element)) {         return myRequired(value, element, param);     }     return jQuery.validator.methods.required(value, element, param); }, jQuery.validator.messages.required); 

I looked at the source code for the validators, and the default implementation of "required" is defined as an anonymous method at jQuery.validator.messages.required. So there is no other (non-anonymous) reference to the function that I can use.

Storing a reference to the function externally before calling addMethod and calling the default validator via that reference makes no difference.

What I really need to do is to be able to copy the default required validator function by value instead of by reference. But after quite a bit of searching, I can't figure out how to do that. Is it possible?

If it's impossible, then I can copy the source for the original function. But that creates a maintenance problem, and I would rather not do that unless there is no "better way."

like image 295
Craig Stuntz Avatar asked Jan 15 '09 17:01

Craig Stuntz


People also ask

How many ways we can clone object in JavaScript?

JavaScript provides 3 good ways to clone objects: using spread operator, rest operator and Object.

How do you make a deep copy in JavaScript?

Copy an Object With Object. assign() was the most popular way to deep copy an object. Object. assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.

Why do we use clone in JavaScript?

"Cloning" an object in JavaScript means creating a new object with the same properties as the original object. Objects in JavaScript are stored by reference, which means that two variables can point to the same object in memory. Modifying one object variable can impact other variables.


2 Answers

Storing a reference to the function externally before calling addMethod and calling the default validator via that reference makes no difference.

That's exactly what should work.

jQuery.validator.methods.oldRequired = jQuery.validator.methods.required;  jQuery.validator.addMethod("required", function(value, element, param) {     // handle comboboxes with empty guids     if (someTest(element)) {         return myRequired(value, element, param);     }     return jQuery.validator.methods.oldRequired(value, element, param); }, jQuery.validator.messages.required); 

This should work too: (And the problem with this is solved)

var oldRequired = jQuery.validator.methods.required; jQuery.validator.addMethod("required", function(value, element, param) {     // handle comboboxes with empty guids     if (someTest(element)) {         return myRequired(value, element, param);     }     return oldRequired.call(this, value, element, param);     // return jQuery.oldRequired.apply(this, arguments); }, jQuery.validator.messages.required); 
like image 53
Georg Schölly Avatar answered Oct 06 '22 10:10

Georg Schölly


Function.prototype.clone = function() {     var fct = this;     var clone = function() {         return fct.apply(this, arguments);     };     clone.prototype = fct.prototype;     for (property in fct) {         if (fct.hasOwnProperty(property) && property !== 'prototype') {             clone[property] = fct[property];         }     }     return clone; }; 

The only bad thing with that is that the prototype isn't cloned so you can't really change it... I'm working on a way to clone any type of objects and I just have RegExp left to do. So I'll probably edit tomorrow and put the entire code (which is kind of long and isn't optimised if you only use it for functions and objects.

And to comment other answers, using eval() is totaly stupid and is way too long and the Function constructor is kind of the same. Literrals are much better. And including JQuery just for that, moreover if it doesn't work properly (and I don't think it does) isn't the brightest thing you can do.

like image 31
xavierm02 Avatar answered Oct 06 '22 09:10

xavierm02