-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add _.create method #1907
Add _.create method #1907
Conversation
Might make |
@@ -90,6 +91,23 @@ | |||
return cb(value, context); | |||
}; | |||
|
|||
// An internal function for creating a new object that inherts from another. | |||
var baseCreate = nativeCreate || (function() { | |||
function Object() {} |
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.
Using function Object() {}
will cause an issue in an old browser (not sure off the top of my head which) with the use of the object literal on line 107
. The literal will incorrectly use the local Object
constructor instead. I'll see if I can dig up more detail on that.
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.
Use Ctor
?
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.
Lodash has the same thing in baseCreate
, are you just dropping support for that browser or are you doing something magical?
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.
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.
@jdalton Hmm, I do like the Object {}
I think it'd be better to use Ctor
for this.
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.
are you just dropping support for that browser or are you doing something magical?
Ours is:
function baseCreate(prototype) {
return isObject(prototype) ? nativeCreate(prototype) : {};
}
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.
@jdalton I was referring to the Object
in:
if (!nativeCreate) {
baseCreate = (function() {
function Object() {} // <<
return function(prototype) {
if (isObject(prototype)) {
Object.prototype = prototype;
var result = new Object;
Object.prototype = null;
}
return result || context.Object();
};
}());
}
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.
@jdalton Hmm, I do like the Object {} I think it'd be better to use Ctor for this.
I'm not too concerned about that, this will only be for environments without Object.create
result || context.Object();
That references global.Object
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.
Yap, I avoided issues by doing context.Object()
as mentioned above.
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.
Oooooooh, I misread what you said.
A wild understanding appears
@jdalton Updated |
// created object. | ||
_.create = function(prototype, props) { | ||
var result = baseCreate(prototype); | ||
return props ? _.extend(result, props) : result; |
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.
I haven't read the spec for Object.create
, is it own
props or in
props used
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.
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.
Alright well we may have to defer to 2.0 in that 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.
Could I update it to use _.keys
until then?
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.
@thejameskyle I haven't opened an issue yet, but I would like to maintain _.extend
behaviour to use in
props and add a _.assign
function for own
properties.
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.
Ya know my stance on it.
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.
@jdalton and for those who don't? 👉😁👈
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.
and for those who don't? 👉😁👈
I think _.assign
(aliased as _.extend
) is enough and other cases can fall to _.create
. It's worked well in my experience. That said I also offer things like _.keysIn
, _.forIn
, and _.valuesIn
so devs can easily create their own mixins.
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.
@megawac I've updated _.create
to use _.keys
for now so it isn't blocked.
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.
Yep, I'm definitely for adding keysIn
, valuesIn
and forIn
// Creates an object that inherits from the given prototype object. | ||
// If additional properties are provided then they will be added to the | ||
// created object. | ||
_.create = function(prototype, props) { |
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.
I think this belongs in the Objects
part of the codebase
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 not already? The closest header above says "Object Functions"
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.
My bad got lost in the source
On Sat, Oct 25, 2014 at 9:08 PM, James Kyle [email protected]
wrote:
In underscore.js:
@@ -998,6 +1012,23 @@
return obj;
};
- // Creates an object that inherits from the given prototype object.
- // If additional properties are provided then they will be added to the
- // created object.
- _.create = function(prototype, props) {
It's not already? The closest header above says "Object Functions"
—
Reply to this email directly or view it on GitHub
https://github.com/jashkenas/underscore/pull/1907/files#r19378463.
This looks ready to go. Can I get a 👍? |
for (i = 0; i < length; i++) { | ||
key = keys[i]; | ||
result[key] = props[key]; | ||
} |
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.
mind updating to use _.assign
?
@megawac Updated. |
// An internal function for creating a new object that inherts from another. | ||
var baseCreate = nativeCreate ? function(prototype) { | ||
return _.isObject(prototype) ? nativeCreate(prototype) : {}; | ||
} : function(prototype) { |
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.
Tests pass with
nativeCreate || function(prototype) {
...
Are better tests neaded or is that correct
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.
Ah okay, Object.create()
or Object.create(1)
for instance will error. In that case should the default value be {}
or Object.create(null)
?
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.
Returning {}
make more sense, since it'll mirror the non-nativeCreate path where we can't create a prototype-less object.
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.
For some reason, I didn't think of setting prototype to null in the non-nativeCreate path. Ignore my previous comment.
Anything else needed here? |
@thejameskyle mind just adding a test to cover this case https://github.com/jashkenas/underscore/pull/1907/files#discussion_r20761788? Also thoughts on |
|
440a3c0
to
7de85c4
Compare
@jridgewell [ref] updated thanks. |
Wait a second, I knew there was a reason I thought we couldn't create a prototype-less object without nativeCreate. function Test() {}
Test.prototype = null;
var t = new Test();
t.__proto__ === Object.prototype; // => true
t.toString(); // => "[object Object]" Ignore my comment telling you to ignore my comment. It would be better to take @jdalton's path here and instead return a new object literal, since we can't mirror functionality in the non-nativeCreate path. |
@jridgewell After speaking to @megawac I decided to inline the |
Both inline and separated are fine with me. But I think 70a120d-L117 should be |
@jridgewell I was thinking about making that just |
That would be fine too. 😄 |
Alright LGTM now /cc @michaelficarra |
_.create
is useful as both a "polyfill" forObject.create
and a utility for simple prototype inheritance.Implementation is adapted from Lodash's
_.create
method. I've kept thebaseCreate
function for the usage in the methods @jdalton mentioned here.Ref: @jdalton #1901 (comment)