以下两段代码各自的输出结果是什么,为什么。
//1. var a="window"; function Test(){ console.log(a); var a="local"; console.log(a); } Test(); //2. var pengpeng="This is his code!"; pengpeng.love="study"; console.log(pengpeng); console.log(pengpeng.love);
先说第一个,最后的输出结果首先输出undefined,然后输出local。有些神奇有木有,仔细梳理就会发现端倪了,代码首先定义了一个全局对象a,因此按理说执行Test第一行代码的时候,a此时应该会使用全局对象a的,往下的时候,局部a会覆盖全局a,然后接着输出local,但实际结果第一个却是undefined。
关于这点,不得不提JS的加载逻辑了,很多人会觉得JS变量的定义和声明,是在JS运行期间进行的,其实不是,JS有个预加载逻辑,会事先构造运行环境以及作用域,那么答案就呼之欲出了,上面第一段代码,JS预加载的时候,局部变量a覆盖了全局变量a,那么既然是局部已经优先覆盖了全局a,为什么第一个a还是undefined呢? 这就不得不提作用域了,预加载的时候,全局a的作用域已经变成了局部a,所以一个输出的时候,根据作用域找a的时候,其实是找不到这个a的,此时的a,仅仅只是被定义过,但是它的作用链上,是指向下面的a的,下面的a在运行到那里的时候才会被赋值,而此时a相当于未赋值,所以输出undefined,如果不是全局定义了一下a,第一次输出a会报未定义。
总结一下第一个案例的原理,JS预加载的时候,局部变量改变了全局变量的作用域,在局部变量之前访问全局变量时,此时值是undefined。
再说第二个,这个不细心一下会被“障眼法”遮住,为啥给赋值了,第二个居然仍然输出undefined?? ——答案是,变量pengpeng只是一个值类型对象,而非引用类型对象,值类型是没有属性的, 只有引用类型才有。so,penglong.love肯定会输出undefined了。
如果要用属性,得这么用:
//3. var dingman=new Object(); dingman.love="study"; console.log(dingman.love);
以上知识点出处:https://www.cnblogs.com/sharpxiajun/p/4133462.html