zoukankan      html  css  js  c++  java
  • JS学习之预解释

    预解释(hoisting),或者有的地方翻译为变量提升,是指在当前作用域下,JS代码从上到下执行之前,浏览器会默认先把带var和function关键字的进行提前声明或者定义。

    声明(declare):只声明,没有定义,如var num,此时num的默认值是undefined

    定义(defined):即赋值操作。

    一、var的预解释

    var:预解释的时候只提前的声明,在代码执行的过程中才定义赋值。

    1 var num=15;
    2 console.log(num); //15

    上面的代码,很显然输出15,那么看看下面的代码:

    1 console.log(num); //undefined
    2 var num = 15;
    3 console.log(num);//15

    num经过了预解释,当代码执行到第一行时,输出num的默认值undefined,执行到第二行时,才给num定义即赋值为15,执行到第三行时,输出num为15 。再看看下面的代码:

    1 console.log(num);//Error:num is not defined
    2 num = 12;

    不带var的变量是不进行预解释的,所以代码执行到第一行就会报错。

     

    二、function的预解释

    注意,function的预解释和var的预解释是不太一样的

    function:预解释的时候,声明和定义都完成了。

    1 var num = 12;
    2 function fn() {
    3     console.log(num); //undefined
    4     var num = 13;
    5     console.log(num); //13
    6 }
    7 fn();

    先进行全局作用域(window)下的预解释,var num,fn声明和定义,之后代码从上到下执行,给num赋值=12,因为fn在预解释的时候已经声明+定义过了,所以可以跳过声明和定义这段,直接到第7行的fn(),执行fn,此时fn函数执行,会形成一个私有作用域,在这个私有作用域中,又开始了预解释,var num,然后这个私有作用域中的代码从上到下执行,第一个次输出只声明未定义的num为undefined,第二次输出13 。

     下面总结一下预解释的一些情况:

    1.不管条件是否成立,都会进行预解释:

    1 if (!("a" in window)) {
    2     var a = 1;
    3 }
    4 console.log(a);//-->undefined

    window下的预解释,var a,相当于给window增加一个属性-->window.a,,代码执行,if判断"a" in window为true,取反,所以条件不成立,输出undefined。

    2.只对"="左边的进行预解释,右边的是值,不进行预解释:

    1 fn();//-->undefined() Error:fn is not a function
    2   var fn = function () {
    3   console.log(1); 
    4 };

    3.window下对自执行函数是不进行预解释的,自执行函数的定义和执行是一起完成的了。但是在自执行函数执行的时候,在它的私有作用域中,是要进行预解释的:

    1 ;(function (num) {
    2      //在私有的作用域中是要进行预解释的
    3 })(100);

    4.函数体中return后面的返回值不预解释,但是return后面的代码,虽然不执行,但是要预解释(有点无节操啊)

     1 function fn() {
     2     //私有作用域下的预解释:
     3     //var num;
     4     console.log(num);//undefined
     5     return function () {
     6 
     7     };
     8     var num = 12;
     9 }
    10 fn();

    5.关于重名变量和预解释

    1 function a(x) {}
    2 var a;
    3 alert(a); //function a(x) {}
    重名变量a又被声明了一次,浏览器在解释的时候发现已经有一个同名变量a了,就不再去重复声明了,并且在声明的时候也没有被赋值,则变量a还是保持原来的值不变,即弹出"function a(x) {}"

    如果预解释的时候发现重名了,不重新的声明,但是需要重新的定义。(即后面发现是重名的变量,如果该重名变量只是声明没有定义时,可以忽略,但是该重名变量即声明,执行时又定义赋值的话,该变量的值就等于此时的赋值,比如下面的代码)
    1 function b(x){return x*2; };
    2 var b=9;
    3 var b="abcd";
    4 alert(b);//"abcd"

    犀牛书上是这样说明的:

    使用var语句多次声明一个同名变量是合法的并且也没有什么害处。如果重复声明语句中含有初始值,那么就会被按照普通的赋值表达式来处理。

     

     

    
    

     

  • 相关阅读:
    纯jq编写增删改,弹出框
    li颜色特效
    省市联动Demo
    button轮番点击,只点击一次,鼠标hover
    正则--密码强度验证
    正则--验证邮箱与手机号
    正则表达式--元字符
    C#电脑自动关机代码指令
    1.ASP.NET MVC使用EPPlus,导出数据到Excel中
    6.在MVC中使用泛型仓储模式和依赖注入实现增删查改
  • 原文地址:https://www.cnblogs.com/cataway/p/4874261.html
Copyright © 2011-2022 走看看