JavaScript(四):对象

124 阅读3分钟

JS三座大山:object、this和AJAX。
object是唯一一种复杂数据类型。

对象

对象一种无序的数据集合,是键值对的集合

写法

let obj = {'name': 'frank', 'age': 18}
let obj = new Object({'name': 'frank'})  // 这是正规写法
console.log({'name': 'frank', 'age': 18})  // 直接初始化对象,不赋值给变量

细节:

  • 键名是字符串,不是标识符,可以是任何字符,emoji也可以
  • 键的引号可以省略,省略之后就只能写标识符
  • (重要)就算引号省略了,键名也还是字符串 每个key都是对象的属性名,每个value都是对象的属性值。
// 如果想用变量的值做为键名,就要加中括号(ES6新增)
let a = 'xxx';
var obj = {
  [a]: 1111
}
-----------------
// 或者先初始化一个空对象
obj = {};
obj[a] = 1111;

对象的隐藏属性

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

对象属性的增删改查

删属性

let obj = {'name': 'frank', 'age': 18};
delete obj.name;
delete obj['name']  // 删除属性的另一种方法
'name' in obj; // 查询属性'name'是否存在,返回false。这种方法不会区分obj对象的自身和共有属性
'toString' in obj; // 如上所述,这行语句返回false.

读属性

Object.keys(obj)  // 查看obj对象的所有属性
Object.values(obj) // 查看obj对象的所有属性值
Object.entries(obj)  // 查看obj对象的所有键值对
console.dir(obj)  // 查看obj对象的构成:自身属性和共有属性
obj.__proto__  // 查看obj对象的隐藏属性
obj.hasOwnProperty('toString')  // 查看toString属性是否是obj对象的自有属性,返回false
/* 查看单个属性,这个有点像python读取dict类型的方式 */
obj['key']  // 中括号语法
obj.key  // 点语法

obj.name等价于obj['name'],不等价于obj[name]
let name = 'frank'; obj[name]等价于obj['frank'],而不是obj['name']

增加或修改属性

// 直接赋值
obj['name'] = 'Brendan';
obj['na'+'me'] = 'Brendan';
obj.name = 'Brendan';

// 批量赋值(ES6新增)
Object.assign(obj, {'name': 'frank', 'gender': 'male'})

如何修改或增加共有属性?

  • 无法通过自身修改或增加共有属性
  • 如果执意修改或增加原型上的属性,请使用Object.prototype.xxx = 'xxx',不推荐用obj.__proto__.xxx = 'xxx'。(原则上是不要修改原型,这会引起很多问题。如果一旦修改,很多共有属性就变得不可信,这是JS的脆弱之处,开发者很容易就能触及语言的根本) obj.__proto__ = null这个语句就会抹去obj对象的隐藏属性,自然隐藏属性就无法被调用。
    ES6推出了修改对象共有属性的方法,可以方便开发者自定原型。这也意味着如果要修改原型,就要在设计之初做好设计工作,中途不要再去修改。
let common = {'国籍': '中国', hairColor: 'black'}
let person = Object.create(common)

返回结果如下
3cb077ae9e276c529b90fd97eb05b80.png

原型 Prototype

每个对象都有原型,原型里存着对象的共有属性,比如obj的原型就是一个对象,obj.__proto__存着这个对象的地址,这个对象里有toString/ constructor/ valueOf等属性。
对象的原型也是对象,所以对象的原型也有原型,obj={}的原型即为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根。这个原型也有原型,是null
console.log(Object.__proto__.__proto__)对象的原型的原型,输出得到的是null