ES6 学习笔记_02(作用域)

什么是作用域?

作用域就是一个变数的生存範围,一旦超出了这么範围就无法存取到这个变数。

在ES6之前,Javascript只拥有函数作用域和全域作用域,函式作用域也就是说每一个函数都有自己的作用域,在作用域外面无法存取到函数内定义的变数,全域作用域代表global任何地方都能存取到,而ES6引入的let与const,多了块状作用域的概念,

作用域式分层的,内层作用域可以取得外层作用域的变数,反之则不行。

全域作用域(global)

全域作用域式全局性的,也就是说在整个Javascript程式中到处都可以使用,所有window物件都属于全域作用域中,全局作用域有个缺点,如果我们定义了很多变数、函示但却没有使用那么它们就全部都在全局作用域中,会污染全局命名空间, 容易引起命名冲突。

var global = 123;test = () => {    console.log(global); //123};test();

值得注意的是,尚未定义且直接赋值的变数都会自动宣告为全局作用域这点在写成式的时候会常常造成错误。

test = () => {    var func = 123;    global = 456;    console.log(func); //123};test();console.log(func); //ReferenceError: func is not definedconsole.log(global); //456 虽然global在函示内被赋值,但却没有定义型态,所以被自动归类为全局作用域 

函式作用域

函式作用域只有在函数内可以被访问到,所以在函数内所宣告的变数不会洩漏到全域中造成全域汙染,而函式作用域可以访问父层作用域的变数,但自身作用域的变数层级较高。

test = () => {    var a = 10;};console.log(a); //ReferenceError: a is not defined
var global = 123;test = () => {    var global = 456;    console.log(global); //456}test();

块级作用域

在ES6中引入了let与const两个变量宣告,新增了块级作用域的概念。

为什么需要块级作用域?

由于ES5只有全局作用域与函数作用域,所以常常会造成一些想像不到的错误。

var tmp = new Date();test = () => {    console.log(tmp);    if(false){        var tmp = "hello world";    }};test(); //undefined

在上面的程式中,虽然function可以读取到全域的tmp变数,但是由于变量提升(hoisting)的关係导致输出为undefined。

var tmp = new Date();test = () => {    var tmp; //hoisting    console.log(tmp); //undefined    if(false){        tmp = "hello world";    }};test(); //undefined

而ES6新增了块级作用域搭配上let,const不会hoisting的情况,可以避免常数的不确定性。

test = () => {    let n = 5;    if(true){        let n = 10;    }    //由于let n=5与console属于同级块状作用域,而let n=10属于下一层级的块状作用域,所以不会互相影响    console.log(n); //5 };

还有值得注意的地方,ES6的块级作用域必须有大括号,若没有JavaScript则认为不存在块级作用域。

//Errorif (true) let x = 1;if (true) {  let x = 1;}

参考资料 :
ECMAScript 6 入门
深入理解JavaScript作用域和作用域链
所有的函式都是闭包:谈 JS 中的作用域与 Closure


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章