zoukankan      html  css  js  c++  java
  • js中的堆和栈

    一.栈和堆

    栈(stack):栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。(基本类型:String,Number,Boolean,Null,Undefined)
    堆(heap):动态分配的内存,大小不定也不会自动释放,存放引用类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量,实际上保存的不是变量本身,而是指向该对象的指针。(引用类型:Function,Array,Object)

    二.区别

    栈:所有在方法中定义的变量都是放在栈内存中,随着方法的执行结束,这个方法的内存栈也自然销毁。
    优点:存取速度比堆快,仅次于直接位于CPU中的寄存器,数据可以共享;
    缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
    堆:堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是为了反复利用,这个对象将被保存到运行时数据区。

    三.栈和堆的溢出

    栈:可以递归调用方法,这样随着栈深度的增加,JVM维持着一条长长的方法调用轨迹,知道内存不够分配,产生栈溢出。
    堆:循环创建对象,通俗点就是不断的new 一个对象。

    四:传值和传址的区别

    栈和堆的区别:即基本类型和引用类型的区别

    var a = [1,0,9,8,7];
       var b = a;
       var c = a[0];
       console.log(b);     //[1,0,9,8,7]
       console.log(c);     //1
       //改变数值
       b[1] = 3;
       c = 5;
       console.log(b[1]);  //3
       console.log(a[0]);  //1  
    

    五.深浅拷贝

    深浅拷贝在前端面试中经常被问到,和大家分享一下,先来说说浅拷贝
    浅拷贝:也就是只复制了第一层属性,复制对象是基本类型
    在复制基本类型时,直接使用等号完成,在复制引用类型时,循环遍历对象,对每个属性或值使用等号完成。
    因为a是数组,是引用类型,赋给b的时候传的是栈中的地址,不是堆内存中的对象,c仅仅是从a堆内存中获取的一个数据值,并保存在栈中,所以b修改的时候,会根据地址回到a堆中修改,c则直接在栈中修改,并且不能指向a堆内存中。

            var color1 = ['red','green']; 
            var color2 = [];
            //复制
            for(var i  = 0;i < color1.length;i++){
              color2[i] = color1[i]; 
            }
            console.log(color2);  //[red,green]
            color1.push('black');
            console.log(color2);  //[red,green]
    

    在这个栗子中,color2复制color1,因为数组中的每一项都是基本类型(string),假如数组中的某一项保存的是一个对象,或者是一个数组,又或者说对象的某一个属性还是一个对象(也就是引用类型的某个属性还是引用类型),此时浅拷贝就没用了

    var person = {
        name : 'wang',
        score:{
                math:100,
            English:100
            }
        }
    

    score属性还是一个对象
    深拷贝:对属性中所有引用类型的值,遍历到是基本类型的值为止,利用递归来实现深拷贝。

    function cloneObject (obj) {
         var newObj = {}  //如果不是引用类型,直接返回
          if (typeof (obj) !== 'object') {
              return obj
         }
         //如果是引用类型,遍历属性
        else{
            for (var attr in obj) {
            //如果某个属性还是引用类型,递归调用
            newObj[attr] = cloneObject(obj[attr])
                    }
           }
        return newObj
      }
    

    对于深拷贝,先判断它是否为引用类型,如果不是,直接返回
    如果是,循环遍历该对象的属性,如果某个属性还是引用类型,则针对该属性再次调用deepClone函数。

    链接:https://www.jianshu.com/p/67c0323aef1e

  • 相关阅读:
    sql&nbsp;一些语法&nbsp;聚合函数,…
    SQL标准
    margin:auto 和margin:0 auto的区别
    div居中
    相对问题和绝对问题
    有三行文字,每行最多80个字符,求其中大写字母,小写字母,数字,空格和其他
    输入n个字符串,将以A打头的字符串输出
    判断一个字符串是否是回文字符串
    从键盘键入5个国家的名字,按字典序输出
    输入五个字符串,输出最长的字符串
  • 原文地址:https://www.cnblogs.com/cherishnow/p/10901586.html
Copyright © 2011-2022 走看看