(JavaScript)ES6语法-let + const变量的声明方式

                    (JavaScript)ES6语法-let + const变量的声明方式

本以为自己什么都会其实自己什么都不会:

这一次我们一起看看简单的问题,对比一下ES6语法与ES5语法的变量的声明方式导致的不同。

来先看一段代码:

function run() {
            for(var i = 0; i < 2;i++) {
                console.log("i:" + i);// 0,1
            }
            console.log("for中的i:" + i);// 打印2(此处为什么打印的是2?就是因为当i在执行完最后一次验证条件失败的时候,i值已经被赋值 + 用var声明的变量所在的代码块中是不存在块级作用域的概念的,说白了就是没有一个盒子来盛放的,所以就可以访问到i,下面那个就是出了函数的作用域之后你是无法访问i的因为js中(ES6除外)仅仅支持函数作用域(相当于块级作用域))
        }
        run();
        console.log("run外面的i:" + i);// Uncaught ReferenceError: i is not defined

 我们都知道如果我们使用var来声明变量的话,鉴于上面的情况在run方法里边在for循环外部也是可以使用i,并且输出是2,

- 我们先来说说为什么在run方法里边在for循环外部我们还可以访问到i,在Java中是不可以的?

-1).在JavaScript中是没有块级作用域的概念的,JavaScript中仅仅只有函数作用域的概念。

-2).for循环在run函数这个作用域中,出了这个作用域,run方法中声明的变量方法什么的就不可以使用了,所以最后打印的那个i就会直接报错。

-3).又因为for循环语句在run函数的作用域中,所以在run方法中声明的变量在run方法里边在for循环外部都可以被访问到。又因为我们的循环循环到2的时候就不满足条件整个for循环就终止了,但是我们还遗漏了一个小细节,因为我们的i此时已经被附上值了所以我们在run方法里边在for循环外部访问i的时候就是2。


来我们再来看一段代码:

function execute() {
            for(let i = 0;i < 2;i++) {
                console.log("i:" + i);
            }
            console.log("execute作用域内的i:" + i);// Uncaught ReferenceError: i is not defined
        }
        execute();
        console.log("execute作用域外的i:" + i);// Uncaught ReferenceError: i is not defined

没错这段代码就是用ES6的语法写的,我们都知道,当我们使用let变量的声明方式声明变量的时候就会自动的与当前的作用域绑定,即生成块级作用域。所以我们在execute方法内部与for循环外部是不可以访问到i的。所以在execute方法内部与for循环外部报错了。因为我们在for循环外部从来就没有定义过i所以怎么可以访问到呢?


暂时性死区:

来我们先看一段代码:

(ES5写法)

        var worker = "Tom";
        function work() {
            console.log(worker);// 打印undefined
            var worker = "Alice";
        }
        work();

此时相当于在全局作用域中声明一个全局变量worker = "Tom",在work方法中声明一个worker = "Alice"的局部变量c此时在work函数的作用域中我们在此处打印worker,那么这个worker到底是谁呢?到底是全局变量worker还是局部变量worker,答案是局部变量worker(就是在work函数中的的声明的worker)那为什么是undefined,因为在浏览器解析JavaScript代码的时候先进性变量的提升所以在work函数中我们定义的worker也被提升了,相当于var worker = undefined;后面才依次执行console.log(worker);语句和var worker = "Alice";所以打印的结果就是undefined。

(ES6写法)

        var worker = "Tom";
        function work() {
            console.log(worker);// 打印Uncaught ReferenceError: worker is not defined
            let worker = "Alice";
        }
        work();

因为在ES6中,凡是通过let声明的变量都会和当前代码块绑定作用域,并且ES6中也没有变量提升的概念,所以上来直接就是:console.log(worker); -> let worker = "Alice";所以自然会报错,因为在输出之前我们从来都没有定义过worker。这个就叫做暂时性死区。


const定义变量的方式:

-1).对于基本类型来说:使用const声明的变量是不能被直接修改值的。

-2).对于引用类型来说:使用const声明的变量是不能被直接修改'值'(此处值的概念就是指引用类型的地址)的。所以我们不能这样:

const obj= {
    name: 'LJ'
};
obj = {};// 编译报错

但是我们可以在const声明对象的身上添加属性,只要我们不改变其引用地址就好。

        const walk = "走路";
        // walk = "跑步"; => 编译不通过
        const eat = {
            name: "Alice",
            age: 21
        };
        eat.action = "唱歌";
        console.log(eat);// 打印{name: "Alice", age: 21, action: "唱歌"} => 说明const如果修饰的是对象的话,其保证的仅仅是其指向的内存地址不可变,但我们是可以向对象中添加属性的,因为我们并没有改变const修饰的那个变量的指向的地址。

总结:

    -1).相比较ES5来说ES6的语法更加的严谨。

    -2).ES6语法不支持变量提升。

    -3).ES6语法存在暂时性死区。

    -4).const定义对象是不允许被直接改变的,但如果是一个引用类型的话我们可以在不改变引用地址的情况下,增减其属性。

以上就是在反省自身的时候学到的知识点。希望大家指正!
 

猜你喜欢

转载自blog.csdn.net/qq_39872652/article/details/81140751