is
此API为ES6新增API
Object.is() 方法判断两个值是否是相同的值 。
在ES6之前判断两个值是否相等只有==和===,现在我们多了个选择可以使用Object.is()
语法:Object.is(value1, value2);
value1 第一个需要比较的值
value2 第二个需要比较的值
返回值 表示比较结果的布尔值
1 2 3 4 5 6 7 8 9 10 11 12 13 const obj1 = {name : '张三' };console .log (Object .is (obj1, {name : '张三' })); console .log (obj1 === {name : '张三' }); console .log (obj1 == {name : '张三' }); console .log (Object .is (obj1, obj1)); console .log (obj1 === obj1); console .log (obj1 == obj1); const num1 = +0 ;console .log (Object .is (num1, -0 )); console .log (num1 === -0 ); console .log (num1 == -0 );
补充:js对于引用类型的比较实质是内存地址的比较,而不是内容的比较;对于原始类型的比较是值得比较
其实Object.is() 基本和=== 是一样的,不同的地方就是:一是+0不等于-0(在===中 +0 === -0是true),二是NaN等于自身(在===中 NaN === NaN是false)
== 的比较会先进行类型转换再进行比较,而=== 不会。这两区别在最开始学习js的时候应该是有进行了解的
assign
此API是ES6新增的API
assign() 用于将一个或多个对象的可枚举属性拷贝到目标对象,并返回目标对象
assign() 简单讲就是多个对象合并,但如果目标对象(要合入的对象)和来源对象(拷贝来源对象的属性粘贴到目标对象)有相同的key,则来源对象的key会覆盖目标对象的key,来源对象后面还有若干个来源对象,则后面的会覆盖前面的。
该操作会修改目标对象
Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用
语法:Object.assign(target, ...sources)
target 目标对象
sources 源对象
返回值 目标对象
1 2 3 4 5 6 7 8 9 const target = {name : '李白' , id : 1098 };const sources1 = {sexCode : 1 , age : 99 , id : 1010 };const sources2 = {name : '杜甫' , id : 1209 , height : 170 };const result = Object .assign (target,sources1,sources2);console .log (result); console .log (target); console .log (sources1); console .log (sources2);
1 2 3 4 5 6 7 8 9 10 11 12 13 const sources1 = {sexCode : 1 , age : 99 , id : 1010 };const sources2 = {name : '杜甫' , id : 1209 , height : 170 };const sources3 = {sources : sources2};const result2 = Object .assign (sources1,sources2,sources3);console .log (result2);sources2.weight = '68kg' ; console .log (result2);console .log (sources2);console .log (sources3);
sources3 对象的sources 属性是引用的sources2 对象,所以sources2 对象被修改,sources3 的sources 的值就会同步被修改。
sources1 对象将sources3 对象的sources 属性拷贝进去了,sources3 对象的sources 引用的是sources2 对象,所以 ,最终也就是sources1对象sources 也引用了sources2 对象,所以sources2 修改的同时,所有引用了它的(对象),都会被修改
1 2 3 4 5 6 7 8 const sources = {sexCode : 1 , id : 1010 };Object .defineProperty (sources, 'age' , { enumerable : false , value : 99 , }); console .log (sources); const result = Object .assign ({},sources);console .log (result);
sources 是源对象,我们给其设置了一个age 的不可枚举属性,使用assign() API 将其合并入一个空数组,由于age 属性是不可枚举的,所以age 并没有被assign()进行拷贝
此API在IE浏览器不支持,如果需要兼容IE浏览器,可以在js顶部添加如下代码;(如下代码来自MDN )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 if (typeof Object .assign != 'function' ) { Object .defineProperty (Object , "assign" , { value : function assign (target, varArgs ) { 'use strict' ; if (target == null ) { throw new TypeError ('Cannot convert undefined or null to object' ); } let to = Object (target); for (var index = 1 ; index < arguments .length ; index++) { var nextSource = arguments [index]; if (nextSource != null ) { for (let nextKey in nextSource) { if (Object .prototype .hasOwnProperty .call (nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, writable : true , configurable : true }); }
keys
Object.keys() 方法会返回一个由一个给定对象 的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 [`for…in` 循环遍历该对象时返回的顺序一致 。
给定对象 并非表示必须是Object类型,Array也可以使用此方法
如果给定对象是Object,返回的就是这个对象所有可枚举属性的key(键)所组成的数组;如果给定对象是一个Array,返回的就是这个数组元素索引(索引会被转成字符串)所组成的数组
语法:Object.keys(obj)
obj 要返回其枚举自身属性的对象。
返回值 一个表示给定对象的所有可枚举属性的字符串数组
1 2 3 4 5 6 7 8 9 10 11 12 const obj = {name : '李白' , sexCode : 1 , height : 170 };const arr = ['李白' , ['height' ,170 ], ['sexCode' , 1 ]];const str = 'hello world' ;const objKeys = Object .keys (obj); const arrKeys = Object .keys (arr); const strKeys = Object .keys (str); objKeys.forEach (key => { console .log (obj[key]) });
values
此API是ES8新加的,IE不支持
Object.values()方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )
Object.values() 和Object.keys() 是相对的,keys() 返回键组成的数组,value() 返回值组成的数组
语法:Object.values(obj)
obj 被返回可枚举属性值的对象。
返回值 一个包含对象自身的所有可枚举属性值的数组。
1 2 3 4 5 6 7 8 9 10 const obj = {name : '李白' , sexCode : 1 , height : 170 };const arr = ['李白' , ['height' ,170 ], ['sexCode' , 1 ]];const str = 'hello world' ;const objValues = Object .values (obj); const arrValues = Object .values (arr); const strValues = Object .values (str); const res = objValues.some (item => item === '李白' );
如过希望在低版本浏览器和IE,可以在代码起始位置写下如下内容:(如下代码来自MDN )
1 2 3 4 5 6 7 8 9 10 11 if (!Object .values ) Object .values = function (obj ) { if (obj !== Object (obj)) throw new TypeError ('Object.values called on a non-object' ); var val=[],key; for (key in obj) { if (Object .prototype .hasOwnProperty .call (obj,key)) { val.push (obj[key]); } } return val; }
entries
此API是ES8新加的,IE不支持
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)
Object.entries() 与Object.values() 和Object.keys() 可以算是一套的API,Object.values() 和Object.keys() 前文已经说了,Object.entries() 就是将这两个合起来,返回的[[key1,value1],[key2,value2]] 格式
适用: 将一个Object 转换成Map
语法:Object.entries(obj)
obj 可以返回其可枚举属性的键值对的对象。
返回值 给定对象自身可枚举属性的键值对数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const obj = {name : '李白' , sexCode : 1 , height : 170 };const arr = ['李白' , ['height' ,170 ], ['sexCode' , 1 ]];const str = 'hello world' ;const objEntries = Object .entries (obj); const arrEntries = Object .entries (arr);const strEntries = Object .entries (str);const objMap = new Map (objEntries);
兼容低版本和IE,代码起始位置写下如下内容:(如下代码来自MDN Polyfill )
1 2 3 4 5 6 7 8 9 10 if (!Object .entries ) Object .entries = function ( obj ){ var ownProps = Object .keys ( obj ), i = ownProps.length , resArray = new Array (i); while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]]; return resArray; };
fromEntries
此API在ES10草案中被提出,目前尚未写入JS标准
Object.fromEntries() 方法把键值对列表转换为一个对象
Object.fromEntries() 和 Object.entries(obj) 是相反的,Object.entries(obj) 将对象转换成键值对列表,Object.fromEntries() 则将键值对列表还原成对象
适用: 将Map 转换成Object
语法:Object.fromEntries(iterable)
iterable 可迭代对象,类似 Array 、 Map 或者其它实现了可迭代协议的对象。
返回值 一个由该迭代对象条目提供对应属性的新对象(返回一个Object)。
1 2 3 4 5 const objEntries = [["name" , "李白" ], ["sexCode" , 1 ], ["height" , 170 ]];const objMap = new Map (objEntries);const obj1 = Object .fromEntries (objEntries); const obj2 = Object .fromEntries (objMap);
此API未写入js标准,IE及Edge浏览器不支持,Chrom、Firefox、Opera以及Safari稍微低一点的版本也都不支持,不建议在生产环境使用此API
属性简洁表示法
实用度:
常用度:
属性的简洁表示在ES6中引入,它允许我们以更加简洁的方式来写属性,2019年应该没有人没用过了吧
1 2 3 4 5 6 7 8 9 10 const name = '李白' ;const sexCode = 1 ;const obj = { name, sexCode, getHeight ( ) { return 170 ; } }
属性名表达式 想象一下这个场景:在商城系统中一个订单从生成到完成,这个订单会有一系列的状态,在数据库中这个订单存的是代表状态的code码,接口给我们返回的也是code码,前端如何来处理将code码转换成汉字状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const state = { 'A' : '未付款' , 'B' : '待发货' , 'C' : '已发货' , 'D' : '已完成' , 'E' : '已评价' , } console .log (state.A ); const key = 'A' ;console .log (state[key]);
完成示例
1 2 3 4 5 6 7 8 const key = 'state' ;const state = { [key]: '状态' , ['A' + 'B' ]: '未付款但已发货' , [`${key} A` ]: '状态未付款' } console .log (state);
其他(不常用) freeze
Object.freeze() 方法可以冻结 一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
Object.freeze() 相当于将一个对象变为只读状态;但是如果这个对象的某个属性的值还是一个对象(A),则这个A可读可写,除非这个A也是冻结状态;数组作为一种对象,被冻结,其元素也不能被修改,即这个数组元素不能被删除,也不能在添加
语法:Object.freeze(obj)
1 2 3 4 5 6 const people = { name : '李白' } Object .freeze (people);people.age = 102 ; console .log (people);
isFrozen
Object.isFrozen()方法判断一个对象是否被冻结。
语法:Object.isFrozen(obj)
obj 被检测的对象
返回值 Boolean 检测结果
1 2 3 4 5 6 7 8 9 const people = { name : '李白' } let res = Object .isFrozen (people); console .log (res)Object .freeze (people);res = Object .isFrozen (people); console .log (res);
seal
1 2 3 4 5 6 7 const people = { name : '李白' } Object .seal (people);people.age = 102 ; people.name = '杜甫' ; console .log (people);
isSealed
Object.isSealed() 方法判断一个对象是否被密封。
语法:Object.isSealed(obj)
obj 要被检查的对象。
返回值 Boolean 检测结果
1 2 3 4 5 6 7 8 9 const people = { name : '李白' } let res = Object .isSealed (people); console .log (res)Object .seal (people);res = Object .isSealed (people); console .log (res);