理解JS的深拷贝和浅拷贝的问题

2022-12-19 0 853

当他们借助v-bind:来存取特性百惠模块传达第一类的这时候,有这时候他们须要子模块发生改变的这时候不发生改变父模块的值,通常能借助JSON.stringify(JSON.parse(jsonstr))将传达来的对象表达式到子模块他们的data,这种做的基本原理是对因当的值再次突显两个内部空间,进而化解单向存取。,但es6有两个广度表达式的方式也能化解那个难题, let obj= Object.assign({}, obj)也能化解。

比如说两个字符串(array)

survive复本是当字符串a表达式成字符串b的这时候,b发生改变里头的字符串值的这时候,a也随著发生改变。

survive复本留存了两个对准该第一类的操作符,大部份的操作方式都是对该提及的操作方式,因此对对象的修正会负面影响其它的拷贝第一类。

广度复本是霍洛德字符串a表达式成字符串b的这时候,b发生改变里头的字符串值的这时候,a里头的字符串字符串不随著发生改变。

var

arr

=

[

“a”

,

“b”

,

“c”

,

“d”

,

“e”

];

var

Arr

=

JSON

.

stringify

(

arr

);

//先转化为string字符串的类型

var

Brr

=

JSON

.

parse

(

Arr

);

//在解析字符串的类型

Brr

[

1

]

=

h

;

//这种修正Brr中的字符串的这时候就不会影响到arr里头字符串的值

console

.

log

(

arr:

+

arr

);

//结果是arr:a,h,c,d,e

console

.

log

(

“Arr:”

+

Brr

);

//结果是Arr:a,h,c,d,e

那么为什么survive复本会发生改变a的字符串值而广度复本则不会呢?

因为survive复本对准的是同两个内存,而广度复本是增加了两个新的内存,因此不会负面影响到原来a的内存, 所 以就不会发生改变原来的值 eg.

var

arr

=

[

“a”

,

“b”

,

“c”

,

“d”

,

“e”

];

var

Arr

=

arr

;

Arr

[

1

]

=

h

;

console

.

log

(

arr:

+

arr

);

//arr的下标1的‘b’也变成了‘h’ 结果是:arr:a,h,c,d,e

console

.

log

(

“Arr:”

+

Arr

);

//结果是:Arr:a,h,c,d,e

字符串的深复本

对于字符串的深复本常规的有三种方式:

方式一:遍历拷贝

var

arr

=

[

“a”

,

“b”

],

arrCopy

=

[];

for

(

var

item in arr

)

arrCopy

[

item

]

=

arr

[

item

];

arrCopy

[

1

]

=

“c”

;

arr

// => [“a”, “b”]

arrCopy

// => [“a”, “c”]

考虑伪多维数组能写成函数形式:

function

arrDeepCopy

(

source

){

var

sourceCopy

=

[];

for

(

var

item in source

)

sourceCopy

[

item

]

=

typeof

source

[

item

]

===

object

?

arrDeepCopy

(

source

[

item

])

:

source

[

item

];

return

sourceCopy

;

}

这种方式简单粗暴,但借助JS本身的函数我们能更加便捷地实现那个操作方式。

方式二:slice()

能参考 W3School 对 slice() 方式的描述:slice() 方式可从已有的字符串中返回选定的元素。

调用格式为:

arrayObject.slice(start,end) 方式返回两个新的字符串,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。该方式并不会修正字符串,而是返回两个子字符串。

在这里他们的思路是直接从字符串开头截到尾:

arrCopy = arr.slice(0); arrCopy[1] = “c”; arr // => [“a”, “b”] arrCopy // => [“a”, “c”] 能看出成功创建了一份原字符串的复本。

方式三:concat()

能参考 W3School 对 concat() 方式的描述: concat() 方式用于连接两个或多个字符串。

调用格式为: arrayObject.concat(arrayX,arrayX,……,arrayX) 该方式不会发生改变现有的字符串,而仅仅会返回被连接字符串的两个副本。

使用这种方式的思路是他们用原字符串去拼接两个空内容,放回的便是那个字符串的复本:

arrCopy

=

arr

.

concat

();

arrCopy

[

1

]

=

“c”

;

arr

// => [“a”, “b”]

arrCopy

// => [“a”, “c”]

第一类的深复本

对于字符串的深复本他们有了概念,那么通常第一类呢?

他们给出两个第一类:

var

obj

=

{

“a”

:

1

,

“b”

:

2

};

同样做测试:

var

objCopy

=

obj

;

objCopy

.

b

=

3

;

obj

// => { “a”: 1, “b”: 3 }

objCopy

// => { “a”: 1, “b”: 3 }

同样,简单的表达式运算只是创建了一份浅复本。

而对于第一类的深复本,没有内置方式能使用,他们能他们命名两个函数进行这一操作方式:

var

objDeepCopy

=

function

(

source

){

var

sourceCopy

=

{};

for

(

var

item in source

)

sourceCopy

[

item

]

=

source

[

item

];

return

sourceCopy

;

}

但对于复杂结构的第一类他们发现那个函数并不适用,例如:

var

obj

=

{

“a”

:

{

“a1”

:

[

“a11”

,

“a12”

],

“a2”

:

1

},

“b”

:

2

};

因此须要进行一点修正:

var

objDeepCopy

=

function

(

source

){

var

sourceCopy

=

{};

for

(

var

item in source

)

sourceCopy

[

item

]

=

typeof

source

[

item

]

===

object

?

objDeepCopy

(

source

[

item

])

:

source

[

item

];

return

sourceCopy

;

}

var

objCopy

=

objDeepCopy

(

obj

);

objCopy

.

a

.

a1

[

1

]

=

“a13”

;

obj

// => { “a”: { “a1”: [“a11”, “a12”], “a2”: 1 }, “b”: 2 }

objCopy

// => { “a”: { “a1”: [“a11”, “a13”], “a2”: 1 }, “b”: 2 }

3、第一类字符串的深复本

如果再考虑更奇葩更复杂的情况,例如他们定义:

var obj = [{ “a”: { “a1”: [“a11”, “a12”], “a2”: 1 }, “b”: 2 }, [“c”, { “d”: 4, “e”: 5 }]]; 这是两个由第一类、字符串杂合成的奇葩字符串,虽然他们平时写程序基本不可能这么折腾他们,但能作为一种特殊情况来考虑,这种他们就能结合之前说的方式去拓展复本函数:

var

objDeepCopy

=

function

(

source

)

{

var

sourceCopy

=

source

instanceof

Array

?

[]

:

{};

for

(

var

item in source

)

{

sourceCopy

[

item

]

=

typeof

source

[

item

]

===

object

?

objDeepCopy

(

source

[

item

])

:

source

[

item

];

}

return

sourceCopy

;

}

var

objCopy

=

objDeepCopy

(

obj

);

objCopy

[

0

].

a

.

a1

[

1

]

=

“a13”

;

objCopy

[

1

][

1

].

e

=

“6”

;

obj

// => [{ “a”: { “a1”: [“a11”, “a12”], “a2”: 1 }, “b”: 2 }, [“c”, { “d”: 4, “e”: 5 }]]

objCopy

// => [{ “a”: { “a1”: [“a11”, “a13”], “a2”: 1 }, “b”: 2 }, [“c”, { “d”: 4, “e”: 6 }]]

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务