ring 根据 ole 如果 cti def scrip 是我
代码 1:
- console.log(typeofa2)//undefined
- vara2='littlebear';
- console.log(a2)//littlebear
- console.log(typeofa2)//string
- vara2=1;
- console.log(a2)//1
代码 2:
- console.log(typeofa2)//undefined
- vara2='littlebear';
- console.log(a2)//littlebear
- console.log(typeofa2)//string
- vara2=1;
- console.log(a2)//1
代码 3:
- console.log(typeofa)//undefinedconsole.log(a)//报错,遇到<script>标签对时,会先对这一块进行预解析,下面没预解析,所以找不到声明过的a,于是报错了
- console.log(typeofa)//undefined
- vara=1;
- console.log(a)//1
第一个 script 标签里的 a,undefined,直接输出啊,立马报错。因为在第一个 script 标签的时候没有发现 a 声明过,没声明直接使用就会报错。 第二个 script 标签里面的输出是我们预料之中的
得出一个结论:js 的预编译,是从有顺序的,根据 script 标签的顺序从上到下执行的。
例如:
- function fn(a,b){
- console.log(a)//容易上当
- vara=10;
- console.log(a)//10
- }
- fn('容易上当');
- 参数a会覆盖预编译变量a的默认值,如果有函数,函数会覆盖参数a的值,这个就是先后顺序而已
- function fn() {
- function a() {
- console.log(1)
- }
- return a;
- function a() {
- console.log(2)
- }
- }
- fn()(); //2
由于预编译,后面的 a 覆盖了前面的 a,所以 return a 的值 其实就是预编译之后 a 的值,预编译之后 a 的值就是第二个 a。
- vara=10;
- function fn(){
- //预编译a 赋值undefined,内部作用域存在a这个变量,所以这里 !a 就是 !undefined,就是true,进入函数a=20;
- //但是后面的a怎么就是20呢,js没有块级作用域!! 不要小看js各种细节,够折腾的
- if(!a) {
- vara=20
- }
- console.log(a)// 这里是20 ,
- }
- fn()
- //a in window ==>true 、 !true ===》false
- if (! (a in window)) {
- var a = 1;
- }
- console.log(a) // undefined
js 作用域
ebe ring 根据 ole 如果 cti def scrip 是我
来源: http://www.bubuko.com/infodetail-2063578.html