This article records is the individual in the use of $.extend encountered a small problem, as well as causal analysis and solutions, very practical, the need for small partners can refer to.
I've been working on the mobile side lately, and since I'm familiar with jquery, plus Zepto provides the same API as jquery, I chose Zepto as the development framework.
As a result of the mobile-side development, some ES5 new APIs, such as foreach, are also applied, and here are some examples of the code I wrote:
?
1
2
3list.foreach (function (v) {
Return!! V
})
I naively thought that foreach was like each of jquery's, so long as my return value was false, it would interrupt the loop, so the traversal code like this would have written a lot (really lazy to declare variables for each traversal).
After writing for a while, I suddenly discovered that foreach's callback function did not interrupt the loop, so I hung a function on the Array.prototype, then ReplaceAll, perfect.
?
1
2
3
4
5
6
7
8
9
10array.prototype.foreach = function (fn) {
var i = 0, len = this.length;
for (; i < Len; ++i) {
if (FN (this[i], i) = = False) {
Break
}
}
};
Until one day, I want to do some optimization, considering the client needs to save the JSON too large (not fooled you, the maximum can go to 20M), stringify time is too time-consuming, will block the UI, so I use the worker in the background to open a thread, specifically used to stringify this JSON, Similar to this:
Copy code code as follows:
AddEventListener ("Message", function (e) {
var data = E.data;
data = json.stringify (data);
PostMessage (data);
}, False);
Posmesage:
Copy code code as follows:
Worker.postmessage (data)
However, the console prints the following error message:
Copy code code as follows:
Uncaught datacloneerror:failed to execute ' postMessage '-' Worker ': An object could is not cloned.
Pit Dad, this day killed why not even a JSON copy, so, I began to look for the reason, let me find my json there is this thing:
God, what the hell is this, this foreach came in, I looked at the editor inside the $.extend (true, {}, obj) is shivering in there, I can not help but doubt that you are not in the mischief. So, I looked at the $.extend source:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
23function Extend (target, source, deep) {
For (key in source)
if (Deep && (Isplainobject (source[key)) | | IsArray (SOURCE[KEY))) {
if (Isplainobject (Source[key]) &&!isplainobject (Target[key))
Target[key] = {}
if (IsArray (Source[key]) &&!isarray (Target[key))
Target[key] = []
Extend (Target[key], Source[key], deep)
}
else if (Source[key]!== undefined) target[key] = Source[key]
}
Copy all but undefined properties from one or more
objects to the ' target ' object.
$.extend = function (target) {
var deep, args = Slice.call (arguments, 1)
if (typeof target = = ' Boolean ') {
Deep = target
target = Args.shift ()
}
Args.foreach (function (ARG) {Extend (target, ARG, deep)})
return target
}
Oh, my God, this is really the goods in the AH, traversal array with for...in ... Forget it, but else if (Source[key]!== undefined) target[key] = Source[key The conditions here can be serious ah, add a hasownproperty check will not waste much time. Tears
After being Zepto pit, I immediately went to find jquery complaints, I hope it can comfort me, did not think:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63jquery.extend = JQuery.fn.extend = function () {
var options, name, SRC, copy, Copyisarray, clone,
target = Arguments[0] | | {},
i = 1,
Length = Arguments.length,
Deep = false;
Handle a deep copy situation
if (typeof target = = "Boolean") {
Deep = target;
target = Arguments[1] | | {};
Skip the Boolean and the target
i = 2;
}
Handle case as Target is a string or something (possible in deep copy)
if (typeof target!== "Object" &&!jquery.isfunction (target)) {
target = {};
}
Extend JQuery itself if only one argument is passed
if (length = = i) {
target = this;
I.;
}
for (; i < length; i++) {
Only deal with non-null/undefined values
if (options = arguments[i])!= null) {
Extend the Base Object
for (name in options) {
src = target[name];
copy = options[name];
Prevent never-ending Loop
if (target = = copy) {
Continue
}
recurse if we ' re merging plain objects or arrays
if (deep && copy && jquery.isplainobject (copy) | | (Copyisarray = Jquery.isarray (copy)) ) {
if (Copyisarray) {
Copyisarray = false;
clone = src && jquery.isarray (src)? SRC: [];
} else {
clone = src && jquery.isplainobject (src)? src: {};
}
Never move original objects, clone them
target[name] = Jquery.extend (deep, clone, copy);
Don ' t bring in undefined values
else if (copy!== undefined) {
target[name] = copy;
}
}
}
}
Return the Modified Object
return target;
};
The goods are also else if (copy!== undefined) {target[name] = copy;
Finally compelled to write one himself.
Summary: When you want to use $.extend, do not easily hang on Array.prototype and object.prototype your custom attributes and methods, otherwise, you may have to find a bug.
The above mentioned is the entire content of this article, I hope you can enjoy.