本文链接: 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);

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

javascript定义变量和优先级的问题的更多相关文章

  1. Javascript定义变量

    在JavaScript中通过var来定义变量,不管是数字还是字符串,都可以通过这种方式来定义:我们既可以在声明变量的同时给变量赋值,也可以先声明变量,再给变量赋值. <script> va ...

  2. Ansible-playbook之定义变量

    1.引用变量 # 变量引用方式 "{{ }}" 2.定义变量 (vars) - hosts: web # 定义变量 vars: - play_var: This_is_play_v ...

  3. (转载)JavaScript中定义变量

    (转载)http://blog.163.com/xuxiaoqianhz@126/blog/static/165190577201061594421870/ JavaScript中定义变量有两种方式: ...

  4. JavaScript基础——定义变量

    在JavaScript中使用变量来临时存储和访问来自JavaScript文件的数据.变量既可以指向简单的数据类型,如数字或者字符串:也可以指向更复杂的数据类型,比如对象. 在JavaScript中定义 ...

  5. JavaScript中var和this定义变量的区别

    JavaScript中var和this定义变量的区别 在js中声明变量时可以使用var和this,但使用this的有很大一部分参考书是没有的,经过查阅相关资料总结如下: 用var和this声明变量,存 ...

  6. JavaScript 中定义变量时有无var声明的区别

    关于JavaScript中定义变量时有无var声明的区别 var a=5; //正确 a=5; //正确 在javascript中,以上两种方法都是定义变量的正确方法.微软的Script56.CHM中 ...

  7. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  8. [转]深入理解JavaScript的变量作用域

    1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...

  9. JavaScript笔记:变量及其作用域

    一.变量的定义及声明 在javascript中变量仅仅是用来保存值的一个占位符而已,定义变量时要使用关键字var后跟一个变量名,如下所示: var message; //定义一个变量message,像 ...

随机推荐

  1. 如果在安装32位oracle 客户端组件时的情况下以64位模式运行,将出现问题

    今天要写个程序,环境是win7+ vs2008+ oracle.首先得保证能连接到数据库.确认代码是没有问题的,但是拿过来直接.报错: “尝试加载 Oracle 客户端库时引发 BadImageFor ...

  2. kafka-简单事例

    开始创建项目,这里所用的工程结构是maven. 在pox.xml中添加kafka的依赖包,如下所示: <dependency> <groupId>org.apache.kafk ...

  3. Jack Straws(判断线段是否相交 + 并查集)

    /** http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1840    题意:    判断线段 ...

  4. 《Mathematical Olympiad——数论》——整除

    数论这个东西吧,虽说也是高中IMOer玩的数学游戏,颇具美学性的证明比较多.就目前所知,它在算法里是一些加密技术的基础,不多言,开始具体题目的分析. 问题一:已知数列{an},且a0 = 2 , a1 ...

  5. Servlet的一些细节(1)

    1.  Servlet程序必须映射到一个URL地址 由于客户端是通过URL访问web服务器资源,所以Servlet程序必须映射到一个URL地址.这个工作在web.xml文件中使用<servlet ...

  6. codeforces 546B

    Description Colonel has n badges. He wants to give one badge to every of his n soldiers. Each badge ...

  7. javaweb项目的优化 - 几番思念

    简单地来看一个浏览器用户访问的流程: 浏览器->服务器->返回结果显示  这么简单地看,可能想得到的优化手段很少,常见的可能就是优化sql,加快数据库处理:加个缓存,加快返回:使用静态文件 ...

  8. 小学生玩ACM----深搜

    Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  9. 火球-UML大战需求分析(体验版3.0.2).pdf

    火球-UML大战需求分析(体验版3.0.2).pdf http://files.cnblogs.com/files/happlyonline/%E7%81%AB%E7%90%83-UML%E5%A4% ...

  10. [置顶] Oracle 11g R2 RAC:使用 srvctl 工具管理 service 资源

    1.使用 srvctl 工具创建 service 资源 srvctl add service -d db_unique_name -s service_name {-r "preferred ...