本文是前端学习笔记的第七篇,对应web前端开发JavaScript精英课js的第22课时,本篇主要写JS如何避免对全局变量的污染,以及对象枚举(其实也就是遍历对象的属性)
目录
命名空间
在JavaScript中,全局变量的污染往往是一个棘手的问题,如果什么变量都定义在全局中,造成的后果便是代码结构混乱,且容易造成命名冲突,毕竟如果在同一个业务代码中,往往名词都是那么几个,一旦冲突造成的后果是难以预料的,且排查十分困难,因此便产生了一种为解决这类问题而产生的处理方法,即命名空间
命名空间起到的作用主要便是解决命名冲突,到现在为止有多种方案,这里我只写举一个我认为最好的方案
通过闭包与立即执行函数的方式
先来看下面一段代码
<script>
var name = 'abc';
var init = (function () {
var name = 'bcd';
return function () {
console.log(name); // bcd
};
}());
init();
</script>
通过立即执行函数,把涉及到的变量、函数都放在了规定的区域内,可读型大大提高了,更加适用于模块化开发了。同时避免了命名冲突的问题,因为此时即使有命名相同的属性,用的也是作用域链中最近的执行期上下文对象中的属性,不会用到全局中的属性,最后通过闭包的方式则把里面的过程最终要得到的结果返回出来
对象枚举
所谓对象枚举,其实就是把对象的所有属性遍历一遍,这种遍历方式还是挺新颖的,在Java里类似的只有for each循环获取数组或集合的元素,而在JS中我们可以通过for in循环拿到对象的所有属性
<script>
var obj = {
name : 'JayChou',
age : 39,
sing : function () {
console.log('最美的不是下雨天,是曾与你躲过雨的屋檐');
}
};
for (key in obj) {
// console.log(key);
console.log(obj[key]);
}
</script>
for in循环每次都会抽取出对象的一个属性,可以试着把注释放开,就知道了,然后通过console.log输出对象的属性就可以达到遍历对象的效果
注意,在console.log()中的不是obj.key,而是obj[key],为什么呢?因为obj.key会被系统隐式的转为obj["key"],而对象上显然是没有key这个属性的,因此我们直接使用系统隐式转换后的方式进行输出,obj[key]中key会自动执行toString方法转为字符串,达到我们想要的效果,最终输出的就是obj[name]、obj[age]、obj[sing] 等等,平时我们也可以直接写obj[xxx]这样的形式来表示属性,这样还省略了系统隐式转换的过程,效率更高
但是,有时可能对象的原型对象身上也有属性,而通过for in循环的方式是会遍历所有属性的,有时我们并不需要遍历原型对象上的属性,这时我们可以通过hasOwnProperty()方法解决
<script>
Student.prototype.money = 99999;
function Student() {
this.name = 'JayChou';
this.age = 39;
this.sing = function () {
console.log('最美的不是下雨天,是曾与你躲过雨的屋檐');
};
}
var stu = new Student();
for (key in stu) {
if (stu.hasOwnProperty(key)) {
console.log(stu[key]);
}
}
</script>
若key是自己的属性,就会返回true,否则false,利用这一点,便可以只输出到自己的属性了