首页 > 编程 > JavaScript > 正文

JavaScript 词法作用域

2019-11-06 06:06:54
字体:
来源:转载
供稿:网友

1. 词法作用域

(1)什么是作用域?

作用域就是可以作用的区域,即可以使用的区域。变量的作用域就是可以使用该变量的一个范围。最经典的作用域就是块级作用域,利用块来限定代码的执行范围。在 ES6 中引入了关键字 let,该关键字与 var 一样,用于声明变量。
{    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 可以限定作用域。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表