Dans l'article précédent "Ce que vous devez savoir sur l'utilisation de l'"héritage jquery" JavaScript (explication détaillée du code) ", nous avons appris l'utilisation de l'"héritage jquery" JavaScript. L'article suivant vous présentera la méthode de copie d'objet dans JS. Les amis dans le besoin peuvent s'y référer.
En parlant de copie d'objets en javascript
, la première chose à laquelle nous pensons est Object.assign()
javascript
中的对象拷贝,首先我们想到的是Object.assign()
JSON.parse(JSON.stringify()),
还有ES6
的展开操作符[...
]
因为在js
中=
运算符 对于对象来说,不能创建副本,只是对该对象的引用
var x = { a: 1, b: 2, }; y = x; x.a = 10; console.log(x); //{a:10, b:2} console.log(y); //{a:10, b:2}
所以在进行对象操作时,运算符等于号(=
)不可取
var x = { a: 1, b: 2, }; y = Object.assign({}, x); x.a = 10; console.log(x); //{a:10, b:2} console.log(y); //{a:1, b:2}
初看,不会发现异常,因为所要的就是我们所要的结果,把对象结构弄再稍微复杂些再看
var x = { a: 1, b: 2, c: { d: 3, }, }; y = Object.assign({}, x); x.a = 5; console.log(x); //{a:5, b:2, c:{d:3}} console.log(y); //{a:5, b:2, c:{d:3}} x.c.d = 10; console.log(x); //{a:5, b:2, c:{d:10}} console.log(y); //{a:5, b:2, c:{d:10}}
此时就发现坑了,那么已经证明了Object.assign()
只是实现了对象的浅拷贝
Object.assign()
还需要注意的一点是,原型链上属性的不可枚举对象是无法复制的,看一下代码:
var x = { a: 1, }; var y = Object.create(x, { b: { value: 2, }, c: { value: 3, enumerable: true, }, }); var z = Object.assign({}, y); console.log(z); //{c:3}
拿到z
的值很让人意外,因为x
是y
的原型链,所以x
不会被复制
属性b
是不可枚举属性,也不会被复制
只有c
具有可枚举描述,他可以被枚举,所以才能被复制
以上的坑也可以很好的被解决,且往下看:
JSON.parse(JSON.stringify())
解决浅拷贝的坑
var x = { a: 1, b: 2, c: { d: 3, }, }; y = JSON.parse(JSON.stringify(x)); x.a = 5; x.c.d = 10; console.log(x); //{a:5, b:2, c:{d:10}} console.log(y); //{a:1, b:2, c:{d:3}}
当然普通的对象,此种复制方式已经是基本是完美了,那么他的坑在哪里呢
var x = { a: 1, b: function b() { return "2"; }, }; y = JSON.parse(JSON.stringify(x)); z = Object.assign({}, x); console.log(y); //{a:1} console.log(z); //{a:1, b:function b(){return '2'}}
从结果看来,Object.assign()
可以复制方法,JSON.parse(JSON.stringify())
不可以
再来看第第二个坑:
var x = { a: 1, b: { c: 2, d: 3, }, }; x.c = x.b; x.d = x.a; x.b.c = x.c; x.b.d = x.d; var y = JSON.parse(JSON.stringify(x)); console.log(x); /* Uncaught TypeError: Converting circular structure to JSON at JSON.stringify (<anonymous>) at <anonymous>:8:25 */
报错了,其结果表明JSON.parse(JSON.stringify()),
不能拷贝循环引用对象
再来看看Object.assign()
var x = { a: 1, b: { c: 2, d: 3, }, }; x.c = x.b; x.d = x.a; x.b.c = x.c; x.b.d = x.d; var y = Object.assign({}, x); console.log(x); /* [object Object]{ a:1, b:[object, Object], d:[object, Object], d:1 } */
对象字面量的展开操作符目前是ECMAScript
JSON.parse(JSON. stringify ()),
et l'opérateur d'expansion [...
] de ES6
car dans js
Le L'opérateur =
ne peut pas créer une copie pour un objet, c'est juste une référence à l'objetopérateurvar x = [ "a", "b", "c", "d", { e: 1, }, ]; var y = [...x]; console.log(y); //['a', 'b', 'c', 'd', {'e':1}] var m = { a: 1, b: 2, c: ["d", "e"], }; var n = { ...m, }; console.log(n); //{a:1, b:2, c:['d', 'e']}
=
) Non conseilléObject.assign()
function copy(x) { var y = {}; for (m in x) { y[m] = x[m]; } return y; } var o = { a: 1, b: 2, c: { d: 3, e: 4, }, }; var p = copy(o);
.
var x = {}; Object.defineProperty(x, "m", { value: 5, writable: false, }); console.log(x.m); //5 x.m = 25; //这一步没报错,但是也没执行 console.log(x.m); //5
Object.assign()
n'implémente qu'une copie superficielle de l'objet
Object.assign()
Une autre chose à noter est que les objets non énumérables avec des propriétés sur la chaîne prototype ne peuvent pas être copiés. Jetez un œil au code : L'attribut b
est un non énumérable propriété et ne sera pas copié🎜🎜Seul c
a une description énumérable, il peut donc être copié. Les pièges ci-dessus peuvent également être très bien résolus, et regardez en bas : 🎜🎜Profondément. copy JSON.parse (JSON.stringify())
🎜🎜Solution aux pièges de la copie superficielle🎜rrreee🎜Bien sûr, cette méthode de copie est fondamentalement parfaite pour les objets ordinaires, alors où est son piège🎜rrreee 🎜D'après les résultats Allez, Object.assign()
peut copier la méthode, JSON.parse(JSON.stringify())
ne peut pas 🎜🎜 Regardons le deuxième piège : 🎜rrreee🎜 Une erreur a été signalée et le résultat a montré que JSON.parse(JSON.stringify()),
ne peut pas copier l'objet de référence circulaire🎜🎜Jetons un coup d'œil à Object. assign()
🎜rrreee🎜Utiliser l'opérateur Spread [... ]🎜🎜L'opérateur spread des littéraux d'objet est actuellement une proposition de phase 3 de ECMAScript
, ce qui rend copier des objets plus simple🎜rrreee🎜Remarque L'opérateur de propagation est également une copie superficielle. Alors, est-ce vraiment si difficile de copier des objets ? 🎜🎜Faites vos propres roues : 🎜rrreee🎜Certaines personnes disent qu'il ne devrait pas y avoir beaucoup de problèmes si vous faites cela. Ensuite, nous ne pouvons que rire et continuer 🎜rrreee🎜 De cette façon, l'opérateur de spread rencontrera également des pièges lors de la copie d'objets ici. 🎜🎜Il y a des pièges partout et il est difficile de s'en prémunir... J'ai écrit ceci et je suppose qu'il y a encore de nombreux pièges qui n'ont pas été entièrement répertoriés🎜🎜J'en écrirai plus plus tard🎜🎜[Fin] 🎜🎜Apprentissage recommandé : 🎜Tutoriel vidéo JavaScript🎜🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!