Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fix #10466. jQuery.param() should treat object-wrapped primitives as …

…primitives.
  • Loading branch information...
commit 166b9d252a025009413eee1584dc364996dcb1c2 1 parent 6c2a501
Rick Waldron authored December 06, 2011 dmethvin committed December 06, 2011
2  src/ajax.js
@@ -818,7 +818,7 @@ function buildParams( prefix, obj, traditional, add ) {
818 818
 			}
819 819
 		});
820 820
 
821  
-	} else if ( !traditional && obj != null && typeof obj === "object" ) {
  821
+	} else if ( !traditional && jQuery.isPlainObject( obj ) ) {
822 822
 		// Serialize object item.
823 823
 		for ( var name in obj ) {
824 824
 			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
13  test/unit/ajax.js
@@ -1031,6 +1031,19 @@ test("jQuery.param()", function() {
1031 1031
 	equal( jQuery.param( params, false ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" );
1032 1032
 });
1033 1033
 
  1034
+test("jQuery.param() Constructed prop values", function() {
  1035
+	expect(3);
  1036
+
  1037
+	var params = {"test": new String("foo") };
  1038
+	equal( jQuery.param( params, false ), "test=foo", "Do not mistake new String() for a plain object" );
  1039
+
  1040
+	params = {"test": new Number(5) };
  1041
+	equal( jQuery.param( params, false ), "test=5", "Do not mistake new Number() for a plain object" );
  1042
+
  1043
+	params = {"test": new Date() };
  1044
+	ok( jQuery.param( params, false ), "(Non empty string returned) Do not mistake new Date() for a plain object" );
  1045
+});
  1046
+
1034 1047
 test("synchronous request", function() {
1035 1048
 	expect(1);
1036 1049
 	ok( /^{ "data"/.test( jQuery.ajax({url: url("data/json_obj.js"), dataType: "text", async: false}).responseText ), "check returned text" );

11 notes on commit 166b9d2

Robert Katić

jQuery.isPlainObject is unnecessary here - use the faster jQuery.type( obj ) === "object".

Btw.:
Few lines up, there is typeof v === "object" || jQuery.isArray(v) that can be simplified to typeof v === "object".

Also, if really wonted, the isPlainObject can be avoided in .param too, by replacing a.jquery && !jQuery.isPlainObject( a ) with a.jquery && !hasOwn.call( a, "jquery" ), but this would require hasOwn = Object.prototype.toString on the top - so probably not too beneficial considering that isPlainObject is called only once here.

If you want I can make a pull req.

Dave Methvin
Owner

@rkatic, I doubt this would yield any measurable performance improvement in real code, given how seldom this is called. Would you be interested in taking on a larger project for 1.8? These micro-optimizations often are more bother to change than they are worth, we need to be focusing on big gains.

Robert Katić

Yea, the last one is certainly an over-optimization, but I pointed it now in case something like that will be needed...
Other two, however, was more for correctness...

Would you be interested in taking on a larger project for 1.8?

Do you have something in particular in mind?
I have intention to try to contribute to jQuery in next months anyway.

Rick Waldron
Collaborator

My previous comment's test was backwards, strike that.

Rick Waldron
Collaborator

So, jQuery.type(foo) will definitely work fine, but I'm not sure it's worth it? http://jsperf.com/type-vs-isplainobject

Rick Waldron
Collaborator

After making the change, byte counter reports:

jQuery Size - compared to last make
  248549     (+4) jquery.js
   93704     (+2) jquery.min.js
   33275      (-) jquery.min.js.gz
Robert Katić

It's more about correctness. Consider:

function Record(name, id) {
  this.id = id;
  this.name = name;
}

$.param({"boo" : new Record("foo", 666) });

Why to make this unnecessarily invalid?

Also, an more honest perf would probably be http://jsperf.com/type-vs-isplainobject/2.

Rick Waldron
Collaborator

How is that a "more honest perf"??? Because you said so? All you've done is create more noise.

This is the BEST argument given:

It's more about correctness. Consider:

function Record(name, id) {
  this.id = id;
  this.name = name;
}


$.param({"boo" : new Record("foo", 666) });

Why to make this unnecessarily invalid?

Why didn't you lead with that argument instead of nitpicking some half-cocked performance micro-optimization?

Robert Katić

This is not the first time that we do not agree on writing perfs, even if I am simply taking in consideration different types... but at the end the ideal perf is probably something in the middle: making more probable types more frequent, but not ignoring others too.

Rick Waldron
Collaborator

If you want to account for other types, do so in separate tests - it hardly makes sense to cram 3 different operations into each test.

Robert Katić

Maybe that would be even better, but I am not in the mood to make N tests for something like this...

Please sign in to comment.
Something went wrong with that request. Please try again.