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);