javascript 显示全局变量与隐式全局变量的区别


Posted in Javascript onFebruary 09, 2017

在JavaScript中,全局变量有两种声明方式

  • 使用 var 显示声明的全局变量

  • 不使用 var 声明的隐式全局变量

两者的区别在于是否能通过 delete 操作符删除

先看一段代码

var a = 'a'; // 显式声明的全局变量
b = 'b'; // 隐式声明的全局变量
 
console.log(a); // a
console.log(b); // b
console.log(window.a); // a
console.log(window.b); // b

在 js 中全局变量其实是global对象(window)的属性,因此两种方式声明的全局变量都可以通过 window 拿到

尝试用 delete 删除

// 显式声明的全局变量不能被删除
delete a; // 返回 false 
 
// 隐式声明的全局变量可以被删除
delete b; // 返回 true 
 
// 删除情况
console.log(typeof a); // string
console.log(typeof b); // undefined

delete 操作符可以删除一个对象的属性,但如果属性是一个不可配置(non-configurable)属性,删除时则会返回 false(严格模式下会抛出异常)

这就表示使用 var 声明的变量是不可配置的,使用 getOwnPropertyDescriptor 来获取描述属性特性的对象来验证这一点

Object.getOwnPropertyDescriptor(window, a); // {value: "a", writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(window, b); // {value: "b", writable: true, enumerable: true, configurable: true}

两者的根本区别在于显式声明的变量不可配置,不能通过 delete 操作符删除

需要注意的是 configurable 值一旦为 false,描述属性特性的对象就不能被修改,因此不能通过修改属性描述符使得显示声明的全局变量能被 delete 删除,但反过来,可以使隐式声明的全局变量也不能被 delete 删除

b = 'b';
var descriptor = Object.getOwnPropertyDescriptor(window, b);
descriptor.configurable = false;
Object.defineProperty(window, b, descriptor);
delete b; // 返回 false

以下是其他网友的补充

JavaScript之全局变量和隐式全局变量

隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力。

1、通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
2、无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。

这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的:

// 定义三个全局变量
var global_var = 1;
global_novar = 2; // 反面教材
(function () {
  global_fromfunc = 3; // 反面教材
}());
 
// 试图删除
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
 
// 测试该删除
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

在浏览器中,全局对象可以通过window属性在代码的任何位置访问(除非你做了些比较出格的事情,像是声明了一个名为window的局部变量)。但是在其他环境下,这个方便的属性可能被叫做其他什么东西(甚至在程序中不可用)。如果你需要在没有硬编码的window标识符下访问全局对象,你可以在任何层级的函数作用域中做如下操作:

var global = (function () {
  return this;
}());

这种方法可以随时获得全局对象,因为其在函数中被当做函数调用了(不是通过new构造),this总 是指向全局对象。实际上这个病不适用于ECMAScript 5严格模式,所以,在严格模式下时,你必须采取不同的形式。例如,你正在开发一个JavaScript库,你可以将你的代码包裹在一个即时函数中,然后从 全局作用域中,传递一个引用指向this作为你即时函数的参数。

以上就是javascript 显示全局变量与隐式全局变量的区别,两者的根本区别在于显式声明的变量不可配置,不能通过 delete 操作符删除,希望大家多关注三水点靠木的其他文章。

Javascript 相关文章推荐
jquery对表单操作2
Apr 06 Javascript
多个checkbox被选中时如何判断是否有自己想要的
Sep 22 Javascript
js实现带圆角的多级下拉菜单效果
Aug 28 Javascript
[原创]jQuery常用的4种加载方式分析
Jul 25 Javascript
js制作网站首页图片轮播特效代码
Aug 30 Javascript
浅谈JS中的!=、== 、!==、===的用法和区别
Sep 24 Javascript
老生常谈JavaScript中的this关键字
Oct 01 Javascript
javascript汉字拼音互转的简单实例
Oct 09 Javascript
node.js中使用Export和Import的方法
Sep 18 Javascript
vue 的点击事件获取当前点击的元素方法
Sep 15 Javascript
详解Vue+ElementUI从零开始搭建自己的网站(一、环境搭建)
Apr 30 Javascript
javascript实现随机抽奖功能
Dec 30 Javascript
JS获取本周周一,周末及获取任意时间的周一周末功能示例
Feb 09 #Javascript
简单谈谈Javascript函数中的arguments
Feb 09 #Javascript
javascript 中设置window.location.href跳转无效问题解决办法
Feb 09 #Javascript
微信小程序之picker日期和时间选择器
Feb 09 #Javascript
BootStrap 弹出层代码
Feb 09 #Javascript
jQuery插件form-validation-engine正则表达式操作示例
Feb 09 #Javascript
javascript history对象详解
Feb 09 #Javascript
You might like
从php核心代码分析require和include的区别
2011/01/02 PHP
jquery不支持toggle()高(新)版本的问题解决
2016/09/24 PHP
PHP 芝麻信用接入的注意事项
2016/12/01 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
2019/08/23 PHP
PHP dirname(__FILE__)原理及用法解析
2020/10/28 PHP
用JQuery调用Session的实现代码
2010/10/29 Javascript
javascript中的注释使用与注意事项小结
2011/09/20 Javascript
在JS数组特定索引处指定位置插入元素的技巧
2014/08/24 Javascript
JavaScript中的全局对象介绍
2015/01/01 Javascript
jQuery实现新消息闪烁标题提示的方法
2015/03/11 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
简单理解vue中Props属性
2016/10/27 Javascript
浅谈jquery中next与siblings的区别
2016/10/27 Javascript
Javascript中字符串相关常用的使用方法总结
2017/03/13 Javascript
JS使用正则表达式找出最长连续子串长度
2017/10/26 Javascript
js中split()方法得到的数组长度问题
2018/07/19 Javascript
H5+C3+JS实现双人对战五子棋游戏(UI篇)
2020/05/28 Javascript
vue: WebStorm设置快速编译运行的方法
2018/10/18 Javascript
layer插件实现在弹出层中弹出一警告提示并关闭弹出层的方法
2019/09/24 Javascript
JS实现普通轮播图特效
2020/01/01 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
Python正则表达式匹配HTML页面编码
2015/04/08 Python
Django URL传递参数的方法总结
2016/08/28 Python
python探索之BaseHTTPServer-实现Web服务器介绍
2017/10/28 Python
python:接口间数据传递与调用方法
2018/12/17 Python
Python将字典转换为XML的方法
2020/08/01 Python
关于Python字符编码与二进制不得不说的一些事
2020/10/04 Python
python中实现词云图的示例
2020/12/19 Python
Python3.9.1中使用match方法详解
2021/02/08 Python
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
澳大利亚领先的皮肤诊所:Skin Matrix(抗衰老、痤疮专家、药妆护肤)
2018/05/20 全球购物
采购主管工作职责
2013/12/12 职场文书
村官个人总结范文
2015/03/03 职场文书
导游词之阆中古城
2019/12/23 职场文书
Java实现斗地主之洗牌发牌
2021/06/14 Java/Android
JAVA 线程池(池化技术)的实现原理
2022/04/28 Java/Android