美文网首页
前端初学-变量提升

前端初学-变量提升

作者: 始悔不悟 | 来源:发表于2017-05-20 11:45 被阅读0次

    本人所有文章均为学习过程中的总结,不同程度地参考了互联网上其他的文章,如果不正恳请指出,共同进步

    变量提升

    JS代码的执行分为两个阶段
    预解析阶段

    • 变量名和函数声明提升至当前作用域的最上方(只提升声明,不提升赋值)

    执行阶段

    • 按照从上至下的顺序执行语句

    注意:

    • 变量与函数同名时,只提升函数,不提升变量
    • 函数同名时,都提升,后面的函数覆盖前面的函数
    • 函数表达式只会提升变量名,赋值语句在执行阶段按照顺序执行
    • 变量提升是分块的<script></script>
    • 条件是函数声明能否被提升取决于浏览器,不推荐使用if(true){function(){}};

    实例:

    //js中没有块级作用域的说法,大括号并不会创建一个作用域
    
    for(var i=0;i<5;i++){
        console.log(i);//0 1 2 3 4
    }
    console.log(i);//5 for循环外部依旧可以访问到i
    

    只有函数能够创建作用域

    变量提升是分作用域的

    函数与变量同名只提升函数 但是变量赋值还是要执行的

    代码:

    var num=10;
    function num(){
        console.log(123);
    }
    num();
    

    预编译

    function num(){
        console.log(123);
    }
    num=10;
    num();//is not a function
    

    函数与函数同名全部都会提升,但会以函数声明顺序进行覆盖,后面覆盖前面的

    代码:

    function f1(){
        console.log('first');
    }
    function f1(){
        console.log('last');
    }
    

    预编译:

    function f1(){
        console.log('last')
    }
    

    函数表达式与变量提升方式相同,变量赋值不会被提升,但变量声明会提升

    代码:

    f1()//undefined
    var f1=function(){
        console.log('f1');
    }
    

    预编译:

    var f1;//提升
    f1();//调用 undefined
    f1=function(){//赋值
        console.log('f1');
    }
    

    代码:

    function foo() {
        var num = 123;
        console.log(num); //123
    }
    foo();
    console.log(num); //is not defined
    

    预编译:

    function foo() {
        var num;
        num = 123;
        console.log(num); //?123
    }
    foo();
    console.log(num); //is not defined
    
    //is not defined 没有定义
    //undefined  定义了没有赋值
    

    代码:

    var scope = "global";
    foo();
    function foo() {
        console.log(scope); //undefined
        var scope = "local";
        console.log(scope); //local
    }
    

    预编译:

    var scope;
    function foo(){
        var scope;
        console.log(scope); 
        scope = "local";
        console.log(scope); 
    }
    scope = "global";
    foo();
    
    //in 关键字 判断某个对象中是否有某个属性
    

    代码:

    function f1(){
       if("a" in window){
           var a = 10;
       }
       alert(a);//undefined
    }
    f1();
    

    预编译:

    function f1(){
       var a;
       if("a" in window){
           a = 10;
       }
       alert(a);//undefined
    }
    f1();
    

    代码:

    if("a" in window){
        var a = 10;
    }
    alert(a); //10
    

    预解析:

    var a;
    if("a" in window){
        a = 10;
    }
    alert(a);
    

    代码:

    if(!"a" in window){
        var a = 10;
    }
    alert(a); // undefined
    

    预解析:

    var a;
    if(!"a" in window){
      a=10;
    }
    alert(a);
    

    代码:

    var foo = 1;
    function bar() {
        if(!foo) {//此处提升了foo但是是undefined 判断语句会转为!undefined -->true
            var foo = 10;
        }
        alert(foo); //10
    }
    bar();
    

    预解析:

    var foo;
    function bar(){
        var foo;//undefined
        if(!foo) {//!undefined --> ture
            foo = 10;//10
        }
        alert(foo); //10
    }
    foo = 1;
    bar();
    

    代码:

    function Foo() {
        getName = function(){ alert(1); };
        return this;
    }
    
    Foo.getName = function() { alert(2); };
    
    Foo.prototype.getName = function(){ alert(3); };
    
    var getName = function() { alert(4); };
    
    function getName(){ alert(5); }
    
    Foo.getName(); //2
    
    getName(); //4
    
    Foo().getName(); //1
      
    getName(); //1
    
    new Foo.getName(); //2
    
    new Foo().getName(); //3
    
    new new Foo().getName(); //3
    

    预解析:

    function Foo() {
        getName = function(){ alert(1); };
        return this;
    }
    
    var getName;
    
    function getName(){ alert(5); }
    
    Foo.getName = function() { alert(2); };
    
    Foo.prototype.getName = function(){ alert(3); };
    
    getName = function() { alert(4); };
    
    
    
    getName(); //4
    
    Foo().getName(); //1
      
    getName(); //1
    
    Foo.getName(); //2
    
    new Foo.getName();//2 先执行Foo.getName()  new关键字无效
    
    (new Foo).getName();//3 先执行new Foo创建对象
    
    new Foo().getName(); //3 先执行new Foo()创建对象
    
    new new Foo().getName(); //3 相当于 new Foo().getName() new关键字无效

    相关文章

      网友评论

          本文标题:前端初学-变量提升

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