简单点,先去掉判断,这样写:
<script> var name = '张三'; function test(){ var name1 = name; console.log(name1); } test(); </script>
上面看懂了,再加上判断即可。
这个函数是可以看懂的,但是不懂的是:
1、
@奋斗的少年-欧耶: 。。看来你还是不明白var 在作用域开始的时候会被提前到最前面执行么。。
比如说
var a = 1;
function(){
console.log(a);
var a = 0;
console.log(a);
}
会打印undefined 0
是因为函数运行的时候发生了变化 var 定义变量被提前了
运行后的函数是这样的
var a = 1;
function(){
var a = undefined;
console.log(a); //这里根据就近原则会现在本域中查找a 变量 如果没有就去上一级查找a变量直至全局变量window里面也没有就返回报错。 不存在; 因为运行到这里的时候a 还没赋值 所以打印undefined
a = 0;
console.log(a); // 这里的时候 因为赋值了0 所以 打印结果0
}
全程因为 运行域内部有变量a 导致外面的域的a变量根本用不上
@blurs: 哦哦 这个我理解了 变量提升所导致的 但是我又碰到一个问题 就是在最外层 设置一个变量 name 不给他赋值 同时 typeof name 所显示的 是 string 不是 undefined 这个是怎么回事啊?
@blurs: 那个 我知道了 原来是window 对象下的 name 属性 是字符串 非常感谢大佬的帮助 谢谢了~~
。。。因为迷路了 人家线程走的好好的突然发现前面有一个name 咦 这家伙比较近 就是他了 然后就把他拿了过来一看 咦? 还没赋值的undefined?那就没办法了 给他赋值一个李四吧
好啦 玩笑开在这里
简单的来说 这里有一个基础知识
每一个函数作用域 被执行(也就是被调用的时候【后面加了一个()】) 都会产生一个活动域(作用域) 这个域被激活的一瞬间 他会经历3个阶段
阶段一 : 创建 arguments this 变量(活动变量)
阶段二 : 扫描全部定义变量然后创建空变量 (比如你这个name 就算你写在了下面 但是 只要让这个域检测到var name了,不好意思 都会在第一时间帮你定义好,至于你的=“李四” 它才不会管呢,他只管创建不管赋值。这个时候就有了 一个区域变量name=undefined ,)
阶段三 :开始走逻辑流程了(一般的小白都会觉得函数是从这里开始的。。。)
阶段三的时候 他先进入你的if判断 name 还真特么是undefined 那敢情好, 咱们给他赋值李四 好的 然后打印李四。
@blurs: 嗯嗯 但是如果是这样的话就会访问到外部的 name 值以及外部name的数据类型,这种和之前的 if 判断语句里面的 typeof name 为什么会不一样啊? 为什么如下的函数可以访问,之前的那种写法就不能访问呢?
@奋斗的少年-欧耶: 局部变量和全局变量重名会覆盖全局变量...应该没有错吧?
@hehe_54321: 您的意思是说 if 里面的 typeof name 将 name 覆盖了吗? 但是我不加 if 判断直接console.log 是可以获取到 name 的数据类型 以及 name 值的 这怎么解释啊?
@奋斗的少年-欧耶: 我再讲一遍层主的意思吧,函数被执行时,首先扫描函数体中全部对变量的var定义,然后定义好这个变量(但是不进行赋值,也就是创建了一个值为undefined的变量,也就是说你在这个函数之中如果在赋值之前访问到这个名字的变量,不会访问到同名全局变量的值,只会访问到这个undefined值的变量),然后执行函数体,如果有var ...=...实际操作就相当于直接赋值(...=...)。
typeof name不会把name覆盖,是函数体中定义的name把全局的name覆盖了。js不是c++
@hehe_54321: 并不会哟 覆盖只会出现在同一个域类 相同变量名的时候才会出现。
@blurs: 这个 我终于知道是怎么回事了 谢谢大佬们的帮助了 非常感谢~~