博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
警惕javascript变量的全局污染问题
阅读量:6984 次
发布时间:2019-06-27

本文共 2743 字,大约阅读时间需要 9 分钟。

      作用域的概念总是和变量形影不离,它不是javascript语言独有的概念,只是其运用上与其他大型语言略有不同,JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。

      JavaScript对作用域的运用与其他语言略有不同,然而总体概念是一致的。作用域限定了javascript文档中的各个资源的可用范围,决定了你定义变量的位置。使用一个匿名函数来容纳所需的变量就是个很好的方法。所有在函数中定义的变量都只应该在该函数的作用域内生效。(变量的作用域会自动向下延伸,这是闭包的概念)

再声明全局作用域的变量,无论何时都能被所有函数所使用,这是个非常诱人的特性,但是对全局作用域的过度使用会造成全局作用域污染,这倒是我们用光所有的合适的变量名,也会导致长久占用内存空间,从而很难创建出一个能够长久维护的应用来。所以,对全局作用域的使用一定要少而谨慎。

比如,以下的全局污染示例:

1 //全局作用域污染示例 2 var party = "starlen"; 3 //我创建了一个全局作用域变量  4 function pizzaParty(totalSlices,peopleCount) { 5     "use strict"; 6  7     var fairness = totalSlices * peopleCount; 8     return fairness; 9 }10 11 (function () {12     "use strict";13 14     var body = document.getElementsByTagName("body")[0];15 16     body.innerHTML = "'

' ''partyStarty(26,18) ''+partyStarter+'

'";17 })();

 

     全局变量与任何编程语言中的其他东西一样,也有其用途。然而对他的使用尤需谨慎,而且在用之前必须仔细的思量其内容及名称。使用全局变量来设定程序的全局配置数据是个比较好的办法,全局配置包括:基地址(base URL)、目录信息、程序名称,或是一些需要反复使用而重复定义又会造成资源浪费的东西,应该利用每一件东西的长处,而不应该滥用。

现在,我将这个变量移动到了匿名函数之中,以清理该文档的全局作用域。合适的位置看起来也更加顺眼,并且在该函数执行完毕时会立即销毁变量,不会占用内存的宝贵资源。

1 //局部变量作用域 2  3 function Party(totalSlices,peopleCount) { 4     "use strict"; 5  6     var fairness = totalSlices * peopleCount; 7     return fairness; 8 } 9 10 (function () {11     "use strict";12     13     var partyStarter = "starlen";14 //现在,这个变量的作用域只归此闭包函数所有 15     var body = document.getElementsByTagName("body")[0];16 17     body.innerHTML = "'

' ''partyStarty(24,16) ''+partyStarter+'

'";18 })();

 

作用域问题,在javascript中,作用域与其他的面向对象编程语言不太一样,它的作用域是由函数划分的,不是由块划分(while,for,if中间),还有一个特性是所有属于全局作用域的变量都是window对象的属性。

1 //作用域 2 var fruit = "apple"; //全局变量,并属于全局作用域 3  4 if(true){ 5  6     var fruit = "new apple"; //改变全局变量的值,它现在仍处于全局作用域 7 } 8 alert( fruit == "new apple"); //fruit的最终值是new apple 9 10 function apple(){11     var fruit = "old apple"; //使用一个函数来更改它的值12 }13 apple();14 15 alert( fruit == "new apple"); //最后发现,apple函数没有起作用16 17 alert(window.fruit == "new apple"); //全局变量fruit和window对象的fruit属性一致

 

虽然javascript中的作用域规则不如块级作用域那么严格(没有深入研究JS的程序员因此会批评它),但它是非常强大的,而且功能完备,在于闭包概念一起使用时,javascript就能表现出这个脚本语言的强大本色。

 

1 //隐式全局作用域变量声明 2  3 function apple(){ 4     fruit = "apple"; //fruit变量处于apple函数作用域 5 } 6 apple(); 7  8 alert(window.fruit == "apple"); //但是使用window对象会发现,fruit已经处于全局作用域 9 10 //闭包11 var obj = document.getElementById("main");12 13 var items = ["click","keypress"]; //给变量绑定一个数组14 15 for(var i = 0;i < items.length;i++ ){  //循环遍历数组每一个元素16     //闭包函数激发作用域17     (function(){18         item = items[i];  //在此引用全局变量,记住当前的值19 20         obj["on"+item] = function(){  //item引用本for循环上下文所属作用域中的父变量21             alert("这是一个交互动作"+ item);22         }23     })();24 }

闭包概念相对复杂,它意味着内层的函数可以引用存在于包围他的函数的变量,深入研究并理解它,控制变量的作用域,就能避免作用域的污染问题。

转载于:https://www.cnblogs.com/xuanya/p/5922359.html

你可能感兴趣的文章
一个女装小程序的瀑布流实现
查看>>
Docker实现Mariadb分库分表、读写分离
查看>>
Node.js核心内容
查看>>
github克隆本地项目
查看>>
j抽奖
查看>>
GMQ力争为全球区块链数字资产技术应用贡献一份力量
查看>>
VUE+Vant 实现图片上传
查看>>
ajax实现点击加载更多
查看>>
为什么JavaScript没有类而使用原型?——JavaScript语言特性来历
查看>>
TarsGo新版本发布,支持protobuf,zipkin和自定义插件
查看>>
Flutter 如何创建并发布 Plugin (VS Code + GitHub 发布)
查看>>
TableStore实战:GEO索引打造亿量级店铺搜索系统
查看>>
js的防抖和节流
查看>>
redis学与思系列(2)
查看>>
学习springBoot(11)shiro安全框架
查看>>
c++那些事儿11 0 STL List
查看>>
问题记录——跨域
查看>>
PHP7.3即将到来,快来了解一下新特性吧
查看>>
1月9日云栖精选夜读:场景化封装,一站式使用,普惠AI集成 ——阿里云发布智能媒体管理产品...
查看>>
Java Servlet Filter 详解
查看>>