-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EXTEND_PROTOTYPES false by default. #9269
Comments
@jdalton as you know, internal ember does not rely on these things. So we have lots of flexibility here. I am unsure if they should be default on or default off, that is a @wycats and @tomdale question. But I do think if they are ON, we should always use our user land versions and never fall back to native versions. That way if something does change, our users will still get the consistent original behavior they expected. |
I would also add that there are a lot of blog posts, Stack Overflow answers, JSBins and even Ember guides that currently show code that assumes |
An added confusion is we have Enumerable which allows enumeration over non array like objects but with all the array like goodies. This leaves us with potential differences with This part of ember was inherited from the sprout core days, a time when browser world was stale, prototype extensions where used without fear (wrongfully). Going forward this is in the category of |
I think |
I'd be willing to reconsider it once the way you consume Ember is via ES6 modules, and in a 2.x release, but this change would be way too breaking for the 1.x series. |
Also worth noting. In theory currently ember will run slower with prototypes off. And will be an involved but good refactoring to address this |
👍
Ah, good to know. Manually bolting on methods reminds me of Prototype's approach for supporting DOM extensions in older browsers (not so awesome). There's deeper issues as it looks like even with a config of |
@jdalton yes, we need to be consistent about this. The current state is the result of much scenario solving but we a more holistic set of solutions. Currently ember always falls back to existing natives, but clearly we don't actually want this. As it may result in future breakages. if it wasn't for Ember's Enumerable, I would opt immediately to drop our version of this and move to a minimal lodash. |
+1 Extending native prototypes is always dangerous and usually avoidable. I haven't yet used Ember, and this is the main reason why. I want my apps to gracefully upgrade as well as they gracefully degrade. It seems to me that the reason prototypes are extended inside Ember is for syntactic sugar, which, let's be honest, is a fantastic goal. I just worry that it's following such a bad practice that the project itself will suffer in the long term. As an example, let's look at
This solves at least three problems: one, interfering with the native prototype; two, replacing sugar with safety and consistency; three, I'm not using Ember yet. The only problem remaining is the dusty example code on stackoverflow, random blogs, codeschool, and the like; most of which is already behind if not broken since it was published. PLEASE NOTE: I'm not suggesting Ember.Property( function ) as an implementation target here. That is pseudocode provided merely to illustrate a potential solution. Looking at ember-runtime/lib/ext/function.js it seems that |
I think what you suggest is already there (see Ember.computed):
So one can easily avoid using prototype extensions. And projects such as ember-watson can convert your existing code if you wish: https://github.com/abuiles/ember-watson#ember-watsonconvert-prototype-extensions. Also see this emberjs/guides#110 |
So we will be making an effort during the 2 -> 3x lifespan to mitigate the performance issues caused by totally disabling prototype extensions (which is one of the main blockers). There are several ergonomic things that will need to be improved as well, but nothing very hard just laborious. I have also thrown together a first pass at updating the guides to prefer non-prototype extension modes for the 2 most common ones. emberjs/guides#110 A future effort will dig into the array extensions (which are the most gnarly, and without them the current internals will suffer performance issues, but this can be mitigated) |
Thank you @OrKoN - I hadn't yet gotten familiar enough with Ember to track those docs down. Much obliged. That's a huge help, @stefanpenner - thanks. It would have made reading the docs a much more exciting venture because it's obvious that these methods don't extend native prototypes. As far as arrays are concerned, I'm not at all surprised at the pushback on removing the Array extensions. However, there's already a historical example for everybody to already use A([ ]) when they need an Ember-extended array, and that's the crash-and-burn of the early versions of Prototype.js, versus its much smarter (at the time at least) competitor, lodash. True, forcing the A() call makes each of us work harder to do the same thing we'd currently do with a generic array, but wouldn't it make Ember apps more performant to not rely on this antipattern? If we only wrap our arrays when we know they're going to need extended methods, then any generic array can be left as-is, and suffer no performance drags due to extensions. What parts of the internals will suffer from performance issues should the Array extensions be removed? |
Ya, this isn't entirely obvious but let me explain. given the following: {{#each friends as |friend}} Ember essentially does (yes a liberal simplification):
turns out 2. is the offender, as ember assumes If I believe the resolution to this issue is simple, although it will require some grunt work. Ember internals, should not rely on To mitigate the need for all objects having get(obj, 'property');
set(obj, 'property', 'value') rather then: obj.get('property');
obj.set('property', value); This pattern can and likely should by applied to the observable array methods as well. addArrayObserver(array, ...);
removeArrayObserver(array, ...);
pushObject(array, obj); Yes this still leaves the other "nice things" and es6/es7 polyfils, but it reduces the cost and internal domain leakage the observable methods on arrays currently cause. |
Also, it is worth noting. Once we unblock ^ (i think i motivated to work on it this weekend), the performance concerns should be mostly mitigated. And we can pave they way for a future of more well behaved ember apps. |
i started work on this (just now) #10899 |
Tracking in #10899 for the array scenarios. We will still need to deprecate the usage of the various function prototype extensions, but that should be relatively simple to do (will need to be supported throughout the 2.x timeframe though). |
With #10899 it will be easier and of less cost for people to do this opt-in. We can even strongly encourage it. |
Do not use prototype extension for `objectAt`. Related to #9269 and based on the work of @stefanpenner in #10899. If this is acceptable, will continue addressing one extension at a time for quicker merging. (cherry picked from commit cd0d186)
As mentioned, prototype extension is turned off by default in addons. Given this and the effort to not use extensions in Ember's source as well as carefully deprecating some of them, I'm closing this issue. Thanks for the discussion everyone, let's keep working towards a better story! |
I haven't shipped an app with them on in forever. It's likely that we can full swap on the default for 3.0 |
Those apps will suffer from perf issues, until the array |
I am curious about the perf issues you were mentioning @stefanpenner, now that we have Octane, the new reactivity system, ES6 modules, etc… 🤔 Is it still usefull to have |
It is still somewhat important for array in certain contexts. It depends how far down the Octane path really, you could author without ever using |
Currently Ember extends built-in prototypes of
Array
,Function
, &String
by default. Although Ember doesn't require these extensions and they can be disabled, because they are enabled by default they tend to stay that way as evident by sites like vine, twitch, nbcnews, & discourse using the default settings.The problem with adding methods like
Array#compact
,Array#without
,Array#uniq
,Function#on
, &String#capitalize
is that it increases the likelihood that they'll be used and cause problems/roadblocks for future built-in language extensions. For example, if ES7 tried to addArray#without
that behaved in a different way than Ember'sArray#without
newer environments would get the built-in version while older would get Ember's causing an inconsistency and increased possibility of breaking thing. We've seen this recently with MooTools andArray#contains
, but it's happened before withFunction#bind
,String#contains
, and even DOM4Element#remove
.The text was updated successfully, but these errors were encountered: