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

在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 操作符删除,希望大家多关注我们的其他文章。

(0)

相关推荐

  • java根据ip地址获取详细地域信息的方法

    互联网有很多接口可以实现通过ip查询到具体的位置,如下: 通过淘宝IP地址库获取IP位置 请求接口(GET):http://ip.taobao.com/service/getIpInfo.php?ip=[ip地址字串] 响应信息:(json格式的)国家 .省(自治区或直辖市).市(县).运营商 返回数据格式: {"code":0,"data":{"ip":"210.75.225.254","country"

  • Java中创建对象的5种方式总结

    作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有5种创建对象的方式,下面给出它们的例子还有它们的字节码 使用new关键字 } → 调用了构造函数 使用Class类的newInstance方法 } → 调用了构造函数 使用Constructor类的newInstance方法 } → 调用了构造函数 使用clone方法 } → 没有调用构造函数 使用反序列化 } → 没有调用构造函数

  • java使用FastJson解析Json数据

    fastjson 是一个性能极好的用 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发. 主要特点: 快速FAST (比其它任何基于Java的解析器和生成器更快,包括jackson) 强大(支持普通JDK类包括任意Java Bean Class.Collection.Map.Date或enum) 零依赖(没有依赖其它任何类库除了JDK) 一 .生成Json: JavaBean.List<JavaBean>.List<String>.List<Map&l

  • java 同步、异步、阻塞和非阻塞分析

    java 同步.异步.阻塞和非阻塞分析 概要: 正常情况下,我们的程序以同步非阻塞的方式在运行.但是我们的程序总会出现一些耗时操作,比如复杂的计算(找出1到10亿之间的素数)和程序本身无法控制的操作(IO操作.网络请求).包含这些耗时操作的方法我们可以把它称为阻塞方法,包含这些耗时操作的任务我们可以把它称为阻塞任务.阻塞与非阻塞是以是否耗时来定义的. 如果程序中存在大量阻塞操作,就会影响程序性能.但是阻塞的存在是客观事实,我们的程序是无法改变它的,一个网络请求需要3秒才能响应,我们不可能让它1毫

  • 基于JavaScript实现本地图片预览

    本文实例为大家分享了js本地图片预览的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <!-- <!DOCTYPE html>一定要放在第一行,除非上面都是空行 在HTML规范中,单独存在的标签是不需要使用/来自我关闭的,比如<br>,<input>,<hr>等等这样的标签都是符合语法的. 在XHTML规范中,单独存在的标签要按照XML的语法规则进行自我关闭,上面三个标签就应写成<br />,<inpu

  • Java中Integer两种转int方法比较

    方法一: Integer.parseInt(); 返回的是一个 int 的值. 方法二: new Integer.valueof(); 返回的是 Integer 的对象. new Integer.valueof().intValue(); 返回的也是一个 int 的值. 笔试应用例题: 设有下面两个赋值语句: a = Integer.parseInt("123"); b = Integer.valueOf("123").intValue(); 下述说法正确的是( 

  • java中fastjson生成和解析json数据(序列化和反序列化数据)

    本文讲解2点: 1. fastjson生成和解析json数据 (举例:4种常用类型:JavaBean,List<JavaBean>,List<String>,List<Map<String,Object>) 2.通过一个android程序测试fastjson的用法. fastjson简介: Fastjson是一个Java语言编写的高性能功能完善的JSON库.fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jack

  • javascript history对象详解

    前面的话 history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起.由于安全方面的考虑,开发人员无法得到用户浏览器的URL,但借由用户访问过的页面列表,可以在不知道实际URL的情况下实现后退和前进.本文将详细介绍BOM中的history对象 length history.length属性保存着历史记录的URL数量.初始时,该值为1.如果当前窗口先后访问了三个网址,history.length属性等于3 由于IE10+浏览器在初始时返回2,存在兼容性问题,所以该值并不常用 histor

  • 基于JavaScript实现复选框的全选和取消全选

    本文实例为大家分享了js复选框的全选和取消全选的具体代码,供大家参考,具体内容如下 效果图: 测试代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> li{list-style: none;} </style> </head>

  • Java的Jackson库中复杂对象集合的几种简单转换

    话不多说,请看代码: package com; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxm

  • java 获取一组数据中的最大值和最小值

    话不多说,请看代码: public static void main(String[] args) { int array[]={2,4,3,9,1,6,8,5,23}; int max=array[0],min=array[0]; for(int i=0;i<array.length;i++){ if(array[i]>max){ max=array[i]; } } for(int i=0;i<array.length;i++){ if(array[i]<min){ min=ar

随机推荐