对象(Object)是一组无序的数据集合,由键值对组合而成。
对象的声明
var obj = new Object();var obj = {};{foo:1}//这不是对象,这是lebel语句console.log({foo:1})//可以正确输出对象
对象的属性
对象中包含了定义的键值对,另外还有proto(存有所有对象原型的地址)。
1.对象的键名都是字符串,因此可以填入任何内容,不是标识符。(尽管你写入的是数字或者标识符,但是它其实是省略了’’,其实是字符串,但是省略了`’’后就只能写普通的标识符(中文等除外))
2.去掉省略号直接写键名,会出现奇怪的现象,例如写入16进制值0xff,会被转化成255,JS会把它转化成10进制数值再转化成字符串。
3.如果想要在键名中使用变量,则要使用[ ]进行包裹。(会对变量进行求值,然后转化成字符串)
var a=1;
var obj={
'😏':0,// 有效
0xff:1,// 255:1
'0xff':2,// oxff:2
[a]:3// 1:3,会对变量a进行求值,再转化成字符串
}
对象的原型及原型链
1.每个对象都有原型(proto),储存了所有对象的共有属性(构造函数的prototype的地址)。
2.构造函数(Objecrt(),Array(),Date()等)的prototype储存了所有实例对象的共有属性,它也是对象,它的原型(proto)是Object的prototype(对象的根),这就使得实例在存有不同的类的方法的时候,还可以调用Object的方法,而Object的prototype的proto被设定为了null。
3.构造函数同时也是Function构造的,因此构造函数也有proto原型,即为Function的prototype,
这样就形成了原型链。
几个问题
1.window是谁构造的?
Window()构造函数构造的
2.window.Object是谁构造的?
window.Function()构造函数构造的,它是所有函数的构造者
3.window.Function是谁构造的?
还是window.Function(),浏览器构造了Function,并指定它的构造者是自己
对象属性的增删改查
删
使用delete操作符,注意:将对象的键值设置为undefind或者null,并不是删除了键名,而是键名未赋值。
var a = 1;
var obj = {
"😏": 0, // 有效
0xff: 1, // 255:1
"0xff": 2, // oxff:2
[a]: 3, // 1:3,会对变量a进行求值,再转化成字符串
};
obj.a = null;
delete obj["😏"];
console.log(obj);//{1: 3, 255: 1, 0xff: 2, a: null}
查
查键名
1.Object.keys(obj),读取对象的键名 Object.values(obj),读取对象的键值,均会返回数组
Object.entries(obj),读取对象的属性,包括键名和键值,返回二元数组
2.obj.valueOf(),读取对象的键值
3.console.log()或者console.dir(),读取对象的键名和键值
判断对象是否有某种属性
4.使用in操作符,可以判断某一个属性在不在对象中,不会区分是否是共有属性
5.使用方法obj.hasOwnProprety(),会区分是否是共有属性(hasownproperty有自己的),如果在proto中,会返回false(注意proto只是一个名称,不同浏览器不同,这个是chrome的)
查看对象的键值
1.obj.name
2.obj.[‘name’],注意,[ ]中的如果不是字符串,则会对其求值,并转化为字符串,如下
var obj = {'name':1};
obj.[console.log('name')];//undefined,等价于obj.['undefined'],console.log()返回undefined
增、改
修改或者增加对象的属性,与读取键值的方法相同
1.obj.name
2.obj.[‘name’],注意,[ ]中的如果不是字符串,则会对其求值,并转化为字符串
3.给一个对象批量赋值
Object.assign(obj,{ }),会把{ }里的键值对全部添加给obj对象
4.以原型创建对象
let obj = Object.create(common,{
name:{value:1},
age:{value:18}
});
以common为原型创建对象,等于在原型链中增加了一个节点,其中对象的属性要按上述格式写。
defineProperty增、改属性
Object.defineProperty(obj,’属性名’,{描述符})使用defineProperty来增加或者修改对象的属性(或者Object.defineProperties()),描述符用来规定对象的一些特性,具体描述符如下
configurable |
enumerable |
value |
writable |
get |
set |
|
|---|---|---|---|---|---|---|
| 数据描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| 存取描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
configurable为属性是否可以删除,以及除了value和writable之外的描述符是否可以被配置。
enumerable为属性是否可以被遍历,keys或者for..in。
value为属性的值。
writable为属性是否可以被重新赋值。
get和set为监听属性的访问、设置的事件,get、set中的this指向对应的属性。
利用set、get设置对象的访问器
因为set、get可以监听对象,因此可以使用他们进行访问器的设置。
值得注意的是,如果set和get设置的属性与对象普通属性冲突了,那么访问器的属性优先级更高,可以通过封装私有属性的方法来封装对象的普通属性。
用于设置对象的几个API
1.Object.preventExtentions(obj),设置对象不能添加属性。
Object.isExtensible(obj),检测对象是否可以被添加属性。
2.Object.seal(obj),封闭对象,即设置对象不可被添加属性,且设置对象的configurable为false,因此也不能删除属性,不能配置除了value和writable以外的描述符。
Object.isSealed(obj),检测对象是否封闭。
3.Object.freeze(obj),冻结属性,在seal的基础上,冻结属性不可以修改属性的值,即把writable设置为false。
Object.isFrozen(obj),检测对象是否冻结。
