Leaderboard
Javascript Jul 10, 2026
Javascript Object Assign Shallow Copy Primitives

JavaScript Object.assign — What is the output?

This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Object Assign Shallow Copy Primitives and improve your technical interview readiness.

const obj = { a: 1 }
const obj2 = Object.assign({}, obj, { b: 2 })
obj.a = 99
console.log(obj2.a)
A 99
B 1
C undefined
D TypeError

Detailed Explanation

Why This Question Matters

If you've spent any time with JavaScript, you've probably run into the "mutation" headache. The difference between copying a value and copying a reference is one of those things that seems simple on paper but causes massive bugs in production—especially when you're dealing with state management in React or Redux.

This specific challenge tests whether you actually understand how Object.assign() works. A lot of devs assume it creates a deep copy or that it links objects together in some magical way. In reality, it’s much simpler (and more dangerous) than that. Understanding this prevents those "Why is my state changing unexpectedly?" debugging sessions that last three hours.

Understanding the Code

Let's look at the snippet again:

const obj = { a: 1 }
const obj2 = Object.assign({}, obj, { b: 2 })
obj.a = 99
console.log(obj2.a)

Here is exactly what's happening under the hood.

First, we define obj as a simple object. Then comes the Object.assign() call. This method is designed to copy properties from one or more source objects to a target object.

In this line: Object.assign({}, obj, { b: 2 }), the first argument {} is the target. We are telling JavaScript: "Create a brand new empty object, and then shove everything from obj and the literal { b: 2 } into it."

Because we used a fresh empty object as the target, obj2 becomes a completely different reference in memory. It gets the value of obj.a (which is 1) and the value of b (which is 2).

Now, the line obj.a = 99 happens. We are mutating the original obj. But since obj2 was created by copying the *value* of a at that specific moment in time, it doesn't care what happens to obj later.

Finding the Correct Answer

The output is 1.

Why? Because Object.assign performs a shallow copy.

When Object.assign ran, it saw that obj.a was a primitive number. It copied the value 1 into the new object. Once that copy is made, the link between the two objects is severed for that specific property. Changing obj.a to 99 only affects the original object. obj2.a remains 1.

If the answer were 99, it would mean obj2 was holding a reference to obj, but that's not how Object.assign works when you provide a new object as the target.

Common Mistakes Developers Make

The biggest trap here is confusing shallow copies with deep copies.

In this example, we used a primitive (a number). But watch what happens if we use a nested object:

const obj = { a: { value: 1 } }
const obj2 = Object.assign({}, obj)

obj.a.value = 99
console.log(obj2.a.value) // This WILL be 99!

This is where developers get burned. Object.assign only copies the first level. If a property is an object or an array, it copies the reference to that object, not the object itself. So, both obj and obj2 end up pointing to the same nested object in memory.

Another common mistake is forgetting that Object.assign mutates the first argument. If the developer had written Object.assign(obj, { b: 2 }) without the empty curly braces at the start, obj itself would have been changed.

Real-World Usage

In a modern production environment, you'll see this pattern everywhere—especially in state updates.

Back in the day, we used Object.assign constantly. Nowadays, most of us use the spread operator because it's cleaner:

const obj2 = { ...obj, b: 2 };

The spread operator does essentially the same thing as Object.assign({}, ...) in this context. It creates a shallow copy.

You'll see this constantly in React's useState hooks. You can't just mutate a state object because React won't know the state changed (since the object reference remains the same). You *must* create a new object reference using spread or Object.assign to trigger a re-render.

If you're building a complex Redux reducer, understanding that a shallow copy isn't enough for nested data is critical. That's why libraries like Immer are so popular—they handle the "deep" part of the copy for you so you don't accidentally mutate your global state.

Key Takeaways

- Object.assign(target, ...sources) copies properties from source to target.
- Using {} as the target ensures you're creating a new object rather than mutating an existing one.
- It's a shallow copy. Primitives are copied by value, but objects/arrays are copied by reference.
- If you need a deep copy, Object.assign isn't enough; you'll need structuredClone() or a library like Lodash.
- The spread operator {...obj} is the modern, more readable equivalent for shallow copying.

Why this matters

Understanding Object Assign Shallow Copy Primitives is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.

📝
Reviewed by CodeShot Editorial
Every challenge is code-reviewed by senior developers to ensure accuracy and real-world relevance. Learn more.

Ready for your shot?

Join thousands of developers solving one logic puzzle every morning.

Solve Today's Challenge →