Lodash _.create() method
What you’ll learn
- How
_.create(prototype, [properties])links a new object to a prototype, then copies the second-argument values onto it. - Why the second argument takes plain values (not property descriptors like native
Object.create). - When to use
_.create(null)for dictionary-style objects. - Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Understand JavaScript’s prototype chain and the difference between own and inherited properties. Optional: skim _.assign() for the second-argument copy semantics.
- Prototype chain: the
[[Prototype]]slot and how lookup falls through to it. - Native
Object.create: seeing why descriptors are noisy makes the lodash convenience obvious.
Overview
_.create is two steps in one call: link a new object to prototype, then copy own enumerable string keys from properties onto it. Use it whenever you want to skip the boilerplate of pairing Object.create with a manual Object.assign.
Prototype linkage
The new object inherits everything reachable from the prototype, including methods defined later on it.
Plain values, not descriptors
No need for { value, writable, configurable } wrappers—just pass { name: "Ada" }.
Null prototype
_.create(null) drops Object.prototype entirely—safer for user-supplied dictionary keys.
Syntax
_.create(prototype, [properties]) - prototype: any object (including
null) to become the new object’s[[Prototype]]. - properties: optional source whose own enumerable string keys are copied (assign-like) onto the new object.
- Returns: a brand-new object.
- Skipped: symbol keys and inherited keys on the
propertiesargument.
Factory: shared methods on the prototype
Put behavior on the prototype once, then stamp instances with their own data via the second argument.
import create from "lodash/create";
const userProto = {
greet() {
return "Hello, " + this.name + "!";
}
};
function makeUser(name, age) {
return create(userProto, { name, age });
}
const alice = makeUser("Alice", 25);
const bob = makeUser("Bob", 30);
alice.greet(); // "Hello, Alice!"
Object.getPrototypeOf(alice) === userProto; // true Multi-level prototype chain
Layer prototypes by calling _.create at each level. Lookup walks from the instance to each parent until it finds the requested key.
import create from "lodash/create";
const mammal = { giveBirth() { return "live birth"; } };
const dog = create(mammal, {
bark() { return "Woof!"; }
});
const labrador = create(dog, {
breed: "Labrador",
color: "Golden"
});
labrador.bark(); // "Woof!" (one hop up)
labrador.giveBirth(); // "live birth" (two hops up)
labrador.breed; // "Labrador" (own property) Dictionary with null prototype
Pass null as the prototype to get an object with no inherited keys—safe for storing user-supplied dictionary keys like "toString" or "hasOwnProperty".
import create from "lodash/create";
const dict = create(null, { apple: 1, banana: 2 });
Object.getPrototypeOf(dict); // null
"toString" in dict; // false — no Object.prototype noise
dict.apple; // 1
// Compare to a plain object:
const plain = { apple: 1 };
"toString" in plain; // true — inherited from Object.prototype 📋 _.create vs Object.create vs _.assign
| Topic | _.create | Object.create | _.assign |
|---|---|---|---|
Sets [[Prototype]] | Yes | Yes | No (destination unchanged) |
| Second-arg shape | Plain object of values | Property descriptor map | Plain object of values |
| Returns | Brand-new object | Brand-new object | The (mutated) destination |
| Symbol keys copied | No | Yes (via descriptors) | No |
| Typical use | Factory + initial fields in one call | Same, but you control descriptors | Copy fields onto an existing object |
Use _.create when you want a one-liner factory; reach for native Object.create when you need writable: false, getters, or symbol-keyed metadata.
Pitfalls to avoid
Confusing with Object.create
Native Object.create expects property descriptors in arg 2; lodash takes plain values. Mixing the conventions silently produces wrong shapes.
Mutable prototype values
If the prototype holds an array or object, every instance reads the same reference. Assign instance-level state via the second argument instead.
for...in on null-prototype objects
A _.create(null) object has no hasOwnProperty method on it—use Object.prototype.hasOwnProperty.call(obj, key) or Object.hasOwn instead of obj.hasOwnProperty(key).
❓ FAQ
Summary
- Purpose: create a new object linked to
prototypeand assign own enumerable string keys from a values map in one call. - Remember: second arg is values, not descriptors;
nullprototype = dictionary-safe object. - Next: Lodash _.defaults(), _.assign(), or the official Lodash docs for _.create.
_.create(proto, props) is essentially Object.create(proto) followed by _.assign(_, props). The key difference from native Object.create is that the second argument takes plain values, not property descriptors—so no { value, writable, configurable } ceremony.
6 people found this page helpful
