Es6 复阅(12)(部分是非es6的) --对象的扩展(2)

19 篇文章 0 订阅

tip:bind方法创造的函数,name属性返回bound加上原函数的名字
Function构造函数创造的函数,name属性返回anonymous

1.属性的可枚举性和遍历
Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象

	let obj = {
		name:1
	}
	let desc = Obj.getOwnPropertyDescriptor(obj,name)
	/**
		{value: 1, writable: true, enumerable: true, configurable: true}
	*/	
  • value 是这个属性的对应的值
  • writable 是这个属性是否可写
	obj.name = 2;
	// obj.name  2

说明这个属性是可写的

  • enumerable 这个属性的可枚举性
	for...in循环:只遍历对象自身的和继承的可枚举的属性。 // 会返回继承的属性
   Object.keys():返回对象自身的所有可枚举的属性的键名。
   JSON.stringify():只串行化对象自身的可枚举的属性。
   Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。

即是说,如果一个对象的属性的可枚举性是false,则像 Object.keys() 返回的结果中就不会包含这个属性

	Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
	// false
	
	Object.getOwnPropertyDescriptor([], 'length').enumerable
	// false

对象继承的这些方法由于是不可枚举的,所以我们在对一个对象进行for…in 操作的时候,是不会枚举到这些方法的

ES6 规定,所有 Class 的原型的方法都是不可枚举的

:尽量不要用for…in循环,而用Object.keys()代替

属性的遍历方法说明

1.for…in
循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)

	let obj = {
		1:233,
		like:1,
		[Symbol(1)]:1,
		[Symbol(2)]:1,
		[Symbol(3)]:1,
		[Symbol(4)]:1,
		[Symbol(5)]:1,
	}
	for(let key in obj){
	}
	// key: 1
	// key:like

2.Object.keys(obj)

	let obj = {
		1:233,
		like:1,
		[Symbol(1)]:1,
		[Symbol(2)]:1,
		[Symbol(3)]:1,
		[Symbol(4)]:1,
		[Symbol(5)]:1,
	}
	let keyArr = Object.keys(obj);
	// ["1","like"]

3.Object.getOwnPropertyNames(obj)

	let obj = {
		1:233,
		like:1,
		[Symbol(1)]:1,
		[Symbol(2)]:1,
		[Symbol(3)]:1,
		[Symbol(4)]:1,
		[Symbol(5)]:1,
	}
	let res = Object.getOwnPropertyNames(obj);
	// ["1", "like"]

这个方法 与上面的 Object.getOwnPropertyNames(obj) 用法基本相同,不过Object.getOwnPropertyNames(obj) 可以返回对象的不可枚举的属性(不含Symbol 属性)

4.Object.getOwnPropertySymbols(obj) – 返回对象自身的所有 Symbol 属性的键名

	let obj = {
		1:233,
		like:1,
		[Symbol(1)]:1,
		[Symbol(2)]:1,
		[Symbol(3)]:1,
		[Symbol(4)]:1,
		[Symbol(5)]:1,
	}
	let res = Object.getOwnPropertySymbols(obj);
	/**
		[Symbol(1), Symbol(2), Symbol(3), Symbol(4), Symbol(5)]
	*/

5.Reflect.ownKeys(obj) --包含对象自身的所有键名

	let obj = {
		1:233,
		like:1,
		[Symbol(1)]:1,
		[Symbol(2)]:1,
		[Symbol(3)]:1,
		[Symbol(4)]:1,
		[Symbol(5)]:1,
	}
	let res = Reflect.ownKeys(obj);
	// ["1", "like", Symbol(1), Symbol(2), Symbol(3), Symbol(4), Symbol(5)]
	
以上几种方法共同的属性遍历规则:
```markup6
	1.首先遍历所有数值键,按照数值升序排列。
	2.其次遍历所有字符串键,按照加入时间升序排列。
	3.最后遍历所有 Symbol 键,按照加入时间升序排列。
  • enumerable 属性的可配置性
	let obj = {
		name:1,
		code:2
	}

看下这个name属性的可配置性:

	Object.getOwnPropertyDescriptor(obj,'like')
	/*
		{value: 1, writable: true, enumerable: true, configurable: true}
	*/

冻结对象:

	Object.freeze(obj);
	Object.getOwnPropertyDescriptor(obj,'name')
	// {value: 1, writable: false, enumerable: true, configurable: false}

冻结之后,这个对象的可写和可配置都变为false了,如果这个对象有多层,则内层对象还是可写的

	let obj = {
		obj1:{
			name:1
		},
		name:1
	}
	Object.freeze(obj);
	Object.getOwnPropertyDescriptor(obj,'name');
	obj.obj1.name = 2; 
	/**
		let obj = {
			obj1:{
				name:2
			},
			name:1
		}
	*/

所以如果想通过冻结对象来使得对象不可写的话,需要递归冻结每一层的子对象

  • Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
	let obj= {
		name:1
	}

开始配置:

	Object.defineProperty(obj,'name',{
		writable:true,
		enumerable:true,
		configurable:false,
		value:4
	})
	console.log(obj);// {name:4}
	Object.getOwnPropertyDescriptor(obj,'name')
	//{value: 4, writable: true, enumerable: true, configurable: false}

现在我们还是不明白这个 configurable 的用处到底是什么

表示能否通过delete删除属性从而重新定义属性

我们已经将上面这个对象的 name 属性 的configurable 修改为false了,当我们尝试删除这个属性的时候:

	delete obj['name']
	console.log(obj);// {name:4}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值