Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Why $.extend(someObj, anotherObj) Might be Dangerous!

DZone's Guide to

Why $.extend(someObj, anotherObj) Might be Dangerous!

· Web Dev Zone ·
Free Resource

Bugsnag monitors application stability, so you can make data-driven decisions on whether you should be building new features, or fixing bugs. Learn more.

You often have the need to merge two objects. A common use case is that of combining parameters for a $.ajax call. jQuery has a nice function for that, namely jQuery.extend. The function definition is something like jQuery.extend(target, [object 1], [object 2]). But attention, this might have dangerouse side effects if not used properly!

Suppose you have an object, obj1 defines like

var obj1 = {
    value: 1
};

And you need to execute a request to your backend server with some additional parameters, including the values of obj1. Your code might look like

var sendToServer = function(params, successCb, errorCb){
   return $.ajax({
      url: "/api/someurl",
      type: "GET",
      dataType: "json",
      data: params,
      success: successCb,
      errorCb: errorCb
   });
}
 
...
sendToServer(
   $.extend(obj1, { value: 2, someOtherParam: "hello" }),
   function(resultData) {
      console.log("The value of obj1: " + obj1.value);
   },
   function(e) {
      console.log("An error happened");
   });

On line 14 I'm basically giving the parameters to the sendToServer(..) function by combining those in obj1 with some new ones. This is possible since the $.extend(...) function directly returns the result of the combination of the passed objects.
Can you guess the output of line 16?

> The value of obj1: 2

Surprised? Well, take a look at line 14 again and then on the signature of jQuery.extend(target, [object 1], [object 2]). What happens there is a copy of the values provided in the new object, namely { value: 2, someOtherParam: "hello" } onto obj1, hence overwriting obj1's property value, setting it to 2.

The correct version of line 14 would therefore probably be

$.extend({}, obj1, { value: 2, someOtherParam: "hello" })

In this version, the values of obj1 and { value: 2, someOtherParam: "hello" } are copied onto a new object {}, thus not modifying the existing instance of obj1.

Here's a live example that mimics the odd behavior. Attention to this!

Monitor application stability with Bugsnag to decide if your engineering team should be building new features on your roadmap or fixing bugs to stabilize your application.Try it free.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}