• Javascript 学习笔记(一)


      最近在学习ES6的时候,看到ES6相对于ES5新增了块级作用域,在ES5中内层变量可能会覆盖外层变量,引起全局变量的污染

    var tmp = new Date();
    
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = "hello world";
      }
    }
    
    f(); // undefined
    

      刚开始不知道为什么输出的是undefined,后来才想起了JavaScript执行之前会有一个词法分析的过程。上面代码中,函数f执行后,输出结果为undefined,,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。所以这里,将之前学的有JavaScript词法分析的知识整理一遍,方便已有记忆。

      JavaScript代码自上而下执行,引擎负责整个代码的编译以及运行,编译器则负责词法分析、语法分析、代码生成等工作而作用于则如我们熟知的一样,负责维护所有的标识符(变量),但是在js代码执行前,会首先进行词法分析,所以事实上,js运行要分为词法分析执行两个阶段。

    词法分析:

      词法分析主要分为3步

        第1步:分析形参
        第2步:分析变量声明
        第3步:分析函数声明

      如果存在函数嵌套,则从外往内进行词法分析

    代码演示与分析: #1

    function fn1(age,hei) {
      alert(age); // 32 var age = 12; //进行赋值 AO[fn1].age=12 alert(age); // 12 alert(hei); // undefined } fn1(32);

      词法分析:    

        在函数 fn1 调用的瞬间,会产生一个AO(Active Object)对象:    

        1.分析形参

          ① 分析函数的形参,然后将形参作为AO的属性,并且属性的值是 AO.age=undefined、AO.hei=undefined;
          ② 分析函数的实参列表,会把形参列表和函数内部的一个arguments对象(保存当前函数的实参列表,类似数组)形成一个一一对应的关系:arguments[0]=32;分析完实参之后,会检查arguments对象和AO对象的关系——AO.age=arguments[0]=32,AO.hei依然是undefined;    

        2.分析 var 声明的变量

          分析函数内部 var 声明的变量,去检查AO对象上是否存在同名的属性,如果存在,则不作任何的处理;如果不存在则将变量作为AO对象的属性,并且属性的值为undedined即: AO.age=undefined;

        3.分析 function 声明的函数

           没有

      执行过程:

        alert( age )   // 32

        alert( age )  //12  代码执行在这之前的  var age=12 会重新给 AO对象的 age属性赋上新的值

        alert( hei )  //undefined

    代码演示与分析: #2 

    function a(b) {
    	alert(b);
    	function b(){
    		alert(b);
    	}
    	b();
    }
    a(1);
    

      词法分析:

        在函数 a 调用的瞬间,会产生一个AO(Active Object)对象:AO[a]

        1.分析形参

          ① 分析函数的形参b,然后将形参作为AO[a]的属性,并且属性的值是 AO[a].b=undefined;

          ②分析传参,将实参列表与作用域链内部的arguments对象进行对比,arguments[0]=1AO[a].b=arguments[0]=1

        2.分析 var 声明的变量

          没有

        3.分析 function 声明的函数

          分析函数内部的 function 声明的函数, 如果在AO[a]上发现了与函数名相同的属性,则直接覆盖;如果没有则将其设置成AO[a]的属性,属性的值就是这个函数的表达式:AO[a].b= function b(){ alert(b) }

      执行过程:

        alert(b);   // function b(){ alert(b) }

        b();         //执行的过程中,会在自身的 AO[b]上查找属性,如果自身不存在则会去外层的 AO上查找,如果外层还是不存在则会去全局的window上面查找,AO查找的这条连就是作用域链,所以->function b(){ alert(b) }

        

     代码演示与分析: #3

    function test(a) {
    	console.log(a);
    	console.log(b);
    	var a = 10;
    	var b = 11;
    	console.log(a);
    	console.log(b);
    
    	var a = function () {
    		var d =10;
    	}
    
    	function e() {
    		var f = 10;
    	}
    
    	console.log(a());
    	console.log(a);
    	console.log(a);
    
    }
    test(1)
    

      词法分析:

        1.分析形参

          AO[test].a = undefined  —>    arguments[0] = 1   —>   AO[test].a = arguments[0] = 1

        2.分析 var 声明的变量

          AO[test].a = 1 (已存在属性,不做操作)    AO[test].b = undefined 

        3.分析 function 声明的函数

          AO[test].e = function e() { var f = 10; }

       执行过程:

        console.log(a);   // 1

        console.log(b);  // undefined

        console.log(a);   // 赋值AO[test].a = 10  —>   10

        console.log(b);  // 赋值AO[test].b = 11  —>   11

        console.log(a());  //a方法,没有返回值。默认返回 undefined

        e();                      //e方法,没有返回值。默认返回 undefined

        console.log(a);   // AO[test].a = function { var d =10;}   当代码执行到第二个var a时,javascript引擎由于第一步编译器忽略了重复声明的var,且作用域中已经有a,所以重复声明会发生值的覆盖,但并不会报错

  • 相关阅读:
    20150212-2015
    SM30维护视图添加按钮
    SAP保存操作记录CDHDR和CDPOS表
    20150123-慢慢
    20150124-轻轻
    维护 物料主数据 号码段
    ABAP DEMO-2018
    工具
    幽门螺杆菌资料收集
    MySQL 8 连接时出现 1251 和 2059 错误
  • 原文地址:https://www.cnblogs.com/jinxiblog/p/7494717.html
Copyright © 2020-2023  润新知