JS中万物都是对象,今天就深度讲一下Object的里面到底有什么。文章主要讲对象的自有属性和原型中的属性,至于原型链就不在这篇文章多讲了。
创建对象的方法有如下几种
Object.assign() 方法用于将其他对象的可枚举属性复制到目标对象(即第一个参数对象)
常用于将某个对象合并到新对象{}。
常用于继承某个构造函数的原型属性,但是不能继承该构造函数的实例属性,例如上面例子
该属性是实现vue双向数据绑定的核心,这里主要讲它的使用方法。
讲它的相关用法时,就得先理解 的概念。
1.数据属性
数据属性的四个特性
configurable: 表示是否能被delete删除属性且能重新定义该属性。
enumerable: 表示能否通过for-in遍历的属性。
writable: 表示是否能修改属性。
value: 属性的值。
2.访问器属性
数据属性不包含数据值,包含一对get和set的核心方法,在读取访问器属性时,就是通过这两个方法进行操作处理的。
访问器属性的四个特性
configurable: 表示是否能被delete删除属性且能重新定义该属性。
enumerable: 表示能否通过for-in遍历的属性。
get: 读取属性时调用的方法,默认值是undefined。
set: 写入属性时调用的方法,默认值是undefined。
从图中可以看到访问器属性的configurable和enumerable两个属性的默认值都是false,如果后面要对该访问器属性进行delete删除时,将configurable转化成true即可。
从图可以看出该对象具有四个属性,
(defineProperty、defineProperties、getOwnPropertyDescriptor、getOwnPropertyDescriptors)
这四个属性是分为两对:defineProperty vs getOwnPropertyDescriptor、defineProperties vs getOwnPropertyDescriptors。
意思为属性设置和属性的获取解析,第一对上面讲过了,这里就大概说一下第二对的意思,也就是支持设置对个属性,获取多个属性的意思。
Object.defineProperties()
Object.getOwnPropertyDescriptors()
打印出对象的所有属性
Object.entries() 方法返回一个给定对象
Object转Map
new Map()构造函数接受一个二维数组,而Object.entries()方法生成一个二维数组,所以对象、数组、字数串转化为Map结构变得简单。
正常对象的数据属性都可以被 但是通过以下方法,改变了数据属性的四大特性。
相对应的检测方法,返回Boolean。
举例
Object.freeze()方法可冻结对象,冻结后,对象属性不能删除,修改以及添加,只能for...in读取。
该对象方法和==与===运算符相似,但是有明显区别。
Object.is与==比较
== 会将两边的操作数进行隐式转化,之后再进行比较,但是Object.is就不会进行转化。
Object.is与===比较
=== NaN和NaN不等,-0与+0相等,但是Object.is就认为NaN和NaN是相等,而-0和+0是不相等的。
所以总的来说这两个的相似程度比== 运算符更相近。
Object.keys()返回一个 名称(键)的数组
Object.values()返回可枚举属性值得数组
Object.setPrototypeOf(obj, prototype)
为对象obj设置新的原型对象。
注意
如果对象的[[Prototype]]被修改成不可扩展(通过 Object.isExtensible() 查看),就会抛出 TypeError 异常。如果 prototype 参数不是一个对象或者 null (例如,数字,字符串,boolean,或者 undefined ),则什么都不做。否则,该方法将 obj 的 [[Prototype]] 修改为新的值。
下篇文章 JS 对象(Object)的深入解析—原型属性
Object.entries(obj)
将一个可枚举对象按照键值对展开为数组
Object.assign(target, source)
将一个或多个可枚举对象的可枚举属性复制到 target 对象,返回 target 对象。第一级属性深拷贝,以后级别属性浅拷贝
Object.freeze(obj)
相应的也有判断是否冻结的方法----Object.isFrozen()
冻结一个对象。一个被冻结的对象再也不能被修改,包括所有的属性,甚至包括他的原型。返回与原对象相同参数的对象
Object.create(obj)
创建一个新对象,将现有的对象创建为新对象的 proto 。返回一个新对象
Object.keys(obj)
遍历一个对象,将 key 返回为数组
Object.defineProperty(obj, prop, descriptor)
参数:
obj:被操作对象
prop:修改或要定义的属性名
descriptor:修改或要定义的属性的属性描述,即prop的描述
新增或修改一个对象的属性,并返回该对象
扩展:在vue中通过递归调用此方法,为对象的每一个属性绑定get()、set()方法,实现对象的数据监听
Object.getPrototypeOf(obj)
返回目标对象的 prototype 的值。
给定对象的原型。如果没有继承属性,则返回 [null]
JavaScript 原生提供Object对象(注意起首的O是大写),JavaScript 的所有其他对象都继承自Object对象,即那些对象都是Object的实例。
Object本身是一个函数,可以当作工具方法使用,将任意值转为对象。这个方法常用于保证某个值一定是对象。
Object函数的参数是各种原始类型的值,转换成对象就是原始类型值对应的包装对象。
如果Object方法的参数是一个对象,它总是返回该对象,即不用转换。
利用这一点,可以写一个判断变量是否为对象的函数。
function isObject (value) {
returnvalue ===Object(value)
}
isObject([])// true
isObject(true)// false
Object不仅可以当作工具函数使用,还可以当作构造函数使用,即前面可以使用new命令。
Object构造函数的首要用途,是直接通过它来生成新对象。
注意,通过var obj = new Object()的写法生成新对象,与字面量的写法var obj = {}是等价的。或者说,后者只是前者的一种简便写法。
varo1 = {a:1}
varo2 = new Object(o1)
o1 === o2// true
var obj =new Object(123)
obj instanceof Number// true
虽然用法相似,但是Object(value)与new Object(value)两者的语义是不同的,Object(value)表示将value转成一个对象,new Object(value)则表示新生成一个对象,它的值是value。
所谓“静态方法”,是指部署在Object对象自身的方法。
1、Object.keys(),Object.getOwnPropertyNames()
对于一般的对象来说,Object.keys()和Object.getOwnPropertyNames()返回的结果是一样的。只有涉及不可枚举属性时,才会有不一样的结果。Object.keys方法只返回可枚举的属性(详见《对象属性的描述对象》一章),Object.getOwnPropertyNames方法还返回不可枚举的属性名。
由于 JavaScript 没有提供计算对象属性个数的方法,所以可以用这两个方法代替。
var obj = {p1:123,p2:456}
Object.keys(obj).length// 2
Object.getOwnPropertyNames(obj).length// 2
一般情况下,几乎总是使用Object.keys方法,遍历对象的属性。
2、其他方法
除了上面提到的两个方法,Object还有不少其他静态方法,将在后文逐一详细介绍。
(1)对象属性模型的相关方法
Object.getOwnPropertyDescriptor():获取某个属性的描述对象。
Object.defineProperty():通过描述对象,定义某个属性。
Object.defineProperties():通过描述对象,定义多个属性。
(2)控制对象状态的方法
Object.preventExtensions():防止对象扩展。
Object.isExtensible():判断对象是否可扩展。
Object.seal():禁止对象配置。
Object.isSealed():判断一个对象是否可配置。
Object.freeze():冻结一个对象。
Object.isFrozen():判断一个对象是否被冻结。
(3)原型链相关方法
Object.create():该方法可以指定原型对象和属性,返回一个新的对象。
Object.getPrototypeOf():获取对象的Prototype对象。
除了静态方法,还有不少方法定义在Object.prototype对象。它们称为实例方法,所有Object的实例对象都继承了这些方法。