JS 对象基本用法

179 阅读4分钟

JavaScript对象的基本理解

JavaScript里的对象,是第八种数据类型,也是八种类型中唯一的复杂数据类型。

对象的定义是,一种无序的键值对(key-value)的集合。它存储的数据没有顺序,键名也就是属性名,键名的值就是对应的属性值。

对象的键名

对象的所有键名都是字符串(ES6 规则又引入了 Symbol 值也可以作为键名)。因为键名跟标识符不同,所以可以是各种特殊字符也可以。键名默认是字符串,所以加不加引号都可以。如果不加引号,那就只能按照标识符的规则来写字符串,否则会报错。如果键名是数值的时候,会被自动转为字符串,所以键名不可以是数值,这点需要注意。

对象的键名还可以用变量来做。这时需要在变量名外加个[],这样设置后会对变量先求值,转换成字符串后用作键名。这里加不加[]的区别非常容易混淆,也是常见考点,需要多多注意。比如:

let name = 'x';
let obj1 = {name:'tom'};  // 键名为name
let obj2 = {[name]:'tom'}; // 键名为x

声明对象的两种语法

语法很简单,如下:

1. let obj = {'name':'tom'; 'height':'180'};
2. let obj = new Object({'name':'tom'; 'height':'180'});

两种方式是等价的,很显然,我们程序猿一般都会选择第一种写法,它比较简便快捷。第一种写法的本质也是new了一个新的Object对象出来。

增删改查————程序猿的宿命

非资深程序猿的工作日常,就是增删改查,无论做哪一块,何种语言大抵都是如此。学习对一个对象进行操作,也需要从增删改查开始。

改和增基本差不多,放在后面,我们先来说删。

删属性

delete obj.name 或者delete obj['nanme']

删除obj对象的name属性,也对应键名的命名,有两种写法如上。

删除时有个问题,对象存不存在你删的键名呢?需要进行一下判定。 'name' in obj === true 那么就说明在obj对象里包含一个name键名。

这里需要注意另一个容易混淆的点:含有键名,跟属性值为 undefined 无关。如果一个键名对应的属性值是undefined,不能判断这个键名有没有包含在对象里面。.

查属性

其实删属性里已经涉及到查,读属性的部分了。这里探讨一下更详细的查属性相关语法。

  • 查看自身所有键名 使用Object.keys(obj)可以得到对象obj的所有键名。 (另外,使用Object.values(obj)可以得到对象obj的所有属性值。)

  • 查看对象自身及共有属性 console.dir(obj) 注意dir和log的区别,dir的原意是目录,可以增加理解。

这一方法也可看到对象的原型的属性,chrome浏览器会显示在obj.__proto__里。

  • 查看单一属性 中括号或者点语法皆可。
obj.name``` 或者```obj['nanme']

点语法可能会误导人,再次强调一下键名是字符串,或者新增的symbol。

  • 判断一个属性是否共有 obj.hasOwnProperty('toString')

私有返回 true,共有返回 false

关于原型,之前已经探讨过,每个对象都有它的原型存在,原型里存储有对象的共有属性。一般来说obj.__proto__里存着对象原型的地址。

比如 toString / constructor / valueOf 等属性都是对象原型里有的。

修改属性

  • 直接赋值修改
obj.name = 'mike'
等价于obj['name'] = 'mike'
  • 批量赋值 Object.assign(obj, {name: 'mike', age: 25})

增属性

与修改属性的语法基本一样,已有的属性就会进行修改,没有的属性会自动添加。

修改或添加共有属性

  • 无法直接通过自身来增改共有属性,如

obj.toString = 'asd'

只会修改obj自身的属性,改不到原型。

强行要改原型的属性也是可以操作的,这点就体现出JS这门语言的脆弱性了,一些很基本的原型,可以被随意更改里面的方法,导致出现很多问题。

Object.prototype.toString = 'asd'

正常千万不要乱改原型属性。

想新增对象的原型怎么办呢,可以用以下操作 Object.create

let human = {kind: 'human'}; let obj = Object.create(human);

如果要改一个对象的原型,建议一开始就改,不要在操作中途改,很容易出问题。

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

最后再提一句这两个命令的区别。

之前已经说过,判断一个属性是否共有可以用 obj.hasOwnProperty('toString')

如果属性是共有的,不是该对象私有的,会返回 false 值。.

'name' in obj不在乎属性是否私有,或者从原型那里继承的。只要有,就返回 true。