阅读 86

Vue3 基础语法——补充知识

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

1. 对象的引用、浅拷贝、深拷贝

1.1 对象的引用赋值

我们知道,对象是引用类型(JavaScriptJava 等语言中称为引用类型,而在 CC++ 等语言中称为指针),也就是说我们在用对象给某个变量赋值时,实际上是把对象的引用(是一个内存地址)赋值给了该变量,之后我们就说这个变量引用了这个对象(其实就是一个指针,指向了这个对象的内存地址)。

// 对象是引用类型
const info = { name: 'zhj', age: 20 };
const obj = info;
info.name = 'wy';
console.log(obj.name); // wy
复制代码

上面这段代码在内存中的表现如下:

image-20210914193422284.png

1.2 浅拷贝

浅拷贝的方法有很多,我们以 Object.assign() 方法为例:

const info = { name: 'zhj', age: 20 };
// 即把第二个参数 info 对象中所有的属性拷贝一份放到第一个参数对象 {} 中,然后将第一个参数对象作为返回值返回
const obj = Object.assign({}, info);
info.name = 'wy';
console.log(obj.name); // zhj
复制代码

上面这段代码在内存中的表现如下:

image-20210914211205002.png

但是,假如上面的 info 对象中不全是基本类型的属性,还有对象类型的属性,那么再对源对象的该对象属性中的属性(info.friend.name)做修改,也会影响拷贝出的对象的该对象属性中的属性值(obj.friend.name),它们的值是一样的,因为它们引用着堆内存中的同一个对象(infoobjfriend 属性引用的那个对象):

const info = { 
  name: 'zhj', 
  age: 20,
  friend: {
    name: 'ls',
    height: 1.88
  }
};
const obj = Object.assign({}, info);
info.name = 'wy';
console.log(obj.name); // zhj
info.friend.name = 'ww';
console.log(obj.friend.name); // ww
复制代码

上面这段代码在内存中的表现如下:

image-20210914214314157.png

因此,浅拷贝只是将对象的第一层属性进行了拷贝,而对更深层的属性其实是没有做拷贝的。

1.3 深拷贝

深拷贝的方法也有很多,我们拿一种原生的方式(使用 JSON 的两个方法)为例:

const info = { 
  name: 'zhj', 
  age: 20,
  friend: {
    name: 'ls',
    height: 1.88
  }
};
// 先通过 JSON.stringify() 方法把对象转成字符串,在通过 JSON.parse() 方法把字符串还原成对象。还原的时候会在内存中生成一个新的对象,和原来的对象没有任何关系。
const obj = JSON.parse(JSON.stringify(info));
info.name = 'wy';
console.log(obj.name); // zhj
info.friend.name = 'ww';
console.log(obj.friend.name); // ls
复制代码

上面这段代码在内存中的表现如下:

image-20210914220016915.png

因此,深拷贝会对每一层的对象都进行拷贝(拷贝一份新的,而不是使用原来的)。

1.4 使用第三方库的浅/深拷贝方法

除了使用 JS 原生的方式实现浅拷贝或深拷贝,我们还可以使用 lodash 库提供的浅拷贝、深拷贝方法:

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
复制代码
const info = { 
  name: 'zhj', 
  age: 20,
  friend: {
    name: 'ls',
    height: 1.88
  }
};
// const obj = Object.assign({}, info);
// 使用 lodash 的 clone() 方法进行浅拷贝
const obj = _.clone(info);

info.name = 'wy';
console.log(obj.name); // zhj
info.friend.name = 'ww';
console.log(obj.friend.name); // ww
复制代码
const info = { 
  name: 'zhj', 
  age: 20,
  friend: {
    name: 'ls',
    height: 1.88
  }
};
// const obj = JSON.parse(JSON.stringify(info));
// 使用 lodash 的 cloneDeep() 方法进行浅拷贝
const obj = _.cloneDeep(info);

info.name = 'wy';
console.log(obj.name); // zhj
info.friend.name = 'ww';
console.log(obj.friend.name); // ls
复制代码

2. JS 逻辑判断中的隐式转化

逻辑判断时,如果是一个内容为数字的字符串和一个数字进行比较,会隐式的自动将这个内容为数字的字符串转化为 number 类型后再进行比较:

const score = "100";
// 字符串 "100" 和 number 类型的 90 比较,会先将 "100" 转换为 number 类型的 100,再拿 100 和 90 比较
if (score > 90) { // true
  console.log('优秀');
}
复制代码
文章分类
前端
文章标签