zoukankan      html  css  js  c++  java
  • js 变量、函数提升

    js 变量、函数提升

    先简单理解下作用域的概念,方便对变量与函数提升的概念的理解

    function foo() {
        var x = 1;
        if (x) {
            var x = 2;
        }
        console.log(x);
    }
    foo();// 2
    结果为2,可见js中并没有块级作用域的概念
    能够使用以下的方法创造自己的作用域。这样不会干扰到外部变量

    function foo() {
        var x = 1;
        if (x) {
            (function() {
                var x = 2;
            }());
        }
        console.log(x);
    }
    foo();// 1
    
    结果为1,可见js中的作用域是以函数为边界的

    1.变量提升:

    变量提升与js的预编译有关,以下通过样例辅助说明

    var a = 100;
    var b = 200;
    function foo(){
        console.log(a);// undefined
        a = 10;
        console.log(a);// 10
        var a = 1;
        console.log(a);// 1
        console.log(b);// 200
    }   
    foo();
    js预编译时会先在当前作用域中找到var声明的变量分配空间。赋值为undefined。假设找不到就会到下一级作用域中找

    上面的代码的等价代码例如以下:

    var a = 100;
    var b = 200;
    function foo(){
        var a;
        console.log(a);// undefined
        a = 10;
        console.log(a);// 10
        a = 1;
        console.log(a);// 1
        console.log(b);// 200
    }   
    foo();
    这样看是不是easy理解多了。第一行var声明了a,可是没有赋值,因此为undefined。以下打印10、1也就顺理成章了。

    至于变量b。它在当前作用域中找不到,因此须要到外层作用域中找。在window下找到了变量b,能够看到它的值为200


    2.函数提升

    首先要明白两点:

    <1> 仅仅有函数声明才会进行函数提升

    <2> 函数提升会将函数体一起提升上去,这点与变量提升有所不同

    以下来证明函数表达式不能进行函数提升:

    ~function() {
        alert(typeof next); // undefined
        ~function next() {
            alert(typeof next); // function
        }()
    }()
    函数前面加个~的目的是将函数声明变成函数表达式,实际上也能够加其他运算符。比方+,-,!等,总之这个函数声明被变成了函数表达式。

    从打印结果来看第一个alert出的是undefined,说明next根本没有发生函数提升。

    以下来接着验证:

    a();// 123
    
    var a = function(){
        console.log("321");
    }
    
    a();// 321
    
    function a(){
        console.log("123");
    }
    从结果能够看出,先打印出来的反而是放在后面的a()。上面代码的等价表演示样例如以下:

    var a = function a(){
        console.log("123");
    }
    
    a();
    
    a = function(){
        console.log("321");
    }
    
    a();


    那么假设当变量提升与函数提升同一时候发生的时候,哪个的优先级更高呢?我们来做个实验:

    function fn(){
    	console.log(a);
    	var a = 2;
    	function a(){}
    	console.log(a);
    }
    fn();// function a(), 2
    从打印顺序中能够看出。函数提升比变量提升优先级高。由于函数提升是将函数体总体提升,提升上去后立刻赋值。

    等价代码例如以下:

    function fn(){
    	var a = function(){}
    	console.log(a);
    	a = 2;
    	console.log(a);
    }
    fn();

    以下再来几个有趣的样例:

    B = 100;
    function B(){
        B = 2;
        console.log(B);
    }
    B(); // B is not a function
    //函数提升导致的
    
    ////////////////////
    B = 100;
    var B = function(){
        B = 2;
        console.log(B);
    }
    B(); // 2
    //函数表达式不存在函数提升
    function change() {
        alert(typeof fn); // function
        alert(typeof foo); // undefined
        function fn() {
            alert('fn');
        }
        var foo = function(){
        <span style="white-space:pre">	</span>alert('foo');
        }
        var fn;
    }
    change();
    
    //fn提升了,foo没有提升

    以下还有几个思考题:

    1.

    var a = 1;  
    function b() {
        console.log(a);
        a = 10;  
        function a() {}  
    }  
    b();// ?
    console.log(a);// ?
    2.

    a = 10;
    (function a(){
        a = 1;
        console.log(a);// ?
    })();
    3.

    function a(i) { 
        console.log(i);// ?
        var i = 1; 
        console.log(i);// ?
    }; 
    a(10); 


  • 相关阅读:
    基础网络技术--学习网络的的道路漫长啊
    华为nova8se和vivoS7e的区别哪个好
    Java.awt实现一个简单的围棋
    HashMap put原理详解(基于jdk1.8)
    Paper Pal:一个中英文论文及其代码大数据搜索平台
    【u116】最短路计数
    【u108】取数游戏
    【u106】3D模型
    【topcoder SRM 652 DIV2 250】ValueOfString
    【u103】绘制二叉树
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7159557.html
Copyright © 2011-2022 走看看