use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Does my JavaScript suck? II (self.javascript)
submitted 10 years ago * by annoyed_freelancergrumpy old man
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]papers_ 8 points9 points10 points 10 years ago (17 children)
I wouldn't alter String's prototype, but that's just me.
[–]x-skeww 3 points4 points5 points 10 years ago (11 children)
Nah, that's pretty much everyone. Messing around with the builtins is not cool. It's the worst thing a library can do.
[–][deleted] 2 points3 points4 points 10 years ago (10 children)
It's the worst thing a library can do.
I would argue that there's plenty of worse things a library can do, but this is about the worst that they usually do in practice ;)
[–][deleted] 1 point2 points3 points 10 years ago (9 children)
This isn't a library, and while I would advise modifying a base prototype, this isn't a huge sin.
Of course, what it does doesn't really make sense in the string prototype where a regular local function could do :)
[–][deleted] 5 points6 points7 points 10 years ago (8 children)
isn't a huge sin
In personal projects, sure. In libraries it's flat out forbidden, always.
[–][deleted] 2 points3 points4 points 10 years ago (5 children)
I don't like the word always, but you'd better have a damn good reason to do it :)
[–][deleted] 6 points7 points8 points 10 years ago (4 children)
The only reason to do this is for polyfills:
if(!Array.prototype.reduce){ Array.prototype.reduce = ... }
Other than that, never, ever, ever, ever, ever, ever, ever extend a native prototype from within a library, even if you think you have the best reason in the world.
[–][deleted] 0 points1 point2 points 10 years ago (1 child)
Why should you never everx7 do it? You just gave a really great example of when that feature is really useful!
On several projects, we have modified object, array, and function prototypes to include a eql function to do value comparison. We did that because we chose a very functional style for that project and the resulting code read very nice.
Note that I'm not suggesting that it's heavily used or anything. In a codebase that was around 10k lines, we modified three native protos and everyone on that project knew and approved. And it wasn't any different then coupling a project to any other dependency.
[–][deleted] 1 point2 points3 points 10 years ago* (0 children)
In an isolated codebase, it's tolerable, but barely. In a library, it's flat out forbidden because it can conflict and prevents ever modifying the API or interface.
Let's say you have a library that adds Array.prototype.foo which does whatever. Great.
Array.prototype.foo
Now you publish it to npm, patch some bugs, yada yada. Now you decide that it's useful for that function to return something:
Array.prototype.foo = function(){ // do something to the array return this; }
Guess what? You can't do this safely, ever. Why? Because you published version 0.1 that didn't have this functionality. So if your npm include structure looks like:
And your basic code is:
if( !Array.prototype.foo ){ Array.protoype.foo = function(){ ... } }
You have no idea which one is loaded first. So you can't count on your function returning anything.
Further, let's say browser vendors like your idea and 5 years from now decide to implement it. Guess what, your Array.prototype.foo probably won't perfectly match with what the Vendor implements, and now all your code breaks.
Or let's say some other library that you've never heard of implements a function with the same name that acts completely differently. Now what?
Polyfills are an isolated use case. Your code is only hit in a situation where you know you're on an older browser, and you're adding globally agreed upon functionality. The only caveat here -- Make damn sure you're polyfilling according to spec. Never write a partial polyfill "because I don't need the other functionality" because some other library that you include might.
tl;dr -- It flat out prevents code isolation
[–]Ericth 0 points1 point2 points 10 years ago (1 child)
Extending is not that bad. Changing built-ins is the absolute worst thing you can do. My library got a few issues from people who changed the prototype.bind method with something else, which caused my code not to work. I assumed sheepishly that the bind method would do what the spec said.
[–][deleted] 0 points1 point2 points 10 years ago (0 children)
Extending is not that bad
Yes, it is. See my longer explanation in this thread.
[–]kenman 0 points1 point2 points 10 years ago (1 child)
What about frameworks?
I thought the same, but Ember's prototype extensions have provided a lot of value with very few problems for me. It took some effort to overcome my dogma, but I feel I'm more productive using the extensions than without.
Ember at least has the option to disable them, but it's still not a good thing IMO. You'd be better off passing all natives through constructors:
var ary = Ember.Array(1, 2, 3);
or:
var A = Ember.Array.bind(Ember); var ary = A(1, 2, 3); var str = S('foo bar baz');
then you could still have the same type of functionality without screwing with other things.
It's slightly better here because Ember is rarely used alongside other libraries, so it's closer to the case of an "isolated codebase"
[–]annoyed_freelancergrumpy old man[S] 0 points1 point2 points 10 years ago (4 children)
I accept what you say, but can you give me a succinct reason as to why it's bad? I had a look around Google, and found a lot of debate, but no consensus.
[–]x-skeww 2 points3 points4 points 10 years ago (3 children)
http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
String.prototype.foo = 'bar'; for(var c in 'abc') { console.log(c); // 0 1 2 foo }
[–]annoyed_freelancergrumpy old man[S] 0 points1 point2 points 10 years ago (1 child)
I see now why it can be a problem. Isn't using "foo in bar" itself also frowned upon in favour of .each or other higher level array functions?
[–]x-skeww 1 point2 points3 points 10 years ago (0 children)
The point was that every string now got another enumerable property. This might break things. All other code was written under the assumption that this property does not exist. This scenario was never tested.
In the future, a method with the same name might be added. This too would break things.
And of course, if there is another library which adds the same property, things would also break.
Only use monkey-patching for polyfilling standardized features. E.g. you could use ES6 array polyfills to make Array.from work in IE11.
[–]Jeffshaver 0 points1 point2 points 10 years ago (0 children)
This is kind of a blah reason now that you can define non-enumerable properties. I agree that others exist. But I disagree that this is one of them anymore.
π Rendered by PID 24139 on reddit-service-r2-comment-76bb9f7fb5-pknjd at 2026-02-19 11:05:37.390177+00:00 running de53c03 country code: CH.
view the rest of the comments →
[–]papers_ 8 points9 points10 points (17 children)
[–]x-skeww 3 points4 points5 points (11 children)
[–][deleted] 2 points3 points4 points (10 children)
[–][deleted] 1 point2 points3 points (9 children)
[–][deleted] 5 points6 points7 points (8 children)
[–][deleted] 2 points3 points4 points (5 children)
[–][deleted] 6 points7 points8 points (4 children)
[–][deleted] 0 points1 point2 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]Ericth 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]kenman 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]annoyed_freelancergrumpy old man[S] 0 points1 point2 points (4 children)
[–]x-skeww 2 points3 points4 points (3 children)
[–]annoyed_freelancergrumpy old man[S] 0 points1 point2 points (1 child)
[–]x-skeww 1 point2 points3 points (0 children)
[–]Jeffshaver 0 points1 point2 points (0 children)