Clean Prototype fork (good idea?) - javascript

Is there a prototype fork that doesn't come with any DOM/ajax parts? I really prefer jQuery for these, and would rather not carry the extra baggage. So far I've been using the excellent JS.Class library, which doesn't even touch built-in classes prototypes. However, I've been outgrowing its capabilities, and prototype would fill its holes.
The biggest issue is: how bad is for a library to require prototype? Even such clean one (without the dom helpers, such as $ and $$).

Prototype 2.0.
http://ajaxian.com/archives/prototype-2-0-will-not-extend-the-dom
It's not out yet, though.

Related

node.js utility library for working with objects and arrays?

Is there good utility library for working with objects and arrays.
For example functions like: extend, forEach, copying objects/arrays ect,
What is common in node.js environments? I wonder are there decent alternatives to underscore.js?
underscore.js is a pretty good default for this kind of stuff. Here's a thread on compatibility issues that may be handy.
Edit, upon you're request for something beyond underscore:
As far as I know, underscore has become the defacto standard when you're looking for additional array operations (much like jQuery for DOM manipulation). Joyent maintains a pretty thorough manifest of node.js compatible modules, and the only seemingly comparable utility would appear to be an experimental library called fjs with an emphasis on currying (and judging from the source, most of the functionality comes from extending underscore functions anyway). There might be something else out there, but as far as I know nothing with the penetration and maturity of underscore.
Yet another edit - here are a handful of older libraries if you're so curious, but their maintenance has fallen off a bit - valentine, wu.js, Functional, and Sugar. Functional and valentine may be a bit thinner; wu.js looks to be about the same and sugar is even fatter.
lodash is a "drop-in replacement* for underscore.js" that you may also want to consider.
Lo-Dash v0.7.0 has been tested in at least Chrome 5-21, Firefox 1-15, IE 6-9, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.8, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5
For extend specifically, you can use Node's built-in util._extend() function.
var
extend = require('util')._extend,
x = {a:1},
y = extend({}, x);
Source code of Node's _extend function: https://github.com/joyent/node/blob/master/lib/util.js#L563
Have a look at Ramdajs: http://ramdajs.com/0.22.1/index.html
The primary distinguishing features of Ramda are:
Ramda emphasizes a purer functional style. Immutability and
side-effect free functions are at the heart of its design philosophy.
This can help you get the job done with simple, elegant code.
Ramda functions are automatically curried. This allows you to easily
build up new functions from old ones simply by not supplying the final
parameters.
The parameters to Ramda functions are arranged to make it convenient
for currying. The data to be operated on is generally supplied last.
The last two points together make it very easy to build functions as
sequences of simpler functions, each of which transforms the data and
passes it along to the next. Ramda is designed to support this style
of coding.

Revisiting extending native prototypes after ECMAScript 5

Recently, given the changes to defining properties in ECMAScript 5, I have revisited the question of whether we can safely extend the native JavaScript prototypes. In truth, all along I have extended prototypes like Array and Function, but I avoided doing so with Object, for the obvious reasons. In unit testing with Jasmine, by adding Object.prototype specs to specs for my own personal framework, extending Object.prototype with non-enumerable functions has appeared to be safe. Data properties like a "type" property, however, with getters/setters that do any unusual processing have had unintended consequences. There is still the possibility of conflicts with other libraries--though in my work, that hardly ever comes up. Nevertheless, as long as the functions are not enumerable, it looks like extending Object.prototype can be safe.
What do you think? Is it safe to extend Object.prototype now? Please discuss.
Extending objects native to JavaScript might become a little safer, through many collision concerns still stand. Generally, unless you're extending object to support standartized behavior from more recent standard it really would be still much safer to introduce wrapper - it is much easier to do things right way when you're the only one in control.
Speaking of objects native to environment (DOM elements and nodes, AJAX stuff), new JS standard still don't give and, arguably, can't give you any guarantee about any interaction with those except what defined in their interface standard. Never forget that they're potentially accessible through many different scripting engines and thus not need to be tailored for quirks of one specific language - JS. So recommendation to not extend those either still stands as well.
The definitive, absolute answer is ...
"It depends." :)
Extending any built in JavaScript object can be perfectly safe or it can be a complete disaster. It depends on what you are doing and how you are doing it.
Use smart practices and common sense and test the hell-out-of-it.

object.prototype===object.fn history

Calling all JS historians.
A common pattern is to alias a class' prototype to fn, which is less verbose.
Where did the object.prototype===object.fn convention originate in JavaScript?
I see many libraries using it.
Just curious.
I believe this practice comes from original jQuery code where author wanted to shield developers from complexity (or natural beauty) of JavaScript native feature - prototypes.
Another potential reason could be the need to remove possible connotation [with existing PrototypeJS library] of the internal jQuery library prototype aspect.

Should I be using prototypes if I don't require inheritance or optimization

