栈堆内存及函数底层处理机制

@1 先来一道面试题吧!
        if (a==1&&a==2&&a==3) {console.log('如何能让代码正常输出')} ?
        看起来是不是不可思议,如何让同一个变量a同时满足三个条件呢?
        先公布一下答案: 
                答案1:var a = {  a:0,
                                            [symbol.toPrimitive] () {return ++this.a} 
                                          }
                解答问题:思路
                                   利用==进行比较的时候,首先会把对象和数组通过Number()转换为
                                   数字,转化的过程,会先去寻找对象数组的[symbol.toPrimitive]的方法,如果
                                   结果为undeifend,则继续执行valueof获取原始值,如果获取的不是原始值,
                                   则需要通过tostring转为字符串,最终再通过number转为数字类型。
                                    a==1, 因为我们在对象中重新写了[symbol.toPrimitive]的这个方法,所以
                                    会返回这个方法执行以后的数据也就是 1 
                                    a==2, 会再次执行[symbol.toPrimitive]的这个方法,返回这个方法以后的                                        数据也就是 2 
                                    执行第三次也就是 3 ,所以判断条件里面的代码会被执行。
                答案2:var a= 0  给全局的window 添加一个a的属性;使用数据劫持的方法改变a的值
                解答问题:思路
                                    数据劫持:当从window上面访问a的时候让a的值++;
                                    Object.defineProperty(window, a, { 
                                                get () {
                                                             return ++a;
                                                       }
                                      })
                                    结论每执行a==1或a==2一次就会使a进行++;上面的判断代码执行。
                答案3:var a = [1, 2, 3] ;a.tostring = a.shift ;
                解答问题:重温下 数组对象转数字的步骤,相当于重写了a的tostring的方法; 每次执行                  a.tostirng = a.shift  a 分为等于1  2  3 ;所有也会执行    


@2  接下来我们再来了解一下数据存储的机制:
       
电脑内存:【虚拟内存(8GB)+ 物理内存(硬盘500GB)】
        1 当浏览器打开一个页面的时候,计算机会从虚拟内存中分配两块内存【堆内存+栈内存】
        2 栈内存(ECstack):作用 2.1 提供代码执行环境,2.2 存储声明的变量和原始值,2.3创建
            一个全局执行上下文(EC),全局代码执行的环境,2.4创建一个存放变量的地方(VO)
        3 堆内存(HEap): 3.1存储对象和函数类型的值,3.2内存中默认开辟一个16进制的空间,用
           于存储全局(GO)的Api例如定时器等;
        4 let a = 12,存储执行的过程:
            第一步:先创建值,如果是原生值类型放在栈里面,如果是对象类型放在堆里面,把地 
                           址赋值给栈里面。
            第二步: 声明变量,将变量放到变量对象中存储也就是栈VO环境中
            第三步: 把创建的值赋值给变量,让变量和值关联在一起,如果是对象创建指针

@3 我们来看一道面试题:
       
let a = {n:1} ;  let b = a ; a.x = a = {n:2};console.log (a.x) ? ;  console.log (b) ? ;
        解答思想:
        a创建出了一个堆内存空间0x001用来存储{n:1}, 同时在栈内存空间存储了a的变
        量和指针0x001。 
        b等于a,在栈内存创建一个b的变量,b同样拥有了指针0x001,指向与a同一块的堆内存
        空间。
        a.x = a = {n:2} // 执行过程:第一步:a.x = {n:2} 给0x001的指针添加了x:{n:1}的属性。再执行
        a={n:2}相当于在堆内存空间,重新创建一个空间0x002存储的{ n:2 }, 这时候a的指针由原来的
        0x001,指向了0x002。
        结论 :  console.log(a.x) // undefiend   console.log(b) // {n:1, x:{n:2}} 

栈堆内存及函数底层处理机制_第1张图片栈堆内存及函数底层处理机制_第2张图片




 

你可能感兴趣的:(javascript,开发语言,ecmascript)