Javascript中的Object和Map
Object是指内存中的可以被标识符引用的一块区域
在JavaScript中,对象是唯一可变的值
对象可以被看作是一组属性的集合
属性键要么是字符串类型,要么是symbol
属性值可以是任何类型的值,包括其它对象,从而可以构建复杂的数据结构
创建Object类型
1.new运算符
var obj = new Object(); //new关键字可以省略
obj.name = 'MyName'; //创建属性字段
2.字面量方式
var obj = {name : 'MyName',age : 28};
如果属性名和值相同,可以使用简写
obj = { x, y } 等价于 obj = { x:x, y:y }
在使用字面量声明Object对象时,不会调用Object()构造函数
获取和设置属性
点表示法:obj.key
中括号表示法:obj[key]
两种方式的区别:点表示法仅能获取字面量属性,并不能动态获取属性
let demo = 'name';
obj.demo; //获取obj的demo属性
obj[demo]; //获取obj的name属性
obj['demo']; //获取obj的demo属性
相比较来讲中括号表示法更加灵活
删除属性
delete obj.key;
数据属性和访问器属性
Object中的属性有两种类型:数据属性和访问器属性,每个属性都有对应的特性(attribute)
数据属性:将键与值相关联,可以通过以下属性来描述:
value:通过属性访问器获取的值,默认undefined
writable:默认false,表示是否可以通过赋值来改变属性
enumerable:默认false,表示是否可以通过 for...in 语句遍历到该属性
configurable:默认false,表示该属性是否可以删除
访问器属性:将键与两个访问器函数(get 和 set)关联,用来获取或者设置值,可以通过以下属性来描述:
get:值为一个无参数的函数,函数名为属性名,用来拦截使用属性访问器获取指定属性时的返回值,默认undefined
let demo = {
get name(){
return 'myname';
},
get age(){
return 30;
}
}
console.log(demo.name); // myname
console.log(demo.age); // 30
console.log(demo.address); // undefined
set:值为一个有一个参数的函数,函数名为属性名,用来拦截设置指定属性的值时的操作,默认undefined
let demo = {
list:[],
set name(myname){
this.list.push(myname);
}
}
console.log(demo.list); // []
demo.name = 'sanqian';
console.log(demo.list); // ['sanqian']
使用set时不能改变自身的值,会造成死循环
set name(myname){this.name=myname;}
// set拦截的就是name属性,而操作中也是在修改name属性,造成死循环
不能为一个属性设置多个set
enumerable:默认false,表示是否可以通过 for...in 语句遍历到该属性
configurable:默认false,表示该属性是否可以删除
Object中的访问器属性中的get和set可以通过对象的字面量方式设置,但是其他属性和数据属性就需要通过Object原型中的方法来设置或获取
Object.getOwnPropertyDescriptor(obj,key):获取指定的obj对象的key属性的访问器属性或数据属性
Object.defineProperty(obj, key, descriptor):设置指定的obj对象的key属性的访问器属性或数据属性,属性描述符descriptor用于设置属性
Object.defineProperties(obj, descriptor):同时设置指定的obj对象添加多个属性的属性描述符
descriptor为一个对象,属性名为要设置的属性,值为一个属性描述符对象
一个对象的同一个属性不能同时设置访问器属性和数据属性
静态方法
Object.assign(target, ...sources):将若干个对象中的自有属性合并到target中,修改target对象并返回
Object.create(obj):根据obj的自有属性创建一个新的对象
Object.defineProperty(obj, key, descriptor):设置指定的obj对象的key属性的访问器属性或数据属性
Object.defineProperties(obj, descriptor):给对象添加多个属性并分别指定它们的配置
Object.entries(obj):返回obj对象自身属性的[key, value]组成的数组
Object.getOwnPropertyDescriptor(obj,key):获取obj的key属性的属性描述符
Object.getOwnPropertyNames(obj):返回包含了obj对象所有的可枚举或不可枚举的属性名组成的字符串
如一个数组对象
let demo = [1,2,3];
console.log(Object.getOwnPropertyNames(demo));
// ['0', '1', '2', 'length']
// 将length这个不可枚举属性也输出了
Object.getOwnPropertySymbols():返回包含了obj对象自身所有的Symbol属性组成的数组
Object.getPrototypeOf(obj):返回指定对象的原型对象
Object.is(val1,val2):比较两个值是否相同,类似于'===',但是该方法判定+0和-0返回true,两个NaN也返回true
Object.freeze(obj):冻结对象,冻结以后不能删除或更改任何属性(包括原型中的属性和访问器属性),修改obj对象并返回
Object.isFrozen(obj):判断obj是否已冻结
Object.keys(obj):返回obj对象自身可枚举属性名称的数组
Object.preventExtensions(obj):将obj对象变的不可扩展(不可添加自身属性,原型中依然可以添加),修改obj对象并返回
Object.isExtensible(obj):判断obj是否可扩展
Object.seal(obj):封闭obj,禁止删除和添加属性(如果属性描述符允许修改则仍然可以修改),禁止修改属性描述符,修改obj对象并返回
Object.isSealed(obj):判断obj是否已封闭
Object.setPrototypeOf(obj):设置obj的原型
Object.values(obj):返回obj自身可枚举值的数组
实例属性
Object.prototype.constructor:一个引用值,指向Object构造函数
Object.prototype.__proto__:指向一个对象,当一个object实例化时,使用该对象作为实例化对象的原型
实例方法
Object.prototype.hasOwnProperty(key):判断一个对象自身是否包含指定的属性(不会查找原型链)
Object.prototype.isPrototypeOf(obj):判断obj对象原型链中是否含有指定对象
Object.prototype.propertyIsEnumerable(key):判断一个属性是否可枚举
Object.prototype.toLocaleString():调用toString()
Object.prototype.toString():返回一个代表该对象的字符串
Object.prototype.valueOf():返回指定对象的原始值
Map数据结构
Object本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键
let obj = {};
let item = {};
obj[item] = "demo";
obj['[object HTMLDivElement]'] // "demo"
当使用object作为键名时,会转换为字符串
ES6提供的Map数据结构类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值都可以当作键
也就是说,Object提供了“字符串 --> 值”的对应,Map提供了“值 --> 值”的对应,是一种更完善的 Hash 结构实现
Map( [val] )构造函数用来创建Map数据结构
其中val接受任何具有Iterator接口、且每个成员都是一个双元素的数组的数据结构
let map1 = new Map([[1,2],[3,4],[5,6]]);
// 使用数组初始化
let map2 = new Map({one:1,two:2});
// 使用对象初始化,报错
let map3 = new Map(map1);
// 使用Map初始化
Map中的键绑定的是内存地址
let key1= [1,2];
let key2= [1,2];
let map = new Map([
[ key1,"one" ],
[ key2,"two" ]
]);
map.get(key1); // one
map.get(key2); // two
key1和key2虽然值时一样的,但是内存地址不同,在Map中被视为两个键
Map中的键名对比类似于精确相等运算符(===),唯一不同的是Map认为NaN等于自身
Set实例的属性和方法
size 属性返回Map的成员总数
set(key, value):设置键名key对应的键值为value
返回修改后的Map
如果key已存在则键值被覆盖,否则就新生成该键名并赋值
由于返回的是修改后的Map,该方法可以链式调用
get(key):获取键名key对应的值,key不存在返回undefined
has(key):返回键名key是否存在的布尔值
delete(key):删除键值对,返回删除是否成功的布尔值
clear():清除所有键值对,没有返回值
keys():返回键名遍历器
values():返回键值遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员