在了解对象基本用法之前,我们必须先清楚什么是对象以及声明对象的写法。

什么是对象

对象就是一组“键值对” 的集合,是一种无序的符合数据集合。

  1. var obj = {
  2. foo: 'Hello',
  3. bar: 'World'
  4. };

上面代码中,大括号就定义了一个对象,它被赋值给变量obj,所以变量obj就指向一个对象。该对象内部包含两个键值对,第一个键值对是foo: ‘Hello’,其中foo是“键名”,字符串Hello是“键值”。键名与键值之间用冒号分隔。第二个键值对是bar: ‘World’,bar是键名,World是键值。两个键值对之间用逗号分隔,最后一个属性后面可以加逗号,也可以不加。

声明对象的写法

对象有三种写法,分别是简单写法、标准写法、匿名写法。
简单写法

  1. let obj = { 'name': 'youzhitang', 'age': 18 }

标准写法

  1. let obj = new Object({'name': 'youzhitang'})

匿名写法

  1. console.log({ 'name': 'youzhitang','age': 18 })

对象基本用法还是我们常见的那四种,增加、删除、修改、查询。

增加或修改(写属性)

如果想增加或修改属性有直接赋值和批量赋值两种方式。

直接赋值

  1. let obj = {name: youzhitang’} // name 是字符串
  2. obj.name = 'youzhitang' // name 是字符串
  3. obj['name'] = 'youzhitang'
  4. obj['na'+'me'] = 'youzhitang'
  5. let key = 'name'; obj[key] = 'youzhitang'
  6. //注意 以下两种是错误写法
  7. // obj[name] = 'youzhitang' // 错,因为name 值不确定
  8. // let key = 'name'; obj.key = 'youzhitang' // 错,因为 obj.key 等价于 obj['key']
  9. 批量赋值

**

assign 分配、赋值

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

增加或修改共有属性

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

  • let obj={},obj2={} //共有toString
  • obj.toString = ‘xxx’只会改obj的自身属性
  • obj2.toString还是在原型上
  1. let obj={},obj2={}
  2. obj.toString='xxx';
  3. console.dir(obj)
  4. //toString: "xxx" obj的自身属性
  5. //toString: ƒ toString() 共有属性不会变

image.png

如果偏要修改或增加原型上的属性呢

  1. obj.__proto__.toString='xxx' //不推荐用这种方式

image.png

  1. Object.prototype.toString = 'xxx'

image.png
一般来说,不要修改原型,会引发很多问题

修改隐藏属性

不推荐使用proto

  1. let obj = {name:'y'}
  2. let obj2 = {name: 't'}
  3. let common = {'hair': 'black'}
  4. obj.__proto__ = common
  5. obj2.__proto__ = common

image.png
推荐使用Object.create

一创建的时候指定原型,后面再改会非常影响性能。

  1. let common = {'hair': 'black'}
  2. let obj = Object.create(common)
  3. obj.name = 'y'
  4. let obj2 = Object.create(common)
  5. obj2.name = 't'

image.png

这种方法加属性只能用obj.xxx = 'xxx'加,不然就会很复杂。

  1. let common = {'hair': 'black'}
  2. let obj = Object.create(common,{
  3. name:{value:'youzhitang'}
  4. })

image.png

删除

一般delete只能删属性,删其他的东西最好不用delete用其他的方法。

delete命令用于删除对象的属性,删除成功后返回true。
它有两种写法:delete obj.xxxdelete obj['name']

  1. var obj = { 'name': 'youzhitang','age':18 };
  2. Object.keys(obj)
  3. delete obj.name
  4. //或
  5. //delete obj['name']

能不能用 obj.xxx=undefined来删呢?

答:不能,因为undefined就像把一个东西的名字给剥夺了,但实际上它还是有名字那一栏的;但是delete就像把整个名字那一栏删掉。
undefined仅仅删掉属性值,delete删掉的是它的属性名和属性值。
注意: 不能用obj.xxx===undefined来断定‘xxx’是否为obj的属性。因为如果xxx等于undefined,他就不能判断xxx在不在对象里面。

可以用’xxx’ in obj && obj.xxx===undefined 来判断含有这个属性名但是值为undefined。

  1. var obj = { 'name': 'youzhitang','age':18 };
  2. Object.keys(obj)
  3. obj.name = undefined
  4. 'name' in obj && obj.name===undefined

1441_1.png

注意,删除一个不存在的属性,delete不报错,而且返回true。

  1. var obj = {};
  2. delete obj.p // true

上面代码中,对象obj并没有p属性,但是delete命令照样返回true。因此,不能根据delete命令的结果,认定某个属性是存在的。

只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。

  1. var obj = Object.defineProperty({}, 'p', {
  2. value: 123,
  3. configurable: false
  4. });
  5. obj.p // 123delete obj.p // false

上面代码之中,对象obj的p属性是不能删除的,所以delete命令返回false(关于Object.defineProperty方法现在不必明白)。

另外,需要注意的是,delete命令只能删除对象本身的属性,无法删除继承的属性。

  1. var obj = {};
  2. delete obj.toString // true
  3. obj.toString // function toString() { [native code] }

上面代码中,toString是对象obj继承的属性,虽然delete命令返回true,但该属性并没有被删除,依然存在。这个例子还说明,即使delete返回true,该属性依然可能读取到值。

查询

  1. Object.key(obj) //查所有的key
  2. console.dir(obj) //通过目录看自身的以及原型的属性
  3. obj.['name'] //看单个属性的方法
  4. obj.name //看单个属性的方法,这里的name是字符串
  5. obj[name] //看单个属性的方法,这里的name是变量

‘name’ in obj和obj.hasOwnProperty(‘name’) 的区别

答:用‘xxx’in obj 看一下属性名在不在对象里就好了。是它的属性就是true,不是的话就是false。

  1. var obj = { 'name': 'youzhitang','age':18 };
  2. Object.keys(obj)
  3. delete obj.name
  4. 'name' in obj

1439_1.png
但是这个方法有个问题它无法判断这个属性是自己的还是原型上共有的,所以提供了hasOwnProperty方法判断一下,是否为对象自身的属性。

  1. var obj = {};
  2. if ('toString' in obj) {
  3. console.log(obj.hasOwnProperty('toString')) // false
  4. }

其他

  1. let obj = Object.create({name:'youzhitang'})let obj2 = new Object({name:'youzhitang'})有什么区别。
    答:他们的结构和自身属性是不一样的。

1453_1.png

  1. 原型和共有属性有什么差别。
    原型的本质是一个对象,共有属性是一个属性。
    原型是包含toString的对象,每一个属性是共有属性,原型包含了共有属性,共有属性依附于原型。