Lodash _.assignIn() method
What you’ll learn
- How
_.assignIn(object, ...sources)mirrors _.assign but also walks inherited string keys from each source’s prototype chain. - Why
_.assignInand_.extendare the same function under two names. - Where this matters in practice (class instances, custom prototypes, mixin patterns).
- Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Read _.assign() first for the shared shallow/mutating semantics; this page focuses on the inherited-key extension.
- Prototype chain: understand
Object.create, constructor prototypes, and the difference betweenhasOwnPropertyandin. - Enumerable flag: non-enumerable inherited properties (such as most built-in
Object.prototypemethods) are still skipped.
Overview
_.assignIn is the “walk-the-chain” cousin of _.assign. Everything else is identical: properties are read from sources left to right, copied into the first argument, and the (mutated) destination is returned.
Inherited keys
Class instances, factory mixins, and prototype-defined shape data all flatten into the destination.
Still shallow
Walking the prototype chain doesn’t deepen the copy—nested values stay shared by reference.
Tree-shakeable
Import lodash/assignIn on its own; lodash/extend resolves to the same module.
Syntax
_.assignIn(object, [...sources])
// alias: _.extend(object, [...sources]) - object: destination object; mutated in place.
- sources: zero or more source objects; own and inherited enumerable string keys are copied left to right.
- Returns: the (now-mutated) destination object.
- Skipped: symbol keys, non-enumerable properties, and properties at depth (use _.merge for those).
Class instance with prototype keys
An instance carries one own key (own) and inherits one (inherited). _.assignIn copies both; the sibling _.assign keeps only the own key.
import assignIn from "lodash/assignIn";
import assign from "lodash/assign";
function Source() {
this.own = "from instance";
}
Source.prototype.inherited = "from prototype";
const src = new Source();
assignIn({}, src);
// => { own: "from instance", inherited: "from prototype" }
assign({}, src);
// => { own: "from instance" } // inherited key skipped Mixin: layer prototype helpers onto a plain object
Define shared behavior on a prototype, then flatten it onto a plain configuration object with one call.
import assignIn from "lodash/assignIn";
const Greeter = {};
Object.getPrototypeOf(Greeter) === Object.prototype; // true (plain object)
const proto = { greet() { return "hi " + this.name; } };
const instance = Object.create(proto);
instance.name = "Ada";
const flat = assignIn({}, instance);
// flat.name -> "Ada"
// flat.greet -> function (copied from prototype)
flat.greet();
// => "hi Ada" Left-to-right conflict resolution
Same precedence rules as _.assign: the last source to mention a key wins. Pass {} as the destination when you want a brand new object.
import assignIn from "lodash/assignIn";
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { a: 3, c: 4 };
assignIn(target, source1, source2);
// target is now { a: 3, b: 2, c: 4 } (source2 overwrites a)
const merged = assignIn({}, target, source1, source2);
// merged === target ? false (fresh object)
// merged is also { a: 3, b: 2, c: 4 } 📋 _.assignIn vs _.assign vs _.merge
| Topic | _.assignIn | _.assign | _.merge |
|---|---|---|---|
| Own keys | Yes | Yes | Yes |
| Inherited keys | Yes | No | No |
| Symbol keys | No | No | No |
| Depth | Shallow | Shallow | Recursive |
| Aliases | _.extend | — | — |
| Typical use | Class instances, prototype-based mixins | Plain config layering | Nested config trees |
Reach for _.assignIn when the source has meaningful data on its prototype; stick with _.assign for plain object literals; use _.merge when you need nested combination rather than overwrite.
Pitfalls to avoid
Unwanted prototype data
Walking the chain also picks up keys you didn’t mean to expose (custom toJSON, framework helpers). Switch to _.assign when you want a strict whitelist.
Destination is written in place
Same trap as _.assign—callers sharing the first argument will see the new keys. Pass {} when you want isolation.
Still shallow
The “In” suffix only changes the key set, not the depth—mutating a nested object after copying still affects the destination.
❓ FAQ
Summary
- Purpose: shallow-copy own and inherited enumerable string keys from sources onto a destination.
- Remember: alias of
_.extend; mutates the destination; symbol keys still skipped; depth unchanged. - Next: Lodash _.assignInWith(), _.assign(), or the official Lodash docs for _.assignIn.
_.assignIn and _.extend are the same function—extend is the legacy alias kept for backwards compatibility. Both walk own and inherited enumerable string keys; only the name differs in the Lodash docs.
6 people found this page helpful
