JavaScript 命名空间 对象枚举

1.命名空间

作用:

管理变量,防止污染全局,适用于模块化开发。

解释:

一个网站或者是一个项目,他是需要很多很多人一起来完成的,有许多个人写 HTML,许多人写 css,许多人写 js,最后把他们拼接在一起,而且在你入职后,是要经过专门的培训的,其中就包括什么样的方法用什么样的名字,它是规定好了的,所以你后期在写的时候就会非常规范,那么,就存在一种问题,大家都用这个名字,虽然你自己写的 js 是你自己的文件包,但是最终都是要通过 script 标签把他们引入到同一个 HTML 文件里的,那么就会存在一种命名冲突:都用这个变量名或者函数名,重 了的话会覆盖的,咋办?鉴于此,我们研究了两种方法:

方法一:

命名空间(老旧方法,已经被抛弃了),例如:

var	org = {
	department1:{
		xiaowang:{
			name:'abc',
			age:18
		},
		xiaohong:{
			name:'def'.
			age:17
		}
	},
	department2:{
		zhangsan:{
			name:'ghk',
			age:18
		},
		lisi:{
			name:'wyz',
			age:21
		}
	}
}
调用的时候则:
var xiaowang = org.department1.xiaowangl;
xiaowang.name;

解析:这个命名空间也是一个对象,对象里也可以套对象,比如说对象里有个部门 1,部门 2,部门 1 里 xiaowang 定义了一个自己的空间,空间里有一些变量啥的,然后在外部 var 一个 xiaowang 等于他自己的空间,再用变量的时候直接 xiaowang.name 即可。 这样就解决了一个命名冲突的问题,因为 a.name 和 b.name 是不一样的两个人,看起来也更加规整化了,但是现在程序越来越复杂了,这种方法就被抛弃了。

方法二:

闭包(现在用的方法,也是闭包的第四个作用)

附:闭包的作用四:模块化开发,防止污染全局变量。比如说:

var init = (function (){
	var name = 'abc',
	function callName(){
		console.log(name);
	}
	return function(){
		callName();
	}
}())

解析:最后 init 等于 return 后边的函数体,那么就会形成闭包,闭包的作用就是变量私有化,我就可以把我要定义的一系列变量放到这个闭包里,防止污染全局变量, 然后里边比如说定义了一系列复杂的方法,最后返回出去的函数里留一个接口,就是在函数里执行定义好的一系列函数来作为一个终端,因为你要实现一个功能就必须调用函数,然后函数再调用函数再使用变量……这里边定义好一系列功能,然后留一个接口返回给 init,然后 init 调用的时候再启用里边的功能,这么做的好处就是不污染全局变量,而且功能也都能实现,比如说你在外部 var name = “bcd”,你执行 init(), 他还是输出 abc,这就是模块化开发。init:这个 init 是初始化的意思,比如说后边你写了一万行 js 代码,你想让人读懂的话很难,因为他不知道入口在哪,所以你定义一个 init,人们最开始的时候就找你 的 init,执行后顺着 init 再依次的捋下来。

var sayName = (function(){
	var name = 'abc';
	function callName(){
		console.log(name);
	}
	return function(){
		callName();
	}
}())

你执行 init()就输出 abc,执行 Deng()就输出 123,他们并不互相影响,这样的话我的变量可以随便起名,你的变量也可以随便取名,就是我们把全局的变量放在局部, 就是为了他们互相不污染,那么比如说我们在以后定义一个方法可以复用的话,我们就把他放到闭包里保存起来,下次直接复制过来用就行了。

2.对象枚举

其实枚举就是遍历的意思,我们以前讲过遍历数组,遍历就是挨个知道信息的过程。

var obj = {
	name:'abc',
	age:18,
	sex:'male',
	height:100,
	width:75
}

我想知道这个对象里边的每个值是什么,可能这个值是后端传给你的,你拆不开,因为你不能以编辑器的角度去看他,程序在自己执行的时候看不到,所以是无法办到了, 假如你用 for 循环,那么到底该循环几圈?它连 length 都没有,所以说 for 循环也不行。想真正的遍历对象,就必须借助一个新的语法:for in 循环。

(1)for in 循环
for(var prop in obj){
	console.log(prop + " " + typeof(prop))
}

解析:这个输出结果就是 name string; age string; sex string; height string; weight string,这个循环把对象的每一个属性名都提取出来了,而且有多少个属性名他就会循环多少圈,所以说 for in 循环的功能只有一个,就是遍历对象用的,它是通过属性的个数来控制循环圈数的,它在循环每一圈的时候,都会把对象的属性名放到 prop 里边,var prop in obj 这一句话就是每一圈 prop 都代表一个变量,每一圈这个属性名都不一样,这个 obj 就是我们想要遍历的那个对象,prop 可以随便换名字但是 in 是固定的,你想遍历谁你就 in 谁。那么有了属性名我们就可以知道每一圈每个属性对应的属性值了:

for(var prop in obj){
	console.log(obj[prop]);
}

此时就得到 13 123 male 100 75

注意:这个循环里不能写成 console.log(obj.prop);他会输出 5 个 undefined 的,因为你obj.prop系统就自动的obj[“prop”],那么他就会把这个prop当成一个属性的,输出 undefined,你写成 obj[prop](里边不能加引号)他就认为这个 prop 是个变量, 而且我们在上边也验证了这个 prop 里边的值刚好是字符串,所以能说通,以后一定要记住,访问的话可以点啥啥啥,写在 for in 里用来枚举的千万要写成方括号的形式, 而且里边不能加引号!

(2)hasOwnProperty

我现在把上边的对象改成:

var obj = {
	name = 'abc',
	age:18,
	sex:'male',
	height:100,
	weight:75,
	__proto__:{
		lsatName:'wang'
	}
}

我们现在再来用上边的 for in 循环遍历一下里边的值就得到 13 123 male 100 75 wang,这就存在一个问题,wang不是我自己身上的属性,他是我的原型的属性,你怎么也给遍历了?这就造成了一种误差,现在我不想把原型上的东西拿出来,就可以这么做,一个对象天生就有一种方法叫 hasOwnProperty,比如上边的,我们 obj.hasOwnProperty(prop),里边需要传参数,把属性名的字符串形式传进去,这个方法就是判断 prop 是不是你自己的属性的,会返回给你一个布尔值,是自己的属性的话就返回 true,否则返回 false,那么,我们就可以把它塞到 if 语句里,如果这个 prop 是自己的属性的话就输出,如果不是的话就是原型上的,不输出:

for(var prop in obj){
	if(obj.hasOwnProperty(prop)){
		cosnole.log(obj[prop]);
	}
}

此时就得到 13 123 male 100 75,那个原型上的 wang 就没有了。这个 obj.hasOwnProperty(prop)起到一个过滤的作用,因为你遍历的时候并不希望拿到原型上的东西,所以说遍历对象的时候他们是成套来用的。

注意:单说这个 for in 循环,他会把你原型和原型链上的东西都打印出来,但是必须是手动设置的,系统自带的不会打印出来的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山大王杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值