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)
返回结果如下
原型 Prototype
每个对象都有原型,原型里存着对象的共有属性,比如obj的原型就是一个对象,obj.__proto__存着这个对象的地址,这个对象里有toString/ constructor/ valueOf等属性。
对象的原型也是对象,所以对象的原型也有原型,obj={}的原型即为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根。这个原型也有原型,是null。
console.log(Object.__proto__.__proto__)对象的原型的原型,输出得到的是null