js运行机制

作者: const_express | 来源:发表于2021-04-10 22:12 被阅读0次
    
    /*js运行机制题目*/
    /*知识点:
    1.所有的等号赋值,第一步是先创建值
    函数创建的时候就声明了她的作用域
    
    */
    
    /*
    全局代码执行作用域EC(G)
    
    */
    var i =0;
    function A(){
        var i =10;
        function x(){
            console.log(i)
        }
        // console.log(x)
        return x   //此时返回的是函数x的函数体
    }
    // console.log(A()+'111')
    var y=A()
    console.log(y)
    // y()
    // var y =A();
    y();
    function B(){
        var i =20;
        y()
    }
    B()
    
    
    /*一般函数执行完毕之后就出栈释放了  函数堆释放
    
    闭包:函数执行时产生一个不被释放的私有上下文(也就是被占用的时候 ),保护里面私有变量不受污染而且还可以把这些信息保存下来,
    供她的下级上下文使用 
    
    * heap 堆函数释放:空指针  比如:
    let obj ={a:'111'}
    obj=null  空指针,此时obj之前指向的堆被释放
    
    * stack 栈内存释放:
    1. 全局上下文中,页面关闭即释放
    2. 私有上下文中:
       (1)函数执行完,私有上下文都会出栈释放
       (2)当前上下文中的某些内容(比如一个堆),被除了当前上下文之外的内容占用了,就不能出栈.
    
    
    
       GC浏览器垃圾回收机制:
       (1)引用标记法_谷歌浏览器:当堆内存被占用时做标记(这个要自己查 TODO:)
       (2)引用计数_IE低版本浏览器 容易内存泄漏 TODO: 查一下内存泄漏的原因以及情况
       总结:当前内存如果被占用就不能被释放,没被占用的时候,浏览器会在空闲时间将他们释放出去
    
    
    
    
    
    */
    
    /*    let  const  var  的区别
    
    * let: 创建一个变量,这个变量可以在下面被修改 比如:
    let a =10;
    a =12
    console.log(a)-->12
    
    * const: 创建一个变量,关联一个值,这个值不可被修改(不能需修改此变量的关联指向) 比如:
    const b =10;
    b=12  --> 报错
    
    但是,如果  const 是一个对象,可以通过成员访问的方式进行修改
    比如:
    const b ={
        name:'qqq'
    }
    b.name='aaa'
    console.log(b)--> {name:'aaa'}
    
    
    * 再相同的上下文中
     (1) var 允许重复声明,但只识别一次
     (2) let 不允许重复声明
    
    
    
    */
    // console.log不会被执行,而是直接报错,是因为在词法解析阶段,如果有报错,所有代码都不会执行
    //code.html:103 Uncaught SyntaxError: Identifier 'b' has already been declared
    // console.log('ok')
    // const b =10;
    // const b =30;
    
    /*   
    var 和function 中声明的变量,除了在全局变量对象VO(G)中储存,也会在GO(window)中设置相应的属性.(新版处理机制:在全局上下文中
    基于bar 和function声明的变量,会直接存储到GO也就是window中,不会在 VO(G)中存储了)
    
    
    let 和const 中声明的变量,只会在全局上下文VO(G)中存储,不会在GO(window )中存储
    
    */
    
    /*  js 中的暂时性死区:用typeof检测一个未声明的变量,不会报错,会显示 'undefined'
    例如:  console.log(typeof n )  -->此时n未被声明,typeof n 形成暂时性死区     但是
    如果   let n =10   上面输出结果就会报错:不得在未声明之前使用n   所以 
    可以用 在下面let创建变量抵消上面的暂时性死区  即  let的机制可以抵消暂时性死区
    
    */
    
    console.log(typeof n)
    // var n =10  -->不会抵消暂时性死区
    //let n=10 
     //-->Uncaught ReferenceError: Cannot access 'n' before initialization  抵消暂时性死区
    
    {
         var k=20
        let m=90;// -->此时的m只是块级私有的 在下面无法被调用
       
        console.log(m)
    }
    console.log(m)
    
    
    /*
    匿名函数:把函数作为值赋给xxx
    例如:  xxx.onclick=function(){....}
    
    */
    
    
    /*
    this 的指向
    
    1-全局上下文中的this指向的是window
    2-块级作用域指向的是他所继承的this,箭头函数也是
    
    函数执行
     *   正常的普通函数执行:看函数执行前是否有“点”,有,“点”前面是谁this就是谁,没有“点”,this是window「严格模式下是undefined」,
     跟他在哪里调用 哪里执行的都没关系
     *   匿名函数:
     *     + 函数表达式:等同于普通函数或者事件绑定等机制
     *     + 自执行函数:this一般都是window/undefined
     *     + 回调函数:一般都是window/undefined,但是如果另外函数执行中,对回调函数的执行做了特殊处理,以自己处理的为主
     *   括号表达式:小括号中包含“多项”,这样也只取最后一项,但是this受到影响(一般是window/undefined),比如:(10,obj.fn)(),
     * 指向的是window,如果开启严格模式,会显示undefind
     * function fn() {
    //     console.log(this);
    // }
    // let obj = {
    //     name: 'zhufeng',
    //     fn
    //     // fn: fn
    // };
    // fn(); //this->window/undefined
    // obj.fn(); //this->obj
    自执行函数的this是window 或者undefeated(在严格模式下
    自执行函数举例:
    (function(){
        console.log(this)==>输出window
    })(10)
    
    
    回调函数:把一个函数A作为实参,传递给另外一个执行的函数B「在B函数执行中,可以把A执行」
    /* function fn(callback) {
        // callback -> 匿名函数
        callback();
    }
    fn(function () {
        console.log(this);
    }); */
    
    /* let arr = [10, 20, 30];
    // arr.forEach(function (item, index) {
    //     console.log(this); //->window
    // });
    arr.forEach(function (item, index) {
        console.log(this); //->forEach第二个参数「对象」  forEach内部做处理了
    },{xxx:'xxx'}); 
    
    
    数组的foreach方法,传的第二个参数会改变this的指向
    */
    //一道题来了!!
    var x = 3,
        obj = {
            x: 5
        };  
        /**在全局上下文中创建了变量
         * x-------3
         * 对象obj-------指向堆地址 0x001
         * 作用域
        **/
    obj.fn = (function () {
        this.x *= ++x;
        return function (y) {
            this.x *= (++x) + y;
            console.log(x);
        }
    })();
    
    /*
    自执行函数,在创建的时候会自己调用一次,指向堆地址0x002  
    作用域:全局 EC(G)
    
    内容:
    'this.x *= ++x;
        return function (y) {
            this.x *= (++x) + y;
            console.log(x);'
    
    执行: this.x=this.x*(++x),前面的this.x,是window.x,也就是3,后面的x也是全局的x,也是3  所以
    此时里面的x都是3 全局x经过运算之后
    this.x=this.x*(++x)
          =3*4
          =12
          
    
    执行完毕,返回一个匿名函数,存储在0x003 同时在0x001堆内存中创建 fn-------0x003,被占用,形成不被释放的闭包
    注意:自执行函数,创建时自调用一次之后,返回的值 赋给等号前面的东西
    此时:
    全局变量中:
    x-----3 变为 x------4(因为++x),再变为x-----12
    
    0x003的内容:
    'this.x *= (++x) + y;
            console.log(x)'
            形成作用域EC(003)
    
    执行完毕后,没有被占用,释放0x002内存
    
    此时0x001中的变量
    x-------5
    fn------0x003
    
    */
    var fn = obj.fn;
    
    /*在全局中创建一个变量fn-------0x003
    
    此时全局变量中存在的有:
    x-------------12
    obj--------0x001
    fn------------0x003
    */
    obj.fn(6);
    /*
    执行0x003中的代码段
    this.x *= (++x) + y;
            console.log(x)
    形成私有上下文,私有作用域EC(1),私有变量
    y--------传参6
    this的指向为obj,根据点语法,obj.fn调用,this就是obj
    this.x=this.x*((++x)+y)
          =5*((全局x--12自增=13)+6)
          =5*(13+6)
          =95
          此时obj中的x发生改变
    obj中:
    x-----5 变为x----95
    
    全局变量中
    x----12 因为自增,变成了x----13
    
    
    
    */
    fn(4);
    /*
    函数调用:相当于0x003中传参4
    因为没有被点,所以匿名函数的this 没有严格模式下为window
    此时:
    this.x *= (++x) + y;
            console.log(x)
    this.x是window中的x,为13,++x的x 也是全局的x 为13,y是此匿名函数执行时形成的新的私有上下文EC(2)中的私有变量
    y------4
    所以执行函数:
    this.x=this.x*((++x)+y)
          =13*((x--13自增为14)+4)
          =13*18
          =234
    ----也就是 此时全局的x变成了234
    因为没被占用,执行完毕后释放
    */
    
    console.log(obj.x, x,);
    /*最终这道题的答案是:
    obj.x为95
    x为234
    */
    
    
    
    
    

    相关文章

      网友评论

        本文标题:js运行机制

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