注册 登录

清河洛

Javascript中的Object和Map

qingheluo2016-12-16清河洛576
Object是指内存中的可以被标识符引用的一块区域在JavaScript中,对象是唯一可变的值对象可以被看作是一组属性的集合属性键要么是字符串类型,要么是symbol属性值可以是任何类型的值,包括其它对象,从而可以构建复杂的数据结构创建Object类型1.new运算符var obj = new Object(); //new关键字可以省略 obj.name = 'MyName'; //创建属性字段 2.字面量方式var obj = {name : 'MyName',age : 28}; 如果属性名和值相同,可以使用简写 obj = { x, y ...

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():使用回调函数遍历每个成员


网址导航