ES进阶:作用域:严格模式 / 名称空间 / IIFE / let / const

更多
2021年01月29日 13点34分 作者:叶飞 修改

为了解决JavaScript作用域的问题(复习),JavaScript开发人员煞费苦心:


名称空间(namespace)

其他成熟的工程化语言内置了名称空间(namespace)来解决这个问题,比如:

//虽然都是“源栈”,但他们显然是不一样的:
China.Chongqing.Luckystack
China.Bejin.Luckystack
US.NewYork.Luckstack

JavaScript只能模拟:

  1. 先定义一个唯一的全局变量(对象)
  2. 其他变量都写出是上述全局变量的成员(属性和方法)
  3. 还可以多层嵌套,最后形成名称空间一样的“样式”
var China = {};
China.Chongqing = {};
China.Chongqing.LuckyStack = {};
China.Chongqing.LuckyStack.wpz = function () {

JQuery等类库就是这样做的。(演示)


IIFE

全称:立即执行函数表达式(Immidiately Invoked Function Expression)

简单理解就是:声明一个匿名函数,然后立即就执行它。

所以语法:(function([parameter,...]){})([parameter,...]);

  1. ()就会让前面的函数立即执行
  2. 为什么需要把被执行函数包裹起来?
    • JavaScript解释器(ES标准)认为 function 关键字开头的语句是函数声明,后面就必须接函数名字(否则抛出一个语法错误信息);
    • 但只要function关键字前面有其他符号,解释器就会认为这是一个(可以匿名的)函数表达式
    • ()能够“欺骗”解释器,而且更有意义,^_^ (你用~/-啥的都行的)
演示:执行效果
    buttons[i].onclick = (function (i) {
        return function () {
            console.log('inner i = ', i);
            document.getElementsByTagName('h2')[0].style.color = buttons[i].style.color;
        }
    })(i);

这样,在每次事件绑定的时候,就把 i 值给“固定”了。此后事件触发的时候,就能够取到这时候被固定的 i 值。(实际上是利用IIFE形成了另外一个闭包)

此外,IIEF还可以用于:

  • 形成一个单独的作用域(模拟块级作用域 let )
  • 避免全局变量“污染”
演示:JQuery中IIEF的使用



strict模式(ES5)

把我们之前的代码稍作改动:

function scope() {
    /*var*/ sname = '李志博';   //注释掉var
@猜一猜@:会有什么结果?


如果在JavaScript的函数中声明变量,不使用var,该变量就具有全局作用域!——特性超级坑爹的一个“特性(bug)”,尤其是在代码review的时候,你根本不知道这是在:

  • 使用一个已声明的变量,还是
  • 要声明一个全局变量

所以从ES5开始,JavaScript就引入了所谓的“严格”模式,在代码顶部添加一行:

'use strict';  -- 如果浏览器不支持?

使用严格模式,就能强制JavaScript声明变量时必须使用:var;否则会报错。(以及其他约束)

演示:调试窗口报错


官方推荐总是使用严格模式。但是,如果

  • a.js 文件上声明了'use strict'
  • b.js 文件没有声明'use strict'且没有按照严格模式书写代码

  • 在html文件中先引用了a.js,然后再引用了 b.js

@想一想@:会出现什么情况?

所以,更多时候,我们不得不把'use strict'声明在函数顶部。




块级作用域(ES6)

JavaScript直到ES6,才引入了关键字:let。由let声明的变量,具有“块级(block)”作用域(同:C#等主流语法):

变量的作用域从声明开始,直到声明所在的花括号结尾为止。

不考虑兼容性,推荐总是使用 let!let的优势很多:

  • 没有什么变量提升,必须“先声明后使用”:
    {
        console.log(a);
        let/*var*/ a = 10;
    }
  • 声明的全局变量不会“挂”到window变量上

所有ES6新语法,默认use strict。


常量

const version = '1.0' 
关键字:const,语法特点:
  • 声明的同时必须赋值
  • 一旦赋值,就不能更改
  • 和let一样,块级作用域+严格模式

控制台演示:错误信息

注意:常量只是不能改变常量的“引用”,即:比如常量指向一个对象……

const zdh = { name : "周丁浩" }


@想一想:能不能修改 zdh.name='zdh'; ?


作业

设置一个常量password,保存你的密码

一起帮用户被分为5种,每种都有一个整数代号:

  • 0:访客
  • 1:注册用户
  • 2:文章发布者
  • 3:管理员
  • 4:超级管理员
写一段代码,用switch...case将代号转换成文字输出,但3和4都统称“管理员”即可



JavaScript 作用域 ES6
赞: 0 踩: 0

打赏
已收到打赏的 帮帮币

你的 打赏 非常重要!
为了保证文章的质量,每一篇文章的发布,都已经消耗了作者 1 枚 帮帮币
没有“帮帮币”,作者无法发布新的文章。

全系列阅读
评论 / 0

Web前端


HTML和CSS

HTML最常用的标签和属性,含HTML5的语义标签和新属性,但不包含需要JavaScript操作的HTML5 API,以及CSS基础(简述CSS 3动画相关),以及bootstrap.js以外的Bootstrap的内容。

Javascript入门

Javascript的基本语法:为能使用JQuery和Bootstrap.js的使用打下基础

ES进阶

借助于ES6,讲解JavaScript中一些更复杂的语法特性,如作用域、闭包、面向对象、原型链、this变化、module等

JQuery和Bootstrap

JQuery类库(含Ajax),以及Bootstrap的JavaScript组件部分

全部
关键字



帮助

反馈