jQueryPlugin: return this vs return this.each() - javascript

Yes, there are many topics about that, but I still didn't get it.
I prepared two jsfiddle:
return this
return this.each()
What's the difference?
There any many answers, but my examples show the same output. So some some of these answers might be wrong!?
what does "return this.each()" do in jQuery?
"It allows for one to call a plugin or an event on a bunch of elements and then apply that same function or event to all of them" --> work's with return this as well
"It allows you to chain multiple functions" --> same here
"Allows you to do things like: $("mySelector").foo().show();" --> I still can do this as well, when I use return this
I also created another jsfiddle that shows - in my opinion - that it doesn't matter if you're wrapping you code into return this.each();:
http://jsfiddle.net/7S3MW/1/
The Chrome Console shows the same output!
So what's the difference?

Two things:
Your examples are flawed in that they do exactly the same thing to each element.
The real issue isn't return this versus return this.each, the issue is this versus this.each.
For (1), consider the difference between this plugin:
(function($) {
$.fn.mangle = function(options) {
this.append(' - ' + this.data('x'));
return this;
};
})(jQuery);
Demo: http://jsfiddle.net/ambiguous/eyHeu/
And this plugin:
(function($) {
$.fn.mangle = function(options) {
return this.each(function() {
$(this).append(' - ' + $(this).data('x'));
});
};
})(jQuery);
Demo: http://jsfiddle.net/ambiguous/5dMMH/
So you see, you need to use this.each if you need to treat the individual elements in the this set differently. You would have similar effects if your plugin had to attach element-specific data to each element: if you didn't use each then you'd end up attaching the exact same piece of data to all of the elements inside this and that would just leave you confused about why information is bleeding all over the place.
For (2), it doesn't matter if you return this or return this.each(... since x.each(...) returns x anyway.

Let me show you two "equivalent" pieces of code that could clarify your question:
With jQuery "each" function:
(function($) {
$.fn.mangle = function(options) {
return this.each(function() {
$(this).append(' - ' + $(this).data('x'));
});
};
})(jQuery);
Without jQuery "each" function:
(function($) {
$.fn.mangle = function(options) {
var objs = this;
for (var i=0; i<objs.length; i++) {
var obj = objs[i];
$(obj).append(' - ' + $(obj).data('x'));
};
return this;
};
})(jQuery);
So, basically, each function is used to apply some code to all elements contained in this object (as this usually refers to a group of elements returned by a jQuery selector) and return the reference to this (as each function always returns that reference -to allow chaining calls-)
As a side note: The second approach (-for loop-) is faster (notably on old browsers) than former one (-each function-).

They are both exactly the same. .each() returns this, so return this.each() is EXACTLY the same as this.each(); return this;
Edit: your newest fiddle's makeRed method doesn't return this and is therefore not chainable.

Related

javascript: prototype in javascript like reflection in c#, is it possible? [duplicate]

In Ruby I think you can call a method that hasn't been defined and yet capture the name of the method called and do processing of this method at runtime.
Can Javascript do the same kind of thing ?
method_missing does not fit well with JavaScript for the same reason it does not exist in Python: in both languages, methods are just attributes that happen to be functions; and objects often have public attributes that are not callable. Contrast with Ruby, where the public interface of an object is 100% methods.
What is needed in JavaScript is a hook to catch access to missing attributes, whether they are methods or not. Python has it: see the __getattr__ special method.
The __noSuchMethod__ proposal by Mozilla introduced yet another inconsistency in a language riddled with them.
The way forward for JavaScript is the Proxy mechanism (also in ECMAscript Harmony), which is closer to the Python protocol for customizing attribute access than to Ruby's method_missing.
The ruby feature that you are explaining is called "method_missing" http://rubylearning.com/satishtalim/ruby_method_missing.htm.
It's a brand new feature that is present only in some browsers like Firefox (in the spider monkey Javascript engine). In SpiderMonkey it's called "__noSuchMethod__" https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/NoSuchMethod
Please read this article from Yehuda Katz http://yehudakatz.com/2008/08/18/method_missing-in-javascript/ for more details about the upcoming implementation.
Not at the moment, no. There is a proposal for ECMAScript Harmony, called proxies, which implements a similar (actually, much more powerful) feature, but ECMAScript Harmony isn't out yet and probably won't be for a couple of years.
You can use the Proxy class.
var myObj = {
someAttr: 'foo'
};
var p = new Proxy(myObj, {
get: function (target, methodOrAttributeName) {
// target is the first argument passed into new Proxy, aka. target is myObj
// First give the target a chance to handle it
if (Object.keys(target).indexOf(methodOrAttributeName) !== -1) {
return target[methodOrAttributeName];
}
// If the target did not have the method/attribute return whatever we want
// Explicitly handle certain cases
if (methodOrAttributeName === 'specialPants') {
return 'trousers';
}
// return our generic method_missing function
return function () {
// Use the special "arguments" object to access a variable number arguments
return 'For show, myObj.someAttr="' + target.someAttr + '" and "'
+ methodOrAttributeName + '" called with: ['
+ Array.prototype.slice.call(arguments).join(',') + ']';
}
}
});
console.log(p.specialPants);
// outputs: trousers
console.log(p.unknownMethod('hi', 'bye', 'ok'));
// outputs:
// For show, myObj.someAttr="foo" and "unknownMethod" called with: [hi,bye,ok]
About
You would use p in place of myObj.
You should be careful with get because it intercepts all attribute requests of p. So, p.specialPants() would result in an error because specialPants returns a string and not a function.
What's really going on with unknownMethod is equivalent to the following:
var unk = p.unkownMethod;
unk('hi', 'bye', 'ok');
This works because functions are objects in javascript.
Bonus
If you know the number of arguments you expect, you can declare them as normal in the returned function.
eg:
...
get: function (target, name) {
return function(expectedArg1, expectedArg2) {
...
I've created a library for javascript that let you use method_missing in javascript: https://github.com/ramadis/unmiss
It uses ES6 Proxies to work. Here is an example using ES6 Class inheritance. However you can also use decorators to achieve the same results.
import { MethodMissingClass } from 'unmiss'
class Example extends MethodMissingClass {
methodMissing(name, ...args) {
console.log(`Method ${name} was called with arguments: ${args.join(' ')}`);
}
}
const instance = new Example;
instance.what('is', 'this');
> Method what was called with arguments: is this
No, there is no metaprogramming capability in javascript directly analogous to ruby's method_missing hook. The interpreter simply raises an Error which the calling code can catch but cannot be detected by the object being accessed. There are some answers here about defining functions at run time, but that's not the same thing. You can do lots of metaprogramming, changing specific instances of objects, defining functions, doing functional things like memoizing and decorators. But there's no dynamic metaprogramming of missing functions as there is in ruby or python.
I came to this question because I was looking for a way to fall through to another object if the method wasn't present on the first object. It's not quite as flexible as what your asking - for instance if a method is missing from both then it will fail.
I was thinking of doing this for a little library I've got that helps configure extjs objects in a way that also makes them more testable. I had seperate calls to actually get hold of the objects for interaction and thought this might be a nice way of sticking those calls together by effectively returning an augmented type
I can think of two ways of doing this:
Prototypes
You can do this using prototypes - as stuff falls through to the prototype if it isn't on the actual object. It seems like this wouldn't work if the set of functions you want drop through to use the this keyword - obviously your object wont know or care about stuff that the other one knows about.
If its all your own code and you aren't using this and constructors ... which is a good idea for lots of reasons then you can do it like this:
var makeHorse = function () {
var neigh = "neigh";
return {
doTheNoise: function () {
return neigh + " is all im saying"
},
setNeigh: function (newNoise) {
neigh = newNoise;
}
}
};
var createSomething = function (fallThrough) {
var constructor = function () {};
constructor.prototype = fallThrough;
var instance = new constructor();
instance.someMethod = function () {
console.log("aaaaa");
};
instance.callTheOther = function () {
var theNoise = instance.doTheNoise();
console.log(theNoise);
};
return instance;
};
var firstHorse = makeHorse();
var secondHorse = makeHorse();
secondHorse.setNeigh("mooo");
var firstWrapper = createSomething(firstHorse);
var secondWrapper = createSomething(secondHorse);
var nothingWrapper = createSomething();
firstWrapper.someMethod();
firstWrapper.callTheOther();
console.log(firstWrapper.doTheNoise());
secondWrapper.someMethod();
secondWrapper.callTheOther();
console.log(secondWrapper.doTheNoise());
nothingWrapper.someMethod();
//this call fails as we dont have this method on the fall through object (which is undefined)
console.log(nothingWrapper.doTheNoise());
This doesn't work for my use case as the extjs guys have not only mistakenly used 'this' they've also built a whole crazy classical inheritance type system on the principal of using prototypes and 'this'.
This is actually the first time I've used prototypes/constructors and I was slightly baffled that you can't just set the prototype - you also have to use a constructor. There is a magic field in objects (at least in firefox) call __proto which is basically the real prototype. it seems the actual prototype field is only used at construction time... how confusing!
Copying methods
This method is probably more expensive but seems more elegant to me and will also work on code that is using this (eg so you can use it to wrap library objects). It will also work on stuff written using the functional/closure style aswell - I've just illustrated it with this/constructors to show it works with stuff like that.
Here's the mods:
//this is now a constructor
var MakeHorse = function () {
this.neigh = "neigh";
};
MakeHorse.prototype.doTheNoise = function () {
return this.neigh + " is all im saying"
};
MakeHorse.prototype.setNeigh = function (newNoise) {
this.neigh = newNoise;
};
var createSomething = function (fallThrough) {
var instance = {
someMethod : function () {
console.log("aaaaa");
},
callTheOther : function () {
//note this has had to change to directly call the fallThrough object
var theNoise = fallThrough.doTheNoise();
console.log(theNoise);
}
};
//copy stuff over but not if it already exists
for (var propertyName in fallThrough)
if (!instance.hasOwnProperty(propertyName))
instance[propertyName] = fallThrough[propertyName];
return instance;
};
var firstHorse = new MakeHorse();
var secondHorse = new MakeHorse();
secondHorse.setNeigh("mooo");
var firstWrapper = createSomething(firstHorse);
var secondWrapper = createSomething(secondHorse);
var nothingWrapper = createSomething();
firstWrapper.someMethod();
firstWrapper.callTheOther();
console.log(firstWrapper.doTheNoise());
secondWrapper.someMethod();
secondWrapper.callTheOther();
console.log(secondWrapper.doTheNoise());
nothingWrapper.someMethod();
//this call fails as we dont have this method on the fall through object (which is undefined)
console.log(nothingWrapper.doTheNoise());
I was actually anticipating having to use bind in there somewhere but it appears not to be necessary.
Not to my knowledge, but you can simulate it by initializing the function to null at first and then replacing the implementation later.
var foo = null;
var bar = function() { alert(foo()); } // Appear to use foo before definition
// ...
foo = function() { return "ABC"; } /* Define the function */
bar(); /* Alert box pops up with "ABC" */
This trick is similar to a C# trick for implementing recursive lambdas, as described here.
The only downside is that if you do use foo before it's defined, you'll get an error for trying to call null as though it were a function, rather than a more descriptive error message. But you would expect to get some error message for using a function before it's defined.

Get name of prototype object

This question just got upvoted so can update question with what I did
I solved it by iterating over the window object (or user specified object root) and when I found the correct instance I backtracked and got the name from the index. The final solution can be found here
https://github.com/AndersMalmgren/Knockout.BindingConventions
Update end
I'm planning on writing a convention over configuration template source engine for KnockoutJS / MVC.
I'm started with a little client side POC and ran into a show stopper right away
My plan is use this syntax or something similar
MyApp.EditCustomersViewModel = function() {
ko.templates.loadView(this);
};
When doing this it will check the tamplate cache or fetch the templates from server using the object name as key.
The problem is I cant get the name of the prototype object, i tried this
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
If works for objects defined like this
function MyClass() {
}
If you add a prototype to the above object it will not work, or if you define it like this
MyApp = {};
MyApp.MyClass = function() {
};
Prototype and scoping is two musts so this is a showstopper, any ideas?
Fiddle: http://jsfiddle.net/aRWLA/
edit: The background for this is like this.
On the server you have structure like this
Templates\ [ViewName]\index.html
Templates\ [ViewName]\sub-model-template.html
on the client you will do
MyApp.EditCustomersViewModel = function() {
ko.templates.loadView(this);
};
which will generate a ajax request with the objects name as key, which will fetch all the templates for the view in question
Only hoisted functions (function someFunc() {) have a retrievable name.
Assigned functions do not, because you are not technically naming the function but creating an anonymous function and assigning a reference to it (in the memory) to a named variable.
So it's the var, not the function, that is named.
This makes the very idea of retrieving function names pretty much a none-starter, since in any vaguely mature pattern you'll be writing methods, not hoisted functions - and methods of course are assigned functions.
Named expressions (see other answers) are a partial workaround but these have other issues - not least lack of support in older IEs.
(Sidenote: I've long expected browser vendors to build around this such that the names of assigned functions became retrievable, but no joy yet AFAIK.)
I think you problem in improper replacing function prototype: if you replace function prototype object then you must preserve constructor member in prototype:
function Test1() {
}
Test1.prototype={
constructor: Test1
};
MyApp={};
MyApp.MyClass=function MyClass(){
};
MyApp.MyClass.prototype={
constructor: MyApp.MyClass
};
Your example: http://jsfiddle.net/aRWLA/1/
Modified example: http://jsfiddle.net/aRWLA/2/
You can make use of named function expressions:
MyApp.MyClass = function MyClass() { ... };
But note that (suprise) they don't work correctly in all versions of IE.
See: http://kangax.github.com/nfe/
THIS DOES NOT ANSWER THE QUESTION
However, the code might be useful to other people, so I'm leaving it here, just in case. I don't expect upvotes, but please don't abuse it for downvoting either. Thanks.
I don't know your use case, as such I think you've got a design issue - the problem you describe shouldn't happen in practice.
But let's say you do need to have this working. An easy way to do what you need would be something like:
function findNamed(obj, fn){
for(var p in obj)
if(obj[p] === fn)
return p;
return false;
}
var m = {};
m.MyClass = function() {};
console.log(findNamed(m, m.MyClass));
Of course, the solution could be made into a more appropriate OOP form, but this is just to give an idea.
To replicate your use case, it would look like:
m.MyClass = function() {
findNamed(this, arguments.callee);
};
So, the final code is:
Object.prototype.getNameOfCall = function(fn) {
for(var p in this)
if(this[p] === fn)
return p;
throw "Callback not in object.";
};
var m = {};
m.MyClass = function() {
console.log(this.getNameOfCall(arguments.callee)); // MyClass
};
m.MyClass(); // test it out

Prototypejs conflicting with Underscore

EDIT:
I'm putting this at the top because ive finally figured out the actual problem.
Prototypejs is adding an Array.reduce function which is intefering with underscore (see: https://github.com/documentcloud/underscore/issues/7)
There doesn't seem to be anything conclusive here other than "use prototype > 1.6.1) but I can't control what prototype is used unfortunately. Other than altering the _.reduce method to not use the native function or proxying any method that uses reduce (see comments) I can't see any nice way of fixing this issue.
I'm having an issue with Prototypejs being included on the same page as my javascript "app" where I am using underscore.
It seems that whenever I try and use the function _.unique it is actually calling the prototype function instead, this is inside a closure and I am using requirejs to load in _. When I change the order of the libraries included so my app is included before prototype then everything works fine, unfortunately I cannot use this as a solution as I will have no control of how this is included in any page.
I was wondering if anyone had come across this problem before and had a possible solution where _.unique will always call the underscore function rather than any global prototype function called unique.
Thanks
EDIT:
I actually think I might be wrong about the unique method being overridden actually. I have just added some console logs into the underscore function and it seems it is being called but its returning empty:
_.uniq = _.unique = function(array, isSorted, iterator) {
console.log("called this");
console.log(array);
var initial = iterator ? _.map(array, iterator) : array;
var results = [];
// The `isSorted` flag is irrelevant if the array only contains two elements.
if (array.length < 3) isSorted = true;
_.reduce(initial, function (memo, value, index) {
console.log("it never gets here");
if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {
memo.push(value);
results.push(array[index]);
}
return memo;
}, []);
console.log(results);
return results;
};
The first console log gives me "[1,2,3,1]" whereas the second gives me "[]". This does only seem to happen when prototype is included on the page though, so something is going on with it.
Ive added another log (it never gets here) which is ever executed. It looks like underscore is executing the "native" reduce method which is the one provided by Prototypejs which doesnt take an iterator.
Yes, Prototype.js overrides reduce, that's really a bad idea. If reduce is the only thing that Prototype.js messed, so how about set Array.prototype.reduce to null just at the start of _.uniq? Seems that _.intersection and _.union both rely on _.uniq.
_.uniq = _.unique = function(array, isSorted, iterator) {
var keepIt = Array.prototype.reduce;
Array.prototype.reduce = null;
//....
Array.prototype.reduce = keepIt;
};

Is it possible to get the event object for the "current" or "last" event, without receiving it as argument in the handler?

I'm trying to modify the behaviour or a JavaScript library, basically by monkeypatching it (no, there is no better way).
At a certain point in the code, I need to know whether Shift is pressed or not. If the event handler in this library were properly written, it'd receive the "event" as its first parameter, but unfortunately, it isn't (events are wired with onclick inline in the HTML)
So, I'm trying to see if jQuery "stores" the last event object somewhere, or if there is some other way to access it.
Essentially, what I want is "window.event", but ideally I'd like for it to work on Firefox.
Any ideas, besides adding a global onKeyDown handler to the document and keeping track of the state of Shift myself? That feels a bit overkill and a bit too global for my taste.
Can you wrap the function they are using as their event handler? Take this contrived example:
var someObject = {
keyDownListener: function() {
alert('something was pressed!');
}
}
We could replace keyDownListener with our own method that accepts the event object.
var someObject = {
keyDownListener: function() {
alert('something was pressed!');
}
}
var oldKeyDownListener = someObject.keyDownListener;
someObject.keyDownListener = function(event) {
oldKeyDownListener(); // Call the original
// Do anything we need to do here (or before we call the old one!)
}
If you can get inside the function, you can also inspect the arguments object. Your event object should be in there (the first item, I believe).
var f = function() {
console.log(arguments);
}
f(); //= Logs []
f(1); //= Logs [1]
f(1, 'something'); //= Logs [1, 'something']
EDIT (In response to the comment below).
If you can "hijack" the method, here's ONE way you could it. I'm not certain if this is a good approach but if you have all these constraints, it will get you what you want. Basically what this code does is it searches for any elements that have an onclick attribute on them and changes the method signature to include the event object.
We can then wrap the original listener to pull the event object out of arguments and then pass execution back to the original function.
Doing this will get you what you want (I think?). See this code:
HTML:
Click Me​
JavaScript:
window.myFunction = function(one, two, three) {
console.log("one: " + one + ", two: " + two + ", three: " + three);
}
var originalMyFunction = window.myFunction;
window.myFunction = function() {
var event = arguments[arguments.length - 1]; // The last item in the arguments array is our event object.
console.log(event);
originalMyFunction.apply(this, arguments);
}
$('[onclick]').each(function() {
var s = $(this).attr('onclick');
var lastIndex = s.lastIndexOf(')');
var s2 = s.substring(0, lastIndex);
var s3 = s.substring(lastIndex, s.length);
var s4 = s2 + ', event' + s3;
$(this).attr('onclick', s4);
});
You can see it working in this fiddle: http://jsfiddle.net/84KvV/
EDIT 2
If you wanna get really fancy with it, you could even automate the wrapping of the functions. See this fiddle: http://jsfiddle.net/84KvV/2/.
Please note that this is expecting the function strings to be in a certain format so that it can parse it (functionName(...)). If it's not that in that format, this exact code will not work :)
As mentioned in my comment, it IS possible to make window.event exist in browsers that are not IE. It requires you to wrap attachEvent/addEventListener. It would go something like this:
var oldAddEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function(type, listener, useCapture) {
var wrapped = function(event) {
window.event = event;
listener(arguments);
}
oldAddEventListener.call(this, type, wrapped , useCapture);
}
As I said, I'm not sure if this will work for inline event listeners, but it might :) If not, at least it's here as a reference for those looking for something similar.
function eventlessHandler(myVal) {
var event = window.event || eventlessHandler.caller.arguments[0];
// some work
}
It may be needed traverse .caller several times depending on actual call chain.
Tested this on IE6, IE11 and latest Chrome. Should work on most other browsers too.
See also How do you find out the caller function in JavaScript?.

Can I copy/clone a function in JavaScript?

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."
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);
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.
Here is an updated answer
var newFunc = oldFunc.bind({}); //clones the function with '{}' acting as it's new 'this' parameter
However .bind is a new feature of JavaScript there is however a workaround from Mdn
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
Additionally it does not clone the function additional properties.
Note: As #gsnedder pointed out : the bound statement, "this" argument u supplied (blank {} above). Will persist for any future calls of the function, regardless of over-riding via the apply()/call() functions.
This can be used both to your advantage, or disadvantage depending on how you deal with it.
I think you're just missing a bit of scoping. Try this:
jQuery.validator.methods._required = 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._required.call(this, value, element, param);
}, jQuery.validator.messages.required);
(this should only be a comment for Can I copy/clone a function in JavaScript? ... unfortunately with rep < 50 can only post)
Function.prototype.clone=function(){
return eval( '('+this.toString()+')' );
}
suffices, or even
Object.prototype.clone=function(){
return eval( '('+this.toString()+')' );
}
thoughts on efficiency:
human efficiency is far more important than squandering human
resources to optimize or improve a machine's "life"
computers and automated systems are supposed to reduce human effort
not increase it
computational overhead must severely impact a result's palatability
for human consumption, by many many people, to justify investing
effort in optimizing code that often becomes more obscure, arcane and
so esoteric that it can no longer be understood by a stable of
programmers after hours of trying to "comprehend" the logic
on cloning: this question can be quite rhetorical
what does it mean to "clone" a javascript object? especially in the context of recursive function theory
a common theme to rationalize cloning is that it isolates and "protects" an originator from its doppelgänger changes
if a = new Object(); b = new Object(); are a and b clones? how about o = Object; a = new o(); b = new o();
is it really required?
where does cloning stop? are the prototypical attributes to be
isolated also so a cloned object's change of these does not affect
instances not associated with the cloned object? in which case
cloning must go all the way up the prototypical chain to the
primitive constructors which themselves would need to be somehow
cloned and isolated (one trick in a browser is to open a new window and repopulate it with the caveat that opener . etc. can still leak cross-effects)
if you want to clone a function , try this :
Function.prototype.clone=function(){
return eval('['+this.toString()+']')[0];
}
Sounds like there's no 'better way'. I guess you could try making a custom required function for your own eg:
jQuery.validator.addMethod("customRequired", function(value, element, param) {
return myRequired(value, element, param);
}, jQuery.validator.messages.required);
Sounds like you've already tried everything else. Apologies if I misunderstood the question.
Answering the previous post, when I need to share a constructor function, while keeping distinct prototype, I use a wrapper in a new Function :
`
init_from_arg_obj = function () {
return new Function('init', 'for (var i in init) this[i] = init[i];');
};
constructor_A = init_from_arg_obj();
constructor_A.prototype = {a: 'A'};
constructor_B = init_from_arg_obj();
constructor_B.prototype = {b: 'B'};
`
I run several tests to verify that this does not slow execution on good JS engines.

Categories