变量提升

所谓 变量提升 即所有声明变量或声明函数都会被提升到当前函数的顶部。

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

大家可以猜测下上面打印到控制台的消息会是什么?

    结果分别是 : undefine,2 和 1

那么我们再看看下面这个代码打印出来会是什么呢?

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

    log()
    结果分别是 : 1 和 2

结合一下我们对变量提升的定义,你也许已经明白了。对于第一个Demo中,她最终执行的代码实际上是这样的

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

    log()

所以最终打印出来的结果分别是 undefine 和 __2__,这就是变量提升很简单,不是吗?但是你要保持警惕,因为他随时会让你吃大亏。

函数的声明方式

    var getName = function(){
        console.log('函数表达式');
    }

    function getName(){
        console.log('函数声明');
    }

    getName();

还是请大家想想会打印出什么?

    公布结果 : 函数表达式 

这就是两种不一样的声明方式带来的结果,对于 函数声明 JS会在优先解析,确保所有调用这个方法的地方不会报错,但是对于 函数表达式 只会在JS从上往下解析的时候才会,正式解析,我们可以看下面代码会打印出什么。

    console.log(getName); // undefine

    var getName = function(){
        console.log('函数表达式');
    }

    console.log(getName); // 会打印出getName的方法

作用域

JS是没有块级作用域的(ES5之前),但是有函数作用域,我们看下面这两个Demo,看看两者的区别

    function add(){
        a += 10;
        return a;
    }

    var a = 30;

    console.log(add(a)+a);
    function add(a){
        a += 10;
        return a;
    }

    var a = 30;

    console.log(add(a)+a);

这是一道很基础的问题,当我们把两个Demo 同时写出来的时候,我相信很多人是可以回答出正确答案的,下面公布答案。

    第一个Demo : 80
    第二个Demo : 70

为什么会得到这样的结果呢?我们看第一个Demo 函数里面的 a 实际上直接操作window下面的,也就是全局环境。但是第二个Demo操作的确实函数自己的形参,也就是自己的作用域,它的改变不会影响到全局环境的a

JS中声明类的方法有很多种,这里我就介绍最经典的一种而已

    function Animal(){
        this.name = "";
        var food = "";

        var eat = function(){
            console.log('eat');
        }

        this.run = function(){
            console.log('run');
        }
    }

    Animal.prototype.name = "小明";
    Animal.prototype.food = "穿山甲"

    var animal = new Animal();

    console.log(animal); // 会打印出什么属性?
    console.log(animal.name); // 结果会是什么?
    console.log(animal.food); // 那么这个呢?

首先这个涉及到了闭包的概念,关于这个问题我在这里就不详细说了,给大家一个知乎链接,里面讲的答案非常的简单明了,记得要全部看完,不要只关注高分项 JavaScript 里的闭包是什么?应用场景有哪些?,基本我要讲的都在这里面了。

    至于 animal.name 为什么会是 "" ,而 animal.food 是穿山甲,其实很简单,对象对于prototype会是低优先,先找本身存不存在name这个属性,找不到就到prototype去找。

第三方x
15 声望0 粉丝