• 怎样理解基本类型(原始类型)的数据和引用类型的数据


    前言: 数值 / 字符串 / 布尔值 是基本类型, 对象 / 数组 / 函数是引用类型

    ES5中有6种数据类型, 分别为: number / string / boolean / null / undefined / object. 这里的对象是广义的对象, 还可以细分为: array / function / object等. 

    typeof(1); // "number"
    typeof("1"); // "string"
    typeof(true); // "boolean"
    typeof({}); // "object"
    typeof(null); // "object"
    typeof(undefined); // "undefined"
    
    // 数组也是对象
    typeof([1,2,3]); // "object"
    
    // 函数也是对象
    var aFunc = function() {};
    typeof(aFunc); // "function";
    aFunc instanceOf Object; // true

    其中, number / string / boolean 为基本类型, 也叫作: 原始类型; 而 object 则是引用类型, 这里的null 和 undefined有点特殊, 暂时不管它;

    注意: 

    1. 尽管typeof(null)为"object", 但: null instanceOf Object 为 false.

    2. typoof(undefined) 为 "undefined";

    第一步: 基本类型的数据存储在栈内存中

    什么是栈内存呢? 我们目前可以简单理解为是下面这样, 在取得栈内存中的数据时的过程是根据变量名, 找到对应的内存地址, 再把内存地址中的数据取出来.

    也就是说,  栈内存中的数据不能还是内存地址, 只能是特定的值, 这个值其实就是我们说的基本类型. 比如下面这段代码, 我们声明一个叫做: name的变量, 此时内存中就将一个内存地址同这个name作绑定, 然后我们给它赋值一个字符串: "hanmeimei", 这时内存中就会创建一个字符串数据: "hanmeimei", 并且将这个数据所在的内存地址"绑定"到变量名name上. 这样就实现了赋值.

    当我们修改这个这个值为 "lilei"时, 实际上是修改了name指向的内存地址, 此时name将不再指向"hanmeimei"所在的内存地址.

    // 声明一个变量, 因为变量没有赋值, 因此指向 undefined;
    var name; 
    
    // 赋值, 内存中新创建的 "hanmeimei" 数据的地址绑定到了 name上, name不再指向 undefined;
    name = "hanmeimei";
    
    // name 指向内存中新创建的 "lilei" 数据所在的内存地址, 不再指向 "hanmeimei"所在的内存地址
    name = "lilei";

    上面这一过程经历了下面的过程:  

     

    注意: 

    1. JavaScript中一切皆对象, 基本类型也是如此, 只是他们的对象特征体现在他们各自的包装对象上.

    2. 真实的作用过程远比上图描述的复杂, 这里仅作演示;

    3. 如果一个数据没有被任何变量所指向, 那这个数据将会被垃圾回收机制所销毁, 内存将会释放;

    第二步: 引用类型的数据存储在堆内存中

    堆内存是内存中另一种数据组织方式, 不同于栈内存中的 变量 => 内存地址  => 数据这种引用方式, 堆内存中的存储的数据还是内存地址, 也就是说: 从堆内存中取数据要不断地去找数据中内存地址指向的数据, 如果仍旧是内存地址, 则继续往下找. 比如下面这个数组中的数据就是最简单的堆内存: 

    var family, son;
    
    son = "liqiang";
    
    family = ["lilei", "hanmeimei", son];

    对应的演示图如下: 

     

    注意: 

    1. 基本类型无法被修改, 只能被覆盖, 原因是基本类型指向的内存地址里面的数据无法被修改, 只能新建一个数据, 把变量名指向这个内存地址;

    2. 原始类型可以被修改, 指的是它指向的内存地址里面的内存地址可以被修改, 比如上面的000009地址里面的数据, 完全可以再加其他的. 不过加的也只能是内存地址;

    3. 类似String.prototype.replce()一类的类型原始的方法, 产生的数据都是在一个新的内存地址上, 因为它无法做到改变自身.

  • 相关阅读:
    中国开源现状如何?
    程序员怎么升职?
    如何从挫败感到成就感,身为程序员每天都在经历这些!
    现实版“无间道”,4名煞星潜伏,只为拖库!
    想想当初为什么做程序员!
    做程序员累的时候想想这个!
    别人问我:为什么程序员都不善言辞?惭愧啊!
    程序员被沦陷!国内程序员真的饱和了?
    JS和JSP的区别?
    web.xml配置WebApplicationContext的两种方法
  • 原文地址:https://www.cnblogs.com/aisowe/p/11586433.html
Copyright © 2020-2023  润新知