JavaScript中的堆与栈 、浅拷贝与深拷贝

96
王乐城愚人云端
0.1 2019.03.06 17:55* 字数 788

1. 什么是堆栈

在计算机领域中,堆栈是两种数据结构,它们只能在一端(称为栈顶(top))对数据项进行插入和删除,因而按照后进先出的原理运作。

  • 栈 stack:由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
  • 堆 heap:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

2. JavaScript中的基本类型和引用类型与堆栈的联系

  1. 基本类型:Undefined、Null、Boolean、Number 和 String,这5中基本数据类型可以直接访问,他们是按照值进行分配的,存放在栈(stack)内存中的简单数据段,数据大小确定,内存空间大小可以分配。
  2. 引用类型:即存放在堆(heap)内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。

内存

栈 stack 内存 堆 heap 内存
1
"hello"
true
null
undefined
object1 {name: 'tom', age: 23}
array1 [1,2,3]
varible 23

varible = object1.age 是引用,所以在堆中保存的是指针,在栈中保存的引用数据

  1. 最新的基本类型和引用类型,以及之间的区别。

基本数据类型:按值访问,可操作保存在变量中的实际的值。基本类型值指的是简单的数据段。

基本数据类型有这六种:undefined、null、string、number、boolean、symbol(es6)。

引用类型:当复制保存着对象的某个变量时,操作的是对象的引用,但在为对象添加属性时,操作的是实际的对象。引用类型值指那些可能为多个值构成的对象。

引用类型有这几种:Object、Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。

3. 什么是浅拷贝,深拷贝

  1. 基本类型:Undefined、Null、Boolean、Number 和 String,这5中基本数据类型的拷贝,是直接在栈(stack)中增加新数据,拷贝前后互不相干,所以不存在浅拷贝和深拷贝
  2. 引用类型, 浅拷贝下,拷贝引用类型的属性时,是拷贝引用的指针,所以修改内容会影响原始对象。深拷贝下,拷贝引用类型的属性时,是拷贝内容,所以修改不影响原始对象。

4. 手写浅拷贝,深拷贝

浅拷贝一,for in

function copy(obj){
    var newObj = {};
    for(var key in obj){
        newObj[key] = obj[key];
    }
    return newObj;
}

浅拷贝二, Object.keys

function copy2(obj){
    var newObj = {};
    Object.keys(obj).forEach(key=>{
        newObj[key] = obj[key]
    })
    return newObj;
}

深拷贝一,最简单,但只支持符合JSON格式的

function deepCopy(obj) {
    return JSON.parse(JSON.stringify(obj));
}

深拷贝二,(推荐)基本类型直接赋值,对象分三种情况,null, array,object,函数方法直接赋值

 function deepCopy(obj){
    var o;
    switch(typeof obj){
    case 'undefined': break;
    case 'string'   : o = obj + '';break;
    case 'number'   : o = obj - 0;break;
    case 'boolean'  : o = obj;break;
    case 'object'   :
        if(obj === null){
            o = null;
        }else{
            if(obj instanceof Array){
                o = [];
                for(var i = 0, len = obj.length; i < len; i++){
                    o.push(deepCopy(obj[i]));
                }
            }else{
                o = {};
                for(var k in obj){
                    o[k] = deepCopy(obj[k]);
                }
            }
        }
        break;
    default:
        o = obj;break;
    }
    return o;
}

深拷贝三,缺点,只支持拷贝对象

    function deepCopy(obj, clone) {
      clone = clone || {}
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === 'object') {
            clone[key] = Array.isArray(obj[key]) ? [] : {}
            deepCopy(obj[key], clone[key])
          } else {
            clone[key] = obj[key]
          }
        }
      }
      return clone
    }
日记本
Web note ad 1