-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Avoid Object.prototype collisions with defaults #3843
Avoid Object.prototype collisions with defaults #3843
Conversation
}); | ||
model = new Defaulted({two: undefined}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why'd you get rid of this test case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's testing the same thing as the one above it, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No... it's testing that passing undefined
is thrown away, not that the key isn't passed at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var defaults = {foo: true};
_.defaults({}, defaults, {foo: undefined}); // { foo: true }
_.defaults({}, defaults, {bar: undefined}); // { foo: true, bar: undefined }
_.extend({}, defaults, {foo: undefined}); // { foo: undefined }
_.extend({}, defaults, {bar: undefined}); // { foo: true, bar: undefined }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No... it's testing that passing undefined is thrown away, not that the key isn't passed at all.
Isn't that this test?
var defaults = {foo: true};
With my "defaults" implementation:
defaults = {foo: true};
defaults({}, defaults, {foo: undefined}); // { foo: true }
defaults({}, defaults, {bar: undefined}); // { foo: true, bar: undefined }
The only difference with mine is it won't respect properties that are already on the dest
object:
_.defaults({foo: false}, {foo: true}); // { foo: false }
defaults({foo: false}, {foo: true}); // { foo: true }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that this test?
Sorry, missed that in the diff.
The only difference with mine is it won't respect properties that are already on the dest object
Then I'm confused. That changes _.default's behavior completely, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're only using defaults with an "empty" destination object, so it works the same. Externally, this wouldn't be acceptable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but I dunno. Either we should fix this in Underscore or we shouldn't fix this at all. What's good for the goose is good for the gander...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we made it return a new instance instead of modifying the destination, it would work perfectly. We're kind of headed down that path with jashkenas/underscore#2232.
b8bd90f
to
aa421d9
Compare
For reference here's the current fix in lodash lodash/lodash@8a3842b. I think it's fine to have this in Backbone temporarily until it can be addressed in a released version of Underscore. |
I dunno. I feel like this is something that should be fixed in Underscore, if at all. Who names their keys |
It's less those classic |
To be sure, |
Yep, though I think it can be tackled without back compat pains. The likely issues I see are with |
aa421d9
to
325fe1c
Compare
Repinging this: I've updated the PR to use |
325fe1c
to
76077f5
Compare
Ping @akre54 since you're reviewing things today. 😉 |
Hows the perf hit when there are a few keys? |
76077f5
to
92fb299
Compare
Ping. I want to get this one in. |
For the record, I think this ( |
Avoid Object.prototype collisions with defaults
@@ -989,8 +994,8 @@ | |||
|
|||
QUnit.test('`previous` for falsey keys', function(assert) { | |||
assert.expect(2); | |||
var model = new Backbone.Model({0: true, '': true}); | |||
model.set({0: false, '': false}, {silent: true}); | |||
var model = new Backbone.Model({'0': true, '': true}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whys this needed? JS automatically casts keys to strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was a liter warning for inconsistent string usage. Must have committed it by accident. 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linting rules are not perfect 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good, they're much better now than before.
This first commit here makes the changes made in pull jashkenas#3843 unnecessary and we can revert those changes. Since it will be using prototypeless objects we don't have to worry about the collisions
This is definitely an underscore concern, but it's easier to demo in Backbone code.
Fixes #3842.