If my site doesn't require any sort of optimization and my object structure is fairly flat and so there is no need for inheritance, should I be using prototypes at all:
MyObject.prototype.<something>
I refer to this question Javascript when to use prototypes and various writings by John Resig who seems to focus on the performance values of prototype.
I find using the module pattern to define objects and their functions easier to read and manage and as michielvoo mentions, premature optimization tends to cause more harm than good.
Are there any other benefits or uses cases for prototype?
It's a code organization pattern.
There are two good ways to share methods across objects
var oneWay = Object.create(bagOfMethods);
// some value of extend that is sensible
var otherWay = extend({}, bagOfMethods);
The only real advantage prototypes gives is that the link between oneWay and bagOfMethods is live.
Having a live link allows really powerful extensions and monkey patching.
An example is Object.prototype.methodNowLivesOnAllInstances = function () { };
This is a way of doing "asynchronous" programming, you can extend the "class" without worrying whether all instances get the new method.
A note on the modular pattern, it's bloated and not needed. Use a module builder like modul8 or browserify instead.
Well, if you refer to that question, the accepted answer for which starts out by calling it an optimization, then I'd say don't go for premature optimization. You may never reap any benefits (see: YAGNI) and you make your job more difficult, since you yourself (and your team?) prefer the module pattern.

Why is it frowned upon to modify JavaScript object's prototypes?

I've come across a few comments here and there about how it's frowned upon to modify a JavaScript object's prototype? I personally don't see how it could be a problem. For instance extending the Array object to have map and include methods or to create more robust Date methods?
The problem is that prototype can be modified in several places. For example one library will add map method to Array's prototype and your own code will add the same but with another purpose. So one implementation will be broken.
Mostly because of namespace collisions. I know the Prototype framework has had many problems with keeping their names different from the ones included natively.
There are two major methods of providing utilities to people..
Prototyping
Adding a function to an Object's prototype. MooTools and Prototype do this.
Advantages:
Super easy access.
Disadvantages:
Can use a lot of system memory. While modern browsers just fetch an instance of the property from the constructor, some older browsers store a separate instance of each property for each instance of the constructor.
Not necessarily always available.
What I mean by "not available" is this:
Imagine you have a NodeList from document.getElementsByTagName and you want to iterate through them. You can't do..
document.getElementsByTagName('p').map(function () { ... });
..because it's a NodeList, not an Array. The above will give you an error something like: Uncaught TypeError: [object NodeList] doesn't have method 'map'.
I should note that there are very simple ways to convert NodeList's and other Array-like
Objects into real arrays.
Collecting
Creating a brand new global variable and stock piling utilities on it. jQuery and Dojo do this.
Advantages:
Always there.
Low memory usage.
Disadvantages:
Not placed quite as nicely.
Can feel awkward to use at times.
With this method you still couldn't do..
document.getElementsByTagName('p').map(function () { ... });
..but you could do..
jQuery.map(document.getElementsByTagName('p'), function () { ... });
..but as pointed out by Matt, in usual use, you would do the above with..
jQuery('p').map(function () { ... });
Which is better?
Ultimately, it's up to you. If you're OK with the risk of being overwritten/overwriting, then I would highly recommend prototyping. It's the style I prefer and I feel that the risks are worth the results. If you're not as sure about it as me, then collecting is a fine style too. They both have advantages and disadvantages but all and all, they usually produce the same end result.
As bjornd pointed out, monkey-patching is a problem only when there are multiple libraries involved. Therefore its not a good practice to do it if you are writing reusable libraries. However, it still remains the best technique out there to iron out cross-browser compatibility issues when using host objects in javascript.
See this blog post from 2009 (or the Wayback Machine original) for a real incident when prototype.js and json2.js are used together.
There is an excellent article from Nicholas C. Zakas explaining why this practice is not something that should be in the mind of any programmer during a team or customer project (maybe you can do some tweaks for educational purpose, but not for general project use).
Maintainable JavaScript: Don’t modify objects you don’t own:
https://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
In addition to the other answers, an even more permanent problem that can arise from modifying built-in objects is that if the non-standard change gets used on enough sites, future versions of ECMAScript will be unable to define prototype methods using the same name. See here:
This is exactly what happened with Array.prototype.flatten and Array.prototype.contains. In short, the specification was written up for those methods, their proposals got to stage 3, and then browsers started shipping it. But, in both cases, it was found that there were ancient libraries which patched the built-in Array object with their own methods with the same name as the new methods, and had different behavior; as a result, websites broke, the browsers had to back out of their implementations of the new methods, and the specification had to be edited. (The methods were renamed.)
For example, there is currently a proposal for String.prototype.replaceAll. If you ship a library which gets widely used, and that library monkeypatches a custom non-standard method onto String.prototype.replaceAll, the replaceAll name will no longer be usable by the specification-writers; it will have to be changed before browsers can implement it.

Categories

Resources