您的位置:首页> 前端教程> JS教程
文章导航

变量声明带var与不带var的区别

2018-10-12 20:30| 作者: admin| 查看: 1759| 评论: 0|来自: 蚂蚁部落

JavaScript声明变量带var与不带var区别的问题在网络上基本已经谈烂了。

无论是在网上搜索或者在技术群里请教,基本都能得到满满的回复。

回复内容绝大多数如“不带var声明的变量的作用域是全局的,带var声明的变量的作用域是当前所在作用域”。

通过代码实例验证一下热心伙伴们的回复是否正确:

[JavaScript] 纯文本查看 复制代码
function func(){
  address="青岛市南区";
  var webName="蚂蚁部落";
}
func();
console.log(address);
console.log(webName);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/12/203115ii7b389z93899uv8.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

根据上面理论,address声明没有使用var,那么此变量的作用域是全局的,而webName声明使用var,作用范围是函数作用域,所以在函数外部可以正常打印出address值,打印webName则会报错,看起来一切都很正确。

现在可以很负责任的告诉大家,上面的结论是错误的,只有使用var声明的才是变量。

看一段代码实例:

[JavaScript] 纯文本查看 复制代码
console.log(webName);
console.log(address);
var webName;
address;

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/12/203146sjp7zzncvieje3oo.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

大家知道,变量声明有前置现象,如果address也是变量,那么它一定也会前置。

打印结果会与webName相同,然而事实是报错了,分析如下:

(1).首先明确一点,在ES规范明确规定只有用var、let或者const声明的才是变量或者常量。

(2).不使用var创建的address是全局对象的一个属性,属性并没有前置现象,所以会报错。

既然webName是变量,那为什么可以使用window.webName访问此变量,好像webName也是一个属性。其实并不是,变量在执行上下文中的变量对象(VO)中存储,是变量对象的一个属性,在全局执行上下文中,全局对象恰好是变量对象,于是全局作用域中的变量可以使用全局对象window访问。这也是为什么delete无法删除使用var声明的变量,可以删除不适用var声明的"变量"的原因(eval执行上下文除外)。

特别说明:除了上下文,其他上下文中无法直接访问变量对象,因为这是内部的一种实现机制。

很多时候,有些知识点看起来非常简单,其实在它的后面隐藏比较深层次的一些原理,知晓这些原理之后,很多令人迷惑的奇怪现象会迎刃而解,当然自身也能有一种豁然开朗的快感和极大的成就感。

相关阅读:

(1).let可以参阅JavaScript let 命令一章节。

(2).变量对象可以参阅JavaScript 变量对象一章节。

(3).delete可以参阅JavaScript delete用法一章节。

2

鲜花

握手

雷人

路过

鸡蛋

刚表态过的朋友 (2 人)

最新评论

返回顶部