关于对象Object的细碎知识

464 阅读5分钟

1.定义对象

两种定义方式:文字定义和构造函数定义

image.png

区别是:使用文字定义的可以在定义时候添加多少属性;使用构造函数定义的,只能一个属性一个属性的添加。

2.类型:

基本数据类型:string,boolean, number, null, underfined;

复杂数据类型: object

内置对象: String, Boolean, Number, Array,Date,Function,Object,RegExp,Error

注意:平常使用基本类型时候,如果涉及到方法的操作,都是先转换成对应内置对象。

image.png

Date只有构造函数形式,没有文字形式。

3.内容:对象中的内容并不是真正的保存在对象中,而是像一个指针一样,指向引用

  • 属性使用

获取对象属性值,有两种方式:对象.属性名(属性访问)和对象[‘属性名’](键访问)

这两种可以转换使用,区别是属性访问,要去属性名必须满足标识符的命名规范,键访问可以是任意utf-8/Unicode编码格式

使用键访问中,如果属性名设置为一个非字符串类型的值,则会首先转为字符串,数字也不例外。数组除外,数组确实是数字

image.png

  • 可计算属性值 es6新增

设置属性名可以使用一个表达式来显示

image.png

  • 对象的拷贝

使用Json实现深拷贝

image.png

对象浅拷贝

使用assign(),assign的原理是使用=进行赋值操作,以完成对象的拷贝。所以他只会拷贝属性值,不会拷贝对应属性的特性。

  • 属性描述符

每个对象的属性除了值属性外都会有3个特性:writable(可写),enumerable(可枚举),configurable(可配置)

在创建属性时会属性描述符会使用默认值。要修改属性对应的特性时,可以使用defineProperty()

image.png

设置writable为false时,对应属性值不能被修改;

设置enumerable为false时,遍历对象属性时,该属性不能被遍历

设置configurable为false时,不能再使用definePerpety修改当前属性的特性,如果当前writable为true,则仍旧可以修改值,并且可以将writable由true改为false。congfigrable是单向的,不可逆的。修改为false后, 不能再改为true。并且当置为false时,该属性是不可以删除的。

  • 不变性

所有的对象都是浅不变性,即当前对象修改对应属性特性后,该对象指向其他对象时,不受影响(只会影响目标对象和他的直接属性,如果目标对象引用指向了其他对象,其不受影响)。

  1. 对象常量

使用writable:false,和configurable:false,就可以说设置一个不可修改、重定义和不可删除的常量属性;

2.禁止扩展

如果想让对象禁止添加一个新属性并且保留已有属性,可以使用preventExtensions(...);

当前并未修改当前对象的属性描述符,只是将对象设置为能添加新属性,并且对象key删除已有属性。

image.png 3.密封

使用seal(),会创建一个密封对象。

实质就是该对象调用preventExtensions(),并且设置对象内所有属性属性的操作符configurable:false。实现了对象不能添加新属性,并且不能重新配置和删除已有属性,但是依旧可以修改属性对应的值。

4.冻结

使用freeze()会冻结一个对象

实质就是这个方法会调用seal(),并设置对象内的所有属性的属性操作符writable:true;

那么当前这个对象,既不能添加删除,也不能修改值。

只是对当前属性影响,当前对象内引用的其他对象不受影响。

  • Object默认的两种操作[[get]],[[put]]

[[get]]:获取属性值,如obj.name,看似直接拿对象的属性值,其实不是的。他是执行了对象上默认的[[get]]操作,[[get]]操作首先会在自身上查找该属性,如果没有会像当前对象的原型[[prototype]]上查找属性,如果查找到则返回,否则返回underfined;如果当前属性值就设置为underfine的,则不能判断出来当前值是underfined,还是当前属性不存在。

[[put]]:

  1. 判断属性是否是执行操作符,如果是并且有setter,就执行setter;
  2. 属性的数据描述符中writable是否为false,如果是在非严格模式下静默失败,在严格模式下抛出typeError异常
  3. 如果都不是,将该值设置为属性的值。
  • 访问操作符 getter setter

getter和setter不能修改整个对象,只能应用在单个属性上。他两个都是隐藏操作符,在获取或着赋值时候调用。

当给一个属性定义setter或者getter时候,这个属性就会被定义为访问描述符(和数据描述符相对)。对访问描述符来说,JavaScript会忽略他的value和writable特性。取而代之的是关心set和get(同时包括enumerable和configurable)

使用get/set 和使用definePropety结果是一致的。

image.png

! 由于get函数返回了数字2,此时设置set无论是什么值都不起作用

image.png

  • 存在性

判断一个属性是否存在于对象中,可以使用:

image.png 或者使用hasOwnProperty()

image.png

这两者的区别是:in会查找当前对象原型链上的属性,hasProperty只会查找当前对象的属性。

判断对象属性是否可枚举,使用propetyIsEnumerable(),会判断对象是否存在对象上并且weitable:true;

Object.keys()会返回一个数组,包含当前对象的所有可枚举属性;

getOwnPropertyNames() 返回对象所有属性。

Object.keys()和getOwnPropertypeNames()都是只是查找当前对象的属性。

  • 遍历

遍历对象使用for...in,并且for in会遍历原型链中的属性

使用forin只会遍历对象中可枚举的属性。

for...of不会遍历对象。如果想要使用for of遍历对象需要自定义iterater属性。

Symbol.iterator 来获取对象的 @@iterator 内部属性。

image.png

注:这些内容主要是学习完你不知道的JavaScript 对象一章后做的知识总结。