《JS 对象基本用法》

253 阅读6分钟

我们来了解一下JS的数据类型有哪些?

数字(Number)

字符串(String)

布尔(Boolean)

符号(Symbol)

空(Undefined)

空(Null)

对象(Object)

关于JS的数据类型,可以简写为:“四基两空一对象”。其中,前六种数据类型为简单的数据类型,Object为唯一的复杂类型。

还有五个fasly值:undefined、null、NaN、0、''

JS对象

定义

JS对象是无序的数据集合,也是键值对的集合。(键值对中的键(key)是指对象的属性名,值(value)指的是对象的属性值)

对象的声明

简写,一般都用这种写法

let obj = { 'name' : 'frank' , 'age' : 18}

下面这种是正规写法但是太麻烦了

知道它是怎么构造查出来的就OK了

let obj = new Object ({ 'name' : 'frank' , 'age' : 18})

细节

1. 键名是字符串,不是标识符,可以包含任意字符;

2. 引号可以省略,但是省略之后就只能写标识符(按照标识符的要求来,第一个字符不能以数字开头)或者只使用数字;

3. 就算引号省略了,键名也还是字符串(这是一个重点,必须要理解并记住)。

用变量作属性名

有些时候,我们需要用变量来做属性名:

let p1 = 'name'

let obj = { p1 : 'frank' } 这样写,对象的属性名为'p1',并不是变量。

let obj = { [p1] : 'frank' } 这样写,对象的属性名为'name'。这时,我们就以一个变量作了对象的属性名。

总结

不加[]的属性名,会被自动变为字符串;

加了[],则会被当作变量进行求值,然后以求得的值作为对象的属性名,求得的值如果不是字符串,也会自动转变为字符串。

对象的隐藏属性

隐藏属性储存着原型的地址

JS中,每一个对象都有一个隐藏属性,这个隐藏属性储存着其共有属性组成的对象的地址,这个共有属性组成的对象叫做原型。

每一个对象都有原型,原型中存着对象的共有属性;

对象的原型也是对象,这个对象的原型也有原型,这个原型包含所有对象的共有属性,是对象的根。

对象属性的增删改查

删除对象属性

delete obj.xxx或者delete obj['xxx']

通过上述两种方式,可以删除对象的xxx属性。

区分两种方式

delete obj.xxx或者delete obj['xxx']

通过这种方式,可以将对象的属性彻底删除,包括属性名以及属性值。

obj.xxx = undefined

通过这种方式,只是将对象的xxx属性的当前的属性值改为了undefined,而并非将该属性完全删除。

如何确认一个属性是否属于某个对象(只有用in操作符)

'xxx' in obj

通过上述API可以判断属性'xxx'是否属于对象obj。若得到的值为true,则表示属性'xxx'属于对象obj;若得到的值为false,则表示该属性不属于对象obj。

通过obj.xxx === undefined并不能判定属性'xxx'是否属于对象obj。

查看对象属性

查看所有自身属性

Object.keys(obj)

查看自身所有属性的属性名以及属性值,得到的是一系列的数组,每一个属性对应一个数组。

Object.entries(obj)

查看自身+共有属性

console.dir(obj)

可以判断一个属性'xxx'是否是对象的自身属性。

obj.hasOwnProperty('xxx')

当得到的值为true时,说明'xxx'属性是对象的自身属性;反之,当得到的值为false时,说明该属性有可能是对象的共有属性或者对象中并没有该属性。

'name' in obj和obj.hasOwnProperty('name') 的区别

'name' in obj

用来确定'name'属性是否属于对象obj,但是它无法判断'name'属性是obj的自身属性还是共有属性。

obj.hasOwnProperty('name')

用来确定'name'属性是否是对象obj的自身属性。

查看单个属性

中括号语法

obj['key'] //此时的key是字符串'key'

点语法

obj.key //此时的key是字符串'key'

坑新人语法

obj[key] //此时的key是变量,需要先确认key的值

建议优先使用中括号语法 这样可以保证新手在使用时,不会忘记当前的key是一个字符串,而不是一个变量。

关键知识点

obj.name等价于obj['name'],而不等价于obj[name]

简单来说,obj.name与obj['name']中的name是字符串,而不是变量。

下面是一道帮助我们理解记忆的题目,弄清楚这道题,有助于我们理解上述知识点

代码如下:

let list = ['name', 'age', 'gender'] let person = { name:'frank', age:18, gender:'man'} for(let i = 0; i < list.length; i++){ let name = list[i] console.log(???) }

问题:要使得person的所有属性都被打印出来,问号处应该怎么填写?

A.console.log(person.name)

B.console.log(person[name])

答案是选择B。

因为选项A中的name是一个字符串,所以结果会打印出三遍person的name属性的值;

选项B中的name是一个变量,通过for循环,使得name的值分别为'name'、'age'、'gender',这样就可以将person的三个属性的值都打印出来。

修改或增加对象属性(写属性)

一、可以通过直接赋值进行操作

let obj = {name: 'frank'}

obj.name = 'frank'

obj['name'] = 'frank'

obj['na'+'me'] = 'frank'

let key = 'name'; obj[key] = 'frank'

二、可以进行批量赋值

通过下列API即可对对象的属性进行批量赋值

Object.assign(obj,{name:'frank',age:18,gender:'man'})

上述实例表示给对象obj同时赋值三个属性,包括name、age以及gender。

修改或增加共有属性

无法通过自身修改或增加共有属性

看下列示例:

let obj ={}, obj2 ={} obj.toString = 'xxx'

obj与obj2有着共有属性toString,当执行obj.toString='xxx'时,只是修改了obj自身的属性,而obj2.toString仍然在原型上。

如果我们非要对原型中的属性进行修改时,建议使用:Object.prototype.toString = 'xxx'进行修改。

修改对象的原型(一般来说,不要修改原型,会引起很多问题 )

不推荐使用__proto__去修改对象的原型,一般推荐使用Object.create进行修改。

示例一:(不推荐)

let obj = {name:'frank'} 
let obj2 = {name: 'jack'}
let common = {kind: 'human'} 
obj.__proto__ = common 
obj2.__proto__ = common 

示例二:(推荐,一创建就指定原型)

let obj = Object.create(common) 
obj.name = 'frank' 
let obj2 = Object.create(common) 
obj2.name = 'jack' 

规范的大概意思是,要改就一开始就改,别后来再改,后来改会非常影响性能

查属于读,改和增属于写。查的时候会看原型链,改和增是不会看一个对像的原型链的,改只能改自身,增也只能增自身