{ console.log(num);//num is not defined let num = 123;//从定义开始至所在的花括号结束的范围内生效 console.log(num);}console.log(num);(2)词法作用域
在 js 中(不考虑 ES6 特性)是没有块级作用域的,只有词法作用域词法作用域:与代码的运行无关,只与代码的定义书写内容有关。黄金法则:只有函数可以限定作用域,变量声明会提升,访问先在当前找,没有父级作用域来查。可以利用代码的书写绘制出代码的作用域关系。练习:if(!('a' in window)){ var a = 123;}console.log(a);var a = 123;function b(a){ console.log(a); function a(){ console.log('a'); }}b(a);in 运算符语法:'字符串' in 对象 -> boolean含义:该对象中是否存在属性名字为字符串的形式,如果存在返回 true例如:var p = {name: xxx};'name' in p; //true'age' in p; //false绘制作用域关系图:① 在全局范围内声明的所有变量,都是在该范围内可以被使用的,而且没有前后顺序之分② 如果有函数,那么函数内部是独立于外界的一个完整的作用域范围function foo(){ //函数内部也要预解析,声明提升 console.log(num); var num = 10; console.log(num);}foo(); //先打印undefined,后打印10③ 在函数内部如果没有找到对应的变量,会到函数外面查找;如果函数内部和函数外部同时有变量,优先使用函数内部的。先后打印:456、123、123结果:报错,num is not defined,num向上一层找到了变量声明并使用,而此声明是在函数体内的,不在全局范围,故num不是全局变量,只是函数foo1内部的变量 结果:打印456,num向上所有层找都没有找到变量声明,故num成为了全局变量2. 作用域链
在分析代码的时候,多个作用域中含有哪些数据,不容易记住根据变量访问的搜索规则(当前有就用,没有就上一级搜索)绘制作用域链规则:① 把全局作用域看作0级作用域,绘制一条直线② 凡是看到函数,就延伸出一条链,记为 n+1 级链③ 进入函数内,重复上述操作注意:在绘制链的时候,不要给任何变量赋值,将图绘制完成以后,再一句一句分析代码,将数据添加上去例:3. 变量的访问规则
在访问一个变量的时候,首先在当前作用域中查找,如果找到则使用,并停止查找,如果没找到则在上一级作用域中查找(上一级链),如此往复,一定会找到全局作用域(0级链),如果还没有数据,则报错(is not defined),如果是设置数据,则会在全局作用域中增加一个属性(此处严格模式会报错)。4. eval 函数
将字符串作为代码执行语法:eval( '语句' )一般网站不需要考虑安全性的时候,可以这么使用,但是现在已经不建议使用了。推荐使用 Function 实现类似的功能。注意:在严格模式下,eval 可以限定作用域。
新闻热点
疑难解答