健身俱乐部网站建设方案设计,做电影网站如何规避版权,上热门的短视频素材,做网站实现发送信息功能一、词法作用域
1.定义#xff1a; 为什么叫词法作用域#xff1f;因为大部分标准语言编译器的第一个工作阶段叫作词法化#xff0c;词法化的过程会对源代码中的字符进行检查#xff0c;如果是有状态的解析过程#xff0c;还会赋予单词语义。 简单来说#xff0…一、词法作用域
1.定义 为什么叫词法作用域因为大部分标准语言编译器的第一个工作阶段叫作词法化词法化的过程会对源代码中的字符进行检查如果是有状态的解析过程还会赋予单词语义。 简单来说词法作用域就是定义在词法阶段的作用域。是由这个变量和块写在哪里决定而不是由这个变量和块在哪里调用被决定。词法作用域是一生下来就决定了并且一般不会再改变。
function fooa {var b a * 2;function barc {console.log a b c ;}bar b * 3 ;
}
foo 2 ; // 2 4 12查找规则 当在嵌套的作用域查找变量时作用域查找会在找到第一个匹配的标识符时停止。在多层的嵌套作用域中可以定义同名的标识符这叫作“遮蔽效应”——内部的标识符“遮蔽”了外部的标识符。 全局变量会自动成为全局对象比如浏览器中的window对象的属性因此可以不直接通过全局对象的词法名称而是间接地通过对全局对象属性的引用来对其进行访问。例如window.a。这样我们就可以访问到那些被同名变量所遮蔽的全局变量。但非全局的变量如果被遮蔽了无论如何都无法被访问到。
二、改变影响词法作用域 词法作用域也并非完全不可改变如下两种方式就可以实现 1.eval javascript中的eval()函数可以接受一个字符串作为它的参数并能将该参数作为代码进行执行也就是说在你写代码的地方可以生成代码并运行 例如下代码
var strconsole.log(1);
eval(str); //1上面代码运行结果是控制台输出打印了1而str只是一个字符串参数。看着好像是可以动态的生成代码了我们再来看如下的代码:
function foo(str,a){eval(str);console.log(b,a);
}
var b1;
var svar b2;
foo(s,3) //2 3由此可见eval的优势很明显随便传入一个js字符串就可以执行且是在eval所处的当前行执行但其也有弊端eval导致词法作用域被改变(本来b的词法作用域是外部结果变成了内部就是由内而外寻找)编译器在执行的时候因为这个问题会执行的很慢(性能问题)。 2. with with通常被当做是应用一个对象的引用在引用对象属性时候不用重复引用对象本身 例如下面的例子
function foo(obj){with(obj){a2;}
}
var s1{a3;
};
var s2{b3
};
foo(s1);
console.log(s1.a)//2 输出s1的a属性值时输出了2也就是说with改变了当前的词法作用域
foo(s2);
console.log(s2.a)//undefined s2上的a属性其实没有a属性输出了undefined
console.log(a)//2 a变为全局作用域上去with对某个对象赋值属性
//如果该对象没有这个属性这个属性就会被放到全局作用域变成一个全局变量 with对某个对象赋值属性如果该对象没有这个属性这个属性就会被放到全局作用域变成一个全局变量 由此可见with可以在object为非常复杂的嵌套结构时使得代码显得非常简洁但其弊端也很明显那便是生成了全局变量造成数据污染编译器在执行的时候因为这个问题会执行的很慢(性能问题)。