js变量声明提升

通常分析作用域链,要结合变量声明提升,看看下面几个题,把你绕晕没?
其中问题7最经典,如果你能明白,说明原型链你掌握的差不多了。

// --------------------1-----------------
       function foo() {
           var num = 123;
           console.log(num); //?
       }
       foo();
       console.log(num); //?

        //提升后的代码
       function foo() {
           var num;
           num = 123;
           console.log(num); //?123
       }
       foo();
       console.log(num); //?num is not defined

        //is not defined 没有定义
        //undefined  定义了没有赋值

        // --------------------2-----------------

        var scope = "global";

        foo();

        function foo() {

            console.log(scope); //?
            var scope = "local";
            console.log(scope); //?
        }

        //提升后的代码
       var scope;
       function foo(){
           var scope;
           console.log(scope); //?undefined
           scope = "local";
           console.log(scope); //?local
       }
       scope = "global";
       foo();

        // --------------------3-----------------
        //in 关键字 判断某个对象中是否有某个属性

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

       // --------------------4-----------------

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

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


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

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

       // --------------------6-----------------
       var foo = 1;
       function bar() {
           if(!foo) {
               var foo = 10;
           }
           alert(foo); //??10
       }
       bar();

       //提升后的代码
       var foo;
       function bar(){
           var foo;
           if(!foo) {
               foo = 10;
           }
           alert(foo); //??10
       }
       foo = 1;
       bar();

       // --------------------7-----------------
       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(); // ?  alert 2
       getName(); // ? 4
       Foo().getName(); // ? 1
       getName(); // ? 4  //1
       new Foo.getName(); // ? 2 //先执行Foo.getName(),再new。new 2,还是2
        (new Foo).getName(); //
       new Foo().getName(); // ? 3 //先创建Foo对象,在调用函数
       new new Foo().getName(); // ?  3 //先创建对象,调用函数,再new

       //等价于
        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); };

       Foo.getName(); // ?  alert 2
       getName(); // ? 4
       Foo().getName(); // ? 1
       getName(); // ? 4  //1
       new Foo.getName(); // ? 2 //先执行Foo.getName(),再new。new 2,还是2
       (new Foo).getName(); //3
       new Foo().getName(); // ? 3 //先创建Foo对象,在调用函数
       new new Foo().getName(); // ?  3 //先创建对象,调用函数,再new

知识点:局部变量声明提前后不会覆盖原来的全局变量

例1 :参数是引用参数

var foo={n:1};
(function (foo) {
    console.log(foo.n);
    foo.n=3;
    var foo={n:2};
    console.log(foo.n);
})(foo);
console.log(foo.n);

解析:变量提升以后:(局部变量声明提前后不会覆盖原来的全局变量)

var foo = {n:1};
(function(foo){            //形参foo同实参foo一样指向同一片内存空间,这个空间里的n的值为1
    var foo;               //局部变量声明提前后不会覆盖原来的全局变量,赋值才会覆盖
    console.log(foo.n);    //输出1
    foo.n = 3;             //形参与实参foo指向的内存空间里的n的值被改为3
    foo = {n:2};           //形参foo指向了新的内存空间,里面n的值为2.
    console.log(foo.n);    //输出新的内存空间的n的值
})(foo);
console.log(foo.n);        //实参foo的指向还是原来的内存空间,里面的n的值为3.

//所以答案为: 1 2 3

例2: 参数是传值参数

var foo=1;
(function (foo) {
    console.log(foo);
    foo=3;
    var foo=2;
    console.log(foo);
})(foo);
console.log(foo);


//答案为1 2 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值