[ JS个人笔记 ] 传值传址&深浅层拷贝—DAY5

传值(call by value)vs传址(call by reference)

基本型别(Number、String、Boolean、null、undefined)属于 call by value。物件型别(Array、Object、function) 为 call by reference。

1. 传值

当资料为基本型别(如 string、number、boolean、null、undefined),那么即为赋值。

let a = 10let b = 10console.log(a === b) // true

a 更新后不会影响 b

let a = 10let b = aa = 20console.log(a === b) // false

2.传址

当资料为物件型别(Array、Object、function),那么即为赋址。

var obj1 = { v1: 1 };var obj2 = { v1: 1 };console.log( obj1 === obj2 );  // false

因为两者的记忆体位置并不相同。在比较物件型别时,比较的是记忆体位置,而非值。

let obj1 = { v1: 1 };let obj2 = obj1;obj1.v1 = 0;console.log( obj2.v1 );  // 0obj2.v2 = 2;console.log( obj1.v2 );  // 2console.log( obj1 === obj2 );  // true

当我们修改任意物件属性时,另一边的属性也会更动,这是因为两个变数指向相同的记忆体位置,并没有新的物件被複製出来。

注意例外

pass by sharing => 当物件被传入function当参数且物件被重新赋址时,物件是不会被影响的。
let obj1 = { v1: 1 };function change(e){e = {v1:100};console.log(obj1)   //{ v1: 1 }}change(obj1)console.log(obj1)   //{ v1: 1 }

若改成以下,则可变更资料

let obj1 = { v1: 1 };function change(e){console.log(obj1)   // { v1: 1 }e.v1=100;}change(obj1)console.log(obj1)  //{ v1: 100 }

浅层拷贝vs深层拷贝

浅层拷贝:複製资料只能複製第一层,因为深层的物件或阵列还是传址,不会完全複製一份深层拷贝:深拷贝就是完全複製一份,不会有共用记忆体的问题。

1.浅层拷贝常见方法

物件的浅拷贝Object.assign()展开运算子 ...阵列的浅拷贝slice()concat()forEach + push()map()filter()... 展开运算子

2.深层拷贝常见方法

利用 JSON 方法:先转 JSON 格式,再转回来。第三方函式库jQuery 的 $.extendLodash 的 _.cloneDeep()

更详细内容请参考 竹白笔记

面试题目

1.b 会呈现什么答案?

let a = {};let b = a ;let c = b = {number:1};c.name = "tom";console.log(b)

Ans:{number:1,name:tom}
在第三行,c、b皆指向{number:1}
2.请问 console.log(hello.a)、console.log(a)会出现什么?

function hello(){  a = 1;}hello.a = "hi";hello();console.log(hello.a)console.log(a)

Ans:hi、1

3.console.log(family[0].members.bro)会是?

let family = [{  name:"tom",  members:{    mon:'妈',    dad:'爸',    bro:'哥',  }}]let newArray = [];family.forEach((item)=>{  newArray.push(item);})newArray[0].members.bro = '弟' ;console.log(family[0].members.bro)

Ans:弟
因浅层拷贝,故深层指向被複製的物件

4.console.log(family.name)、console.log(family.members.mon)会是?

let family = {  name:"tom",  members:{    mon:'妈',    dad:'爸',    bro:'哥',  }};let newfamily = {...family};newfamily.name = 'ted';newfamily.members.mon = "momy" ;console.log(family.name)console.log(family.members.mon)

Ans:tom、momy


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章