JavaScript定义变量和变量优先级问题探讨


Posted in Javascript onOctober 11, 2014

看下面的代码:

if (!("aa" in window)) {  

    alert('oh my god');

    var aa = 1;  

}  

alert("aa" in window);

alert(aa);

回答以下问题:

会报错吗?会弹出几次?
第2个alert是true还是false?
第3个alert弹出什么?
为什么?
思考下,然后测试下,如果你回答正确,那么后面的文章就不用看了。

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

在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 相关文章推荐
静态页面的值传递(三部曲)
Sep 25 Javascript
javascript对select标签的控制(option选项/select)
Jan 31 Javascript
浅谈关于JavaScript的语言特性分析
Apr 11 Javascript
js中的eventType事件及其浏览器支持性介绍
Nov 29 Javascript
浅谈JavaScript异常处理语句
Jun 26 Javascript
js精美的幻灯片画集特效代码分享
Aug 29 Javascript
JS实现选项卡实例详解
Nov 17 Javascript
关于cookie的初识和运用(js和jq)
Apr 07 Javascript
Bootstrap实现带动画过渡的弹出框
Aug 09 Javascript
js利用clipboardData实现截屏粘贴功能
Oct 12 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
Apr 07 Javascript
openlayers实现图标拖动获取坐标
Sep 25 Javascript
JavaScript中获取鼠标位置相关属性总结
Oct 11 #Javascript
JavaScript中最简洁的编码html字符串的方法
Oct 11 #Javascript
原生Javascript封装的一个AJAX函数分享
Oct 11 #Javascript
探讨js字符串数组拼接的性能问题
Oct 11 #Javascript
分享20款美化网站的 jQuery Lightbox 灯箱插件
Oct 10 #Javascript
Jquery $.getJSON 在IE下的缓存问题解决方法
Oct 10 #Javascript
js点击button按钮跳转到另一个新页面
Oct 10 #Javascript
You might like
浅谈PHP接收POST数据方式
2015/06/05 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
在laravel中使用Symfony的Crawler组件分析HTML
2017/06/19 PHP
jQuery-onload让第一次页面加载时图片是淡入方式显示
2012/05/23 Javascript
JavaScript自动设置IFrame高度的小例子
2013/06/08 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
简单分析javascript面向对象与原型
2015/05/21 Javascript
JavaScript中用于生成随机数的Math.random()方法
2015/06/15 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
JavaScript实现复制内容到粘贴板代码
2016/03/31 Javascript
javascript简单判断输入内容是否合法的方法
2016/05/11 Javascript
JS之相等操作符详解
2016/09/13 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
引入JavaScript时alert弹出框显示中文乱码问题
2017/09/16 Javascript
vue语法之拼接字符串的示例代码
2017/10/25 Javascript
vue中引用阿里字体图标的方法
2018/02/10 Javascript
解决vue-router进行build无法正常显示路由页面的问题
2018/03/06 Javascript
通过nodejs 服务器读取HTML文件渲染到页面的方法
2018/05/17 NodeJs
JavaScript面向对象继承原理与实现方法分析
2018/08/09 Javascript
React 使用recharts实现散点地图的示例代码
2018/12/07 Javascript
vue.js实现数据库的JSON数据输出渲染到html页面功能示例
2019/08/03 Javascript
深入了解JS之作用域和闭包
2020/06/16 Javascript
详解Java中String JSONObject JSONArray List转换
2020/11/13 Javascript
Python跳出循环语句continue与break的区别
2014/08/25 Python
深入理解Python变量与常量
2016/06/02 Python
python的内存管理和垃圾回收机制详解
2019/05/18 Python
python 获取sqlite3数据库的表名和表字段名的实例
2019/07/17 Python
Python实现一个简单的毕业生信息管理系统的示例代码
2020/06/08 Python
CSS3教程(2):网页边框半径和网页圆角
2009/04/02 HTML / CSS
CSS3 伪类选择器 nth-child()说明
2010/07/10 HTML / CSS
汽车专业毕业生自荐信
2013/11/03 职场文书
教师网络培训感言
2014/03/09 职场文书
乡领导班子四风问题对照检查材料
2014/09/25 职场文书
mysql创建存储过程及函数详解
2021/12/04 MySQL
剑指Offer之Java算法习题精讲二叉树的构造和遍历
2022/03/21 Java/Android
MySql如何将查询的出来的字段进行转换
2022/06/14 MySQL