javascript定义变量和优先级的问题

本文链接: javascript定义变量和优先级的问题.转载请保留.

 

看下面的代码:

if (!("aa" in window)) {
alert('oh my god');
var aa = 1;
}
alert("aa" in window);
alert(aa);

回答以下问题:

  1. 会报错吗?会弹出几次?
  2. 第2个alert是true还是false?
  3. 第3个alert弹出什么?
  4. 为什么?

思考下,然后测试下,如果你回答正确,那么后面的文章就不用看了。

-----------------------------

在JS里定义变量太简单了,直接一个var ,甚至不用var都可以:

var a = 1;

这里a就是变量名,1就是变量值。唉,这个太基础了。看下面的代码:

var a;
alert(a);

以firebug测试,会弹出undefined,这个是大家很熟悉的一个字符串了,貌似表示变量未定义。但我觉得,我已经var了啊,这就是定义了嘛,只是没有附值而已。

我们来个真正的没有定义的:

alert(a);

没错,就是直接alert一个根本没有出现过的变量,这会如何?

firebug直接报错了:a is not defined.意思是a没有定义。这个结合前面的代码来看,让人困惑。这个没有定义和前面的未定义有什么不同呢?

其实前面的代码等价于这样的:

var a = undefined;
alert(a);

也就是说,当声明变量而不赋值时,JS会给变量传一个undefined值,注意,这是个“值”,说明a已经有值了,这个值就叫“未定义”。

而后面的直接alert,变量从没有出现过,也就是说这才是真正的未定义。

简单的说:JS中不存在没有值的变量,变量声明的时候就赋值了。

然后我们看下面的代码:

alert(a);
var a = 1;

这个代码会报错吗?因为在alert的时候变量a还没来得及出现呀。

但是这样居然没有报错,而是弹出了undefined值。表明变量a已经存在了,只是值却不是我们想要的,而是undefined。这又是个什么问题呢?

因为var 变量声明和函数声明一样,会提前,其实上面的代码是这样的:

var a;
alert(a);
a = 1;

这么一来就懂了。

所以,这个问题的关键在于:var 声明会提前到作用域顶端,但附值却不会———好纠结的设定,不知道为什么要这么搞。个人觉得这是JS的一个缺陷。

现在有一种代码习惯,主张把变量声明一律放在作用域前方,大概就是考虑到这个——反正就算你不写在前方,JS也会提前到前方。

现在放出文首问题的答案:

只会弹出两个alert,而if里面的alert不会执行,因为var声明的提前性,导致真正的代码是这个样子:

var aa;
if (!("aa" in window)) {
alert('oh my god');
    aa = 1;
}
alert("aa" in window);
alert(aa);

虽然aa为空,但用’aa’ in window判断时会为真,因为a确实存在了,而值是undefined。所以if代码不会执行。后面两个alert我就不说了。

个人感觉这是一个很无厘头的问题,我们应该了解他的原因,但鄙视他这种陷阱。

上面这个问题也是我写这篇文章的缘由,这段代码是我从一篇网文里看到的,但他里面没有答案,我百撕不得骑姐,跑到stackoverflow上去问了才搞清楚。答案就是这篇文章。

但这是很基础的问题啊其实!!!

哈哈,原谅我,后面还有一个问题:

var b = {}
alert(b.aa);
alert(b.aa.bb);

这也是一种声明变量的方式,那么,这段代码会报错吗?为什么?

转载于:https://www.cnblogs.com/bluers/p/3522531.html

### 局部变量全局变量的作用域 局部变量是在函数或代码块内部声明的变量,其作用域仅限于该函数或代码块内部。这意味着局部变量只能在定义它的代码块内被访问修改,外部无法直接访问[^4]。例如,在以下代码中,`x` 是一个局部变量: ```python def example_function(): x = 10 print(x) example_function() # print(x) # 这行代码会引发 NameError,因为 x 是局部变量 ``` 全局变量则是在函数外部声明的变量,其作用域覆盖整个程序,可以在多个函数中被访问修改。例如: ```python y = 20 def another_function(): print(y) another_function() print(y) ``` ### 局部变量全局变量优先级关系 当局部变量全局变量同名时,在函数内部优先使用局部变量。这种规则被称为“局部变量优先”原则。如果在函数内部需要访问全局变量,则必须显式地使用作用域解析操作符(如 `::` 在 C++ 中)或者通过其他语言特定的方式进行区分。 例如,在 C 语言中: ```c #include <stdio.h> int count = 0; // 全局变量 void increment() { int count = 10; // 局部变量 printf("%d\n", count); // 输出局部变量的值 } int main() { increment(); return 0; } ``` 在这个例子中,尽管全局变量 `count` 存在,但在 `increment()` 函数内部,局部变量 `count` 被优先使用[^1]。 在 Python 中,可以通过 `global` 关键字来显式地引用全局变量: ```python count = 0 # 全局变量 def increment(): global count count += 1 increment() print(count) # 输出 1 ``` 如果没有使用 `global` 关键字,Python 会在函数内部创建一个新的局部变量而不是修改全局变量JavaScript 中的情况略有不同,由于变量提升机制的存在,即使在函数内部声明了同名变量,也会导致全局变量被隐藏: ```javascript var val = 10; function test() { console.log(val); // undefined var val = 100; console.log(val); // 100 } test(); ``` 在这个 JavaScript 示例中,虽然第一个 `console.log(val)` 看起来应该输出全局变量 `val` 的值 `10`,但由于变量提升,局部变量 `val` 已经存在但尚未赋值,因此输出为 `undefined` [^5]。 ### 生命周期与存储方式 局部变量的生命周期始于声明位置,结束于代码块执行完毕。它们通常存储在栈内存中,并且每次调用对应的函数或进入代码块时会创建新的副本,互不干扰。全局变量具有全局可见性,在整个程序中都可以访问修改,其生命周期从定义位置开始,直到程序结束[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值