|
1 | 1 | define( [ |
2 | 2 | "./var/arr", |
3 | 3 | "./var/document", |
| 4 | + "./var/getProto", |
4 | 5 | "./var/slice", |
5 | 6 | "./var/concat", |
6 | 7 | "./var/push", |
7 | 8 | "./var/indexOf", |
8 | 9 | "./var/class2type", |
9 | 10 | "./var/toString", |
10 | 11 | "./var/hasOwn", |
| 12 | + "./var/fnToString", |
| 13 | + "./var/ObjectFunctionString", |
11 | 14 | "./var/support", |
12 | 15 | "./core/DOMEval" |
13 | | -], function( arr, document, slice, concat, |
14 | | - push, indexOf, class2type, toString, hasOwn, support, DOMEval ) { |
| 16 | +], function( arr, document, getProto, slice, concat, push, indexOf, |
| 17 | + class2type, toString, hasOwn, fnToString, ObjectFunctionString, |
| 18 | + support, DOMEval ) { |
15 | 19 |
|
16 | 20 | var |
17 | 21 | version = "@VERSION", |
@@ -225,28 +229,24 @@ jQuery.extend( { |
225 | 229 | }, |
226 | 230 |
|
227 | 231 | isPlainObject: function( obj ) { |
228 | | - var key; |
| 232 | + var proto, Ctor; |
229 | 233 |
|
230 | | - // Not plain objects: |
231 | | - // - Any object or value whose internal [[Class]] property is not "[object Object]" |
232 | | - // - DOM nodes |
233 | | - // - window |
234 | | - if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { |
| 234 | + // Detect obvious negatives |
| 235 | + // Use toString instead of jQuery.type to catch host objects |
| 236 | + if ( !obj || toString.call( obj ) !== "[object Object]" ) { |
235 | 237 | return false; |
236 | 238 | } |
237 | 239 |
|
238 | | - // Not own constructor property must be Object |
239 | | - if ( obj.constructor && |
240 | | - !hasOwn.call( obj, "constructor" ) && |
241 | | - !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) { |
242 | | - return false; |
243 | | - } |
| 240 | + proto = getProto( obj ); |
244 | 241 |
|
245 | | - // Own properties are enumerated firstly, so to speed up, |
246 | | - // if last one is own, then all properties are own |
247 | | - for ( key in obj ) {} |
| 242 | + // Objects with no prototype (e.g., `Object.create( null )`) are plain |
| 243 | + if ( !proto ) { |
| 244 | + return true; |
| 245 | + } |
248 | 246 |
|
249 | | - return key === undefined || hasOwn.call( obj, key ); |
| 247 | + // Objects with prototype are plain iff they were constructed by a global Object function |
| 248 | + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; |
| 249 | + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; |
250 | 250 | }, |
251 | 251 |
|
252 | 252 | isEmptyObject: function( obj ) { |
|
0 commit comments