ES6中的变量和作用域

这篇文章主要探讨和学习如何在ES6中处理变量和作用域。

通过let和const决定块作用域

letconst创建的变量只在块作用域中有效。它们只存于包含它们的块中。下面演示的代码,通过letif语句块中声明一个tmp变量。这个变量仅在if语句中有效。

function func() {
    if (true) {
        let tmp = 123;
        console.log(tmp); // => 123
    }
    console.log(tmp);     // => ReferenceError: tmp is not defined
}

相比之下,var声明的变量作用域的范围是函数范围内的:

function func() {
    console.log(tmp);      // => undefined
    if (true) {
        var tmp = 123;
        console.log(tmp);  // => 123
    }
    console.log(tmp);      // => 123
}
console.log(tmp);          // => ReferenceError: tmp is not defined

块作用域意味着你可在有函数内有变量的阴影。

function func() {
    let foo = 5;
    console.log(foo);       // => 5
    if (true) {
        let foo = 10;
        console.log(foo);   // => 10
    }
    console.log(foo);       // => 5
}

const创建不可变的变量

let创建的变量是可变的:

let foo = 'abc';
foo = 'def';
console.log(foo); // => def

const创建的是变量是一个常量,这个变量是不可变的:

const foo = 'abc';
foo = 'def';
console.log(foo);  // => TypeError: Assignment to constant variable.

请注意,如果一个常量指的是一个对象,那么const并不影响常量本身的值是否是可变的,因为它总是指向那个对象,但是对象本身仍然是可以被改变的。

const obj = {};
obj.prop = 123;
console.log(obj.prop); // => 123
console.log(obj);      // => {prop: 123}
obj = {}               // => TypeError: Assignment to constant variable.

如果你想让obj真正成为一个常量,你必须冻结它的值

const obj = Object.freeze({});
obj.prop = 123;

也就是说,如果const定义的常指向的是一个对象。这个时候,它实际上指向的是当前对象的地址。这个地址是在栈里面的,而这个真实的对象是在堆栈里面的。所以,我们使用const定义这个对象后,是可以改变对象的内容的。但是这个地址是不可以改变的。意思也就是不可以给这个对象重新赋值,比如const obj= {}, obj = {},即使是这样,obj好像什么也没有改变,但还是错误的。然而在普通模式下,并没有报错,而obj.name = 'abc'这是完全可以的。这跟JavaScript存储引用对象的值的方式有密切的关系。

const obj = Object.freeze({});
const newObj = {};

obj.name = 'w3cplus';
newObj.name = 'damo';

使用Babel把上面ES6的代码编译成ES5代码:

'use strict';

var obj = Ob
剩余80%内容付费后可查看
* 请输入阅读码(忘记阅读码?

如需转载,烦请注明出处:https://www.w3cplus.com/javascript/es6-scoping.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部