文档章节

用与不用 Var 声明变量的区别

CodeMyLife
 CodeMyLife
发布于 2017/08/06 23:12
字数 727
阅读 4
收藏 0

凡是经常写 JS 的 Coder 都知道这么一个道理,无论是在浏览器环境下还是在其他 JS 宿主环境下声明的变量都会自动变为全局对象的一个同名属性

在浏览器环境下是 window 对象,在 node 环境下是 global 对象

不同于其他语言,JS 在非严格模式下,不使用 var 关键字声明变量并进行赋值操作,并不会抛出异常,而是自动地为我们创建了一个“全局变量”。

num = 1
window.num === num // true

然而事实上,不使用 var 关键字并非创建了一个全局变量,而是对全局对象(也可以称作顶级对象)进行一次属性赋值操作。

首先,JS 引擎会试图在当前作用域内去寻找这个变量, 如果找不到这个变量则沿着作用域链一直向上寻找,最后到达作用域的顶端。如果依旧无法找到,便会在作用域顶端的对象,也就是全局对象上创建一个同名属性,并进行相应的赋值操作。

window.num = 1

那么,在全局环境下(之后的讨论范围都是在全局环境下)使用 var 关键字和不使用 var 关键字到底有什么区别呢?至少直观上并看不出有什么差别。但是在他们内部却有很大的区别。

虽然使用 var 关键字声明的变量会自动成为全局对象的属性,但它具有“不可配置”的特性。

简单的来说,它又是一个存在于全局环境的变量,又是全局对象的一个属性。但是作为一个变量,我们无法使用 delete 操作符来删除它。 delete 操作符只能用于普通的对象上的属性。因此它具有“不可配置”的数据特性,我们可以通过 Object.getOwnPropertyDescriptor 方法来验证:

var num = 10
Object.getOwnPropertyDescriptor(window, "num")
//  {
//   configurable: false,
//   enumerable: true,
//   writable: true,
//   value: 10
// }

这个方法返回一个对象,这个对象包含了该属性的属性描述符。我们可以看到,没有使用var 关键字声明的变量的 configurable 属性为 false,这意味着我们无法对该属性使用 delete 操作符

delete window.num // false

但是对于普通的全局对象上的属性,或者是不使用 var 关键字导致添加的属性,我们可以用 delete 操作符删除该属性,因为它只是一个普通的属性

a = 10
delete window.a // true

不过就算我们了解了这两种操作的细微区别,我们还是要避免不使用 var 关键字来创建变量的情况,这样代码的可读性会更强,也能预防将来发生一些意料之外的错误。

© 著作权归作者所有

上一篇: NPM的使用
下一篇: JS对象的拷贝
CodeMyLife
粉丝 2
博文 20
码字总数 32371
作品 0
珠海
程序员
私信 提问
在Javascript中声明时用var和不用var的区别

Javascript声明变量的时候,虽然用var关键字声明和不用关键字声明,很多时候运行并没有问题,但是这两种方式还是有区别的。可以正常运行的代码并不代表是合适的代码。 上面的声明是在当前域中...

汉斯-冯-拉特
2018/08/05
0
0
ES6 --- 新的变量声明方式 let 与 const 解析

let let 声明的变量只在 let 命令所在的代码块内有效。 小例1: let 声明的变量只在 let 命令所在的代码块内有效, 在代码块之外无效 const const 声明一个常量(所谓常量就是物理指针不可以更...

王小端coder
03/31
0
0
var和let/const的区别

和是 ES6 新增的命令,用于声明变量,这两个命令跟 ES5 的有许多不同,并且和也有一些细微的不同,在认真阅读了阮一峰老师的文档后,发现还是有一些不知道的细节,重新整理了一下,分享给各位...

OBKoro1
01/04
0
0
let & const —— ES6基础总结(二)

前言 在JS中,早已深入人心,因此本文将不再赘述,仅在必要时拉出来溜溜。 声明方式 变量提升 暂时性死区 重复声明 可修改值 块级作用域 全局变量属于顶层对象 var 是 否 是 是 否 是 let 否...

萌小萌和她的前端笔记
05/04
0
0
js的变量提升

JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting) ...

徐耀湘91
2016/12/16
5
0

没有更多内容

加载失败,请刷新页面

加载更多

Android面试常客之Handler全解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/fnhfire_7030/article/details/79518819 前言:又到了一年...

shzwork
29分钟前
4
0
position sticky 定位

本文转载于:专业的前端网站➫position sticky 定位 1、兼容性 https://caniuse.com/#search=sticky chrome、ios和firefox兼容性良好。 2、使用场景 sticky:粘性。粘性布局。 在屏幕范围内时...

前端老手
36分钟前
4
0
CentOS 7 yum 安装 PHP7.3 教程

参考:https://www.mf8.biz/centos-rhel-install-php7-3/ 1、首先安装 EPEL 源: yum install epel-release 安装 REMI 源: yum install http://rpms.remirepo.net/enterprise/remi-release......

dragon_tech
51分钟前
4
0
Linux物理网卡聚合及桥接

Linux内部实现的bridge可以把一台机器上的多张网卡桥接起来,从而把自己作为一台交换机。同时,LInux bridge还支持虚拟端口,即桥接的不一定都是物理网卡接口,还可以是虚拟接口。目前主要表...

xiangyunyan
51分钟前
4
0
一起来学Java8(一)——函数式编程

在这篇文章中,我们将了解到在Java8下如何进行函数式编程。 函数式编程 所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。 首先来看下JavaScript如何进行函...

猿敲月下码
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部