美文网首页
前端--关于值类型和引用类型(放心,术语很少)

前端--关于值类型和引用类型(放心,术语很少)

作者: 银魂飞雪 | 来源:发表于2019-11-01 12:53 被阅读0次

在帮同事解决问题时,经常遇到诸如:

  • 我没有改过这个数据啊,为什么会变了...
  • 为什么我在页面A修改了数据,页面B的也会变

原因通常都是引用类型,既然引用类型容易引起误解,那为什么还要设计引用类型?

答案是性能

做个小测试,循环一定次数,给分别给值类型和引用类型赋值,观察

  • 内存占用
  • CPU占用
  • 耗时
const cpuStat = require('cpu-stat');

function sub(x1, x2) {
  let result = {};
  for (const key in x2) {
    result[key] = x2[key] - x1[key];
  }
  return result;
}

function loop(des, func, count) {
  return new Promise((resolve) => {
   // 强制GC,且在2秒后再运行代码
    global.gc();

    setTimeout(() => {
      cpuStat.usagePercent(function (err, percent, seconds) {
        if (err) {
          return console.log(err);
        }
        console.log(`${des}CPU: ${percent}`);
      });
      const startM = process.memoryUsage();
      const startTime = Date.now();
      for (let i = 0; i < count; i++) {
        func();
      }
      const endM = process.memoryUsage();
      const endTime = Date.now();
      console.log(`${des}Memory: ${JSON.stringify(sub(startM, endM), null, 2)}`);
      console.log(`${des}Time: ${endTime - startTime}`);

      setTimeout(() => {
        resolve();
      }, 3000)
    },2000)
  })
}

const count = 2000000000;

async function execute() {
  const strSource = '某柏慧燕都非要玩要一二三五点五十旱地';
  await loop('str', () => {
    let str = strSource;
  }, count);

  const objSource = { x: strSource };

  await loop('obj', () => {
    let obj = objSource;
  }, count);
}

execute();

运行三次的结果,平均来看
引用类型的内存占用有巨大的优势

内存

值类型(string)占用内存为:2330624字节
引用类型(object)占用内存为:733184字节

约3倍

耗时

值类型为:1021毫秒
引用类型为:779毫秒

约1.3倍

CPU占用

值类型为:9.039%
引用类型为:7.960%
约1.13倍

由此可见,引用类型在性能,特别是内存占用上有巨大的优势。所以,为了性能,必须要把引用类型弄清楚。

我们知道,计算机的临时数据是存在内存中,而每块内存又要有起始地址。
换一个形象的例子:有一排杯子,用来存东西,每个杯子上绑了一些线。杯子表示内存,线表示指向内存的变量

  • 引用类型:每次赋值就是在杯子上绑一根线,定义1000个变量=这个杯子,相当于在杯子上绑了1000根线
  • 值类型:每次赋值就是加一个新杯子,并在杯子上绑一线

其中,杯子就是占用的内存,线就是定义的变量

image.png image.png

显示,对于

  • 引用类型,其中通过其中一根获取到杯子,并往里面加了水。 对于绑在杯子上的其它线,水也增加了。
  • 对于值类型,因为一根线只能对应一个杯子,所以通过某根线获取到杯子,并里面加水,不会影响到其它线绑定的杯子。

当然,有些语言,可以直接操作内存,比如C++不仅有指针,还有指针的指针,这里就不考虑了。

                                  -------------附运行结果图------------
image.png image.png image.png

相关文章

  • 前端--关于值类型和引用类型(放心,术语很少)

    在帮同事解决问题时,经常遇到诸如: 我没有改过这个数据啊,为什么会变了... 为什么我在页面A修改了数据,页面B的...

  • 面试

    值类型和引用类型 值类型和引用类型的区别是值类型直接存储其值,而引用类型存储对值的引用。这两种类型存储在内存的不同...

  • 慕课网《前端JavaScript基础面试技巧》学习笔记

    变量类型 值类型和引用类型 值类型只能存储一个值 值类型复制就是值类型本身 引用类型复制只是复制引用类型的指针 引...

  • 基本类型值和引用类型值

    JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值。 *引用类型包括: 基本类型值和引用类型...

  • 对象

    1.对象分为值类型和引用类型 值类型(不是对象) 引用类型(都是对象) 类型的判断值类型判断用typeof引用类型...

  • 01_JS面向对象

    知识点 数据类型 值类型和引用类型 值类型和引用类型的特征 值类型和引用类型做参数 对象的动态特性 给对象动态添加...

  • C# 装箱,拆箱,向上转型,向下转型

    c#中,数据类型分为值类型和引用类型,装箱和拆箱属于值类型和引用类型间的转换操作。 装箱:值类型向引用类...

  • 第一部分:C#语言基础

    第1章 C#类型基础 C#中的两种类型:值类型和引用类型 1.1 值类型和引用类型 值类型包括了结构和枚举,引用类...

  • c#面向对象11--值类型和引用类型/序列化和反序列化

    值类型和引用类型 值类型:int double char enum bool decimal struct引用类型...

  • C#值类型和引用类型

    值类型和引用类型的区别(小结)相同点:引用类型可以实现接口,值类型当中的结构体也可以实现接口;引用类型和值类型都继...

网友评论

      本文标题:前端--关于值类型和引用类型(放心,术语很少)

      本文链接:https://www.haomeiwen.com/subject/lzdfbctx.html