为了解决JavaScript作用域的问题(复习),JavaScript开发人员煞费苦心:
其他成熟的工程化语言内置了名称空间(namespace)来解决这个问题,比如:
//虽然都是“源栈”,但他们显然是不一样的: China.Chongqing.Luckystack China.Bejin.Luckystack US.NewYork.Luckstack
JavaScript只能模拟:
var China = {}; China.Chongqing = {}; China.Chongqing.LuckyStack = {}; China.Chongqing.LuckyStack.wpz = function () {
JQuery等类库就是这样做的。(演示)
全称:立即执行函数表达式(Immidiately Invoked Function Expression)
简单理解就是:声明一个匿名函数,然后立即就执行它。
所以语法:(function([parameter,...]){})([parameter,...]);
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还可以用于:
把我们之前的代码稍作改动:
function scope() { /*var*/ sname = '李志博'; //注释掉var@猜一猜@:会有什么结果?
如果在JavaScript的函数中声明变量,不使用var,该变量就具有全局作用域!——特性超级坑爹的一个“特性(bug)”,尤其是在代码review的时候,你根本不知道这是在:
所以从ES5开始,JavaScript就引入了所谓的“严格”模式,在代码顶部添加一行:
'use strict'; -- 如果浏览器不支持?
使用严格模式,就能强制JavaScript声明变量时必须使用:var;否则会报错。(以及其他约束)
演示:调试窗口报错
官方推荐总是使用严格模式。但是,如果
b.js 文件没有声明'use strict'且没有按照严格模式书写代码
@想一想@:会出现什么情况?
所以,更多时候,我们不得不把'use strict'声明在函数顶部。
JavaScript直到ES6,才引入了关键字:let。由let声明的变量,具有“块级(block)”作用域(同:C#等主流语法):
变量的作用域从声明开始,直到声明所在的花括号结尾为止。
不考虑兼容性,推荐总是使用 let!let的优势很多:
{ console.log(a); let/*var*/ a = 10; }
注意:命名规则,但是
ES6中还引入了let和const
使用未声明的变量会报错:
alert(xyz); //xyz从未声明
控制台中可以查看(注意:JavaScript的错误不会报到页面!)
此外,理论上变量应该“先声明,后使用”。
但是,JavaScript中有一个特性(其实是bug):
即:JavaScript在执行时会把所有的变量声明(注意:仅仅是声明)提升到代码的顶部。
所有,如下代码不会报错,但是
alert(greet); let greet = "源栈欢迎你!";其实等同于:
let greet; alert(greet); greet = "源栈欢迎你!";
注意:提升的只是greet的声明,greet的赋值没有提升。
而JavaScript会在变量声明的时候默认给它赋一个undefined的值。所以使用未赋值的变量不会报错,只是其值为undefined!
@想一想@:JavaScript运行时究竟是:
这个特性是超级坑(error prone)的,会给我们代码的调试带来非常多的麻烦!
所以,和其他语言(如C#)不同,JavaScript不提倡“就近声明”,而是提倡“(用一个let)在代码顶部声明全部变量”:
let greet = "源栈欢迎你!", name, age; //可以一次声明多个变量这样可以:
换行:
知识的另外一个作用:方便调试:养成习惯,先注释最后删除
因为Javascript语言本身:
ESLint插件应运而生,广受欢迎。在VS2019中已经内置了ESLint检测,在书写JavaScript时会给我们错误提示(红波浪线)和警告(绿波浪线)。
检查是否开启:
演示:警告和错误
所有ES6新语法,默认use strict。
const version = '1.0'关键字:const,语法特点:
控制台演示:错误信息
注意:常量只是不能改变常量的“引用”,即:比如常量指向一个对象……
const zdh = { name : "周丁浩" }
@想一想:能不能修改 zdh.name='zdh'; ?
设置一个常量password,保存你的密码
一起帮用户被分为5种,每种都有一个整数代号:
多快好省!前端后端,线上线下,名师精讲
更多了解 加: