Native prototypes vs $.extension()
At work, we use jQuery. Shortly after 开发者_StackOverflow社区we started using it, I saw that a couple developers were adding functions to a file jquery-extensions.js. Inside, I found a whole bunch of methods added to $
that essentially amount to static methods on jQuery. Here's a few:
$.formatString(str, args) {
...
}
$.objectToArray(obj) {
...
}
Etc. None of them actually use anything to do with jQuery. This struck me as odd.
Eventually, we needed a function in our library to localize dates. My solution was to create:
Date.prototype.toLocaleDate = function() {
...
}
Date.parseLocalDate = function() {
...
}
Shortly after doing this, I get a Sr. Developer coming up to me asking me what I think I'm doing. He tells me that here, where I work, we don't create prototypes because they're evil. The only reasons he gave was that they're fundamentally a poor language features because they "can be abused" and that it's confusing to see prototypes (e.g. how do I know new Date().toLocaleDate() is a prototype and not native ECMAScript). By using $.formatString(...)
instead of "blah blah".formatString(...)
, we're keeping it clear that anything with a $ is not part of native JavaScript.
Those reasons seem a bit silly, but I offered a compromise so he wouldn't have to remember whether a method was an prototype—prefix the prototype function name with $
:
String.prototype.$format = function() {
...
}
"blah blah".$format(...);
That was quickly dismissed and now I'm having to add these $.myPrototypeAsAFauxStaticMethodOnjQuery() functions everywhere.
Am I the only one that thinks this practice is stupid?
The native prototypes debate is a bit tired, there are valid points on both sides, I'll try to summarize them in hope it might be useful to see the big picture.
contra There's no need to extend native prototypes. You've got everything you need.
pro JS standard library is scarce to the extreme. Arrays and strings are lacking many vital features.
contra Use functions or your own "namespaces".
pro Methods like foo.trim()
are far more in the spirit of the language than functions like org.blah.trim(foo)
. Everything is object in javascript and let it be that way.
contra Native JS objects are "reserved" for the language designers. Our methods can accidentally override newly added built-ins.
pro Open objects is a great feature and it would be silly not to use it. A new Javascript version is not something that happens every day and additions to the standard are well known in advance.
contra Extending native prototypes is confusing, because there's no distinction between our and native methods.
pro JS standard library is small and well documented. We javascript developers are supposed to know native methods' names.
contra Extending prototypes can lead to namespace conflicts.
pro Yes, but this can happen with global functions or well-known global objects (like $
) as well.
contra Custom methods are enumerable.
pro Yes, but there's hasOwnProperty
to the rescue. Wrap it in your own enumerator function and stop using raw for..in
loops with objects.
(not a real answer, hence CW)
- Senior titles are often overrated.
- There are a lot of people who don't understand prototypal inheritance.
- Even though extending the prototype of native JavaScript objects is legal, don't do it. You run the risk of clashing with frameworks.
- It doesn't make sense to hijack
$
for non-jQuery utility functions. Why not use the company's own namespace? If you need to be concise, use$$
etc.
I think it's not stupid!, But It's more beautiful to use prototype!, But then again who cares about beauty? Your code eventually will be scary and will suck, But if it's well documented and consistent you'll never need to think about these issues!
精彩评论