对象的方法

149 阅读7分钟

1. Object.assign()通过赋值一个或多个对象来创建一个新的对象。

Object.assign()方法用于对象的合并,将源对象的所有可枚举属性(obj,object),复制到目标对象(target)。Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。

  var target = {a:1};
  var obj = {b:2};
  var object = {c:3};
  Object.assign(target,obj,object);            
  target;          //{a:1,b:2,c:3}

如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

  var target = {a:1,b:2};
  var obj = {b:3,c:4};
  var object = {c:5};
  Object.assign(target,obj,object);
  target;          //{a:1,b:3,c:5}

如果只有一个参数,Object.assign会直接返回该参数。

  var obj = {a:1};
  Object.assign(obj) === obj;      //true

如果该参数不是对象,会先转成对象,然后返回。

  typeof Object.assign(2)          //object

2. Object.create()使用指定的原型对象和属性创建一个新对象。

 Object.create(proto)
  
 //proto->新创建对象的原型对象
 
 

   var obj = Object.create({})
   obj.name;          //undefined
   Object.prototype.name = 'aaa';
   obj.name;          //aaa
   
   
   //使用Object.create(null)创建新对象,防止Object构造函数的原型被修改时对新建的对象产生影响。
   var obj = Object.create(null);
   obj.name           //undefined
   obj.prototype.name = 'aaa';
   obj.name;          //undefined

 
Object.create(proto,propertiesObject)

 //propertiesObject(可选)->添加到新创建对象的属性名及其属性描述符
 

   var obj = Object.create({},{
     name:{
       vale:'aaa',               // 该属性对应的值
       writable:true,            //true 可以被赋值运算符改变
       configurable:true,        //true 该属性能被改变,也能被删除
       enumerable:true           //true 该属性能出现在对象的枚举属性中
       }
   })
   obj.name;           //aaa

3. Object.defineProperty()给对象添加一个属性并指定该属性的配置。

Object.defineProperty()详解

4. Object.defineProperties()给对象添加多个属性并分别指定他们的配置。

与Objdect.defineProperty()相似。Objdect.defineProperty()只能给对象添加一个属性并指定该属性的配置,Object.defineProperties()能给对象添加多个属性并分别指定他们的配置。

语法:Object.defineProperties(obj,props)

//obj->将要被添加属性或修改属性的对象。

//props->该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置

  var obj = new Object()
  Object.defineProperties(obj,{
     name:{
       value:'李四',
       configurable:false,
       writable:false,
       enumerable:false
     },
     age:{
       value:18,
       configable:true
     }
  })
  
  console.log(obj.name,obj.age)     //张三,18
  
  //configurable:仅当该属性的值为true时,该属性才能被改变,也能被删除。默认为false
  //enumerable:仅当该属性的值为true时,该属性才能够出现在对象的枚举属性中。默认未false
  //value:该属性对应的值。默认是undefined
  //writable:仅当该属性的值为true时,该属性才能被赋值运算符改变。默认是false

5. Object.entries()返回给定对象自身可枚举属性的[key,value]数组。

Object.entries()可以把一个对象的键值以数组的形式遍历出来,结果和for...in一致,但不会遍历原型属性。

   //传入对象
   const obj = {a:'bar',b:'abc'};
   console.log(Object.entries(obj));          //[['a','bar'],['b','abc']]
   
   
   //传入数组
   const arr = [1,2,3];
   console.log(Object.entries(arr));          //[['0','1'],['1','2'],['2','3']]
   
   
   //传入数组(数组中包含对象)
   const arr = [{a:1},2,3];
   console.log(Object.entries(arr));          //[['0',{a:1}],['1','2'],['2','3']]
   
   
   //数组(数组中的值全部是对象)
   const arr = [{a:1},{b:2},{c:3}];
   console.log(arr);                           //[['0',{a:1}],['1':{b:2}],['2':{c:3}]]
   
   
   //字符串
   const str = '123';
   console.log(Object.entries(str));           //[['0','1'],['1','2'],['2','3']]
   
   
   //数字、浮点数
   const num = 123;
   console.log(Object.entries(num));           //[]
   
   const float = 12.3;
   console.log(Object.entries(float));         //[]
   
   
   //将object转化为Map
   //new Map()构造函数接受一个可迭代的entries.借助Object.entries方法可以将Object转换成Map
   const obj = {foo:'bar',baz:'abc'};
   console.log(Object.entries(obj));           //[['foo','baz'],['bar','abc']]
   
   const Map = new Map(Object.entries(obj));
   console.log(Map);                           //Map{'foo'=>'bar','baz'=>'abc'}
   

Object.entries()可以把一个对象的键值以数组的形式遍历出来,结果和for...in遍历循环该对象时返回的结果一样,但是不会遍历其原型属性。

6. Object.freeze()冻结对象:其他代码不能删除或更改任何属性。

Object.freeze()这个函数的作用是将对象进行冻结,封装好的对象如果不希望后续进行修改,就可以使用这个函数进行冻结。

被冻结的对象有以下几个特性:

1)不能添加新属性

2)不能删除已有属性

3)不能删除已有属性的值

4)不能修改原型

5)不能修改已有属性的可枚举性、可配置性、可写性

  //----- 冻结数组 -----
  const obj = {pro:42};
  const object = Object.freeze(obj);
  
  //不能修改已有属性的值
  object.pro = 10;
  console.log(object.pro);           //42
  
  //不能添加新属性
  object.sex='男'
  console.log(object)                //{pro:42}
  
  //不能删除原有属性
  delete object.pro;
  console.log(object);               // {pro:42}
  
  
  //----- 冻结数组 -----
  var arr = [1,2,3,4,5]
  Object.freeze(arr);
  arr[0] = '新增'console.log(arr);                  //[1,2,3,4,5]
  
  
  //----- 浅冻结 -----
  var obj = {
    name:'张三',
    info:{
      a:1b:2
    }
  }
  Object.freeze(obj);
  obj.name = '李四'
  console.log(obj);                //{name:'张三',{info:a:1,b:2}}
  obj.info.a = 66;
  console.log(obj.info)            //{a:66,b:2}
  
  
  //----- 深冻结 -----
  var obj = {
    name:'张三',
    info:{
      a:1b:2
    }
  }
  function deepFreeze(obj) {
    //获取所有属性
    var proprNames = Object.getOwnPropertyNames(obj);
    
    //遍历
    propsName.forEach(item=> {
       var propr = obj[item];
       //如果某个属性的属性值是对象,则递归调用
       if(prop instanceof Object && propr !== null){
         deepFreeze(prop)
       }
    })
    
    //冻结自身
    return Object.freeze(obj)
  }
  deepFreeze(obj)
  obj.name = '李四'
  console.log(obj)             //{name:'张三',info:{a:1,b:2}}
  obj.info.a = 20;
  console.log(obj.info);       //{a:1,b:2}

7. Object.getOwnPropertyDescriptor()返回对象指定的属性配置。

   const dog = {}
   Object.defineProperty(dog,{
      breed:{
        value:'1'
      }
   })
   Object.getOwnPropertyDescriptor(dog,'breed')
   /*
      {
        value:'1',
        writable:false,
        enumerable:false,
        configurable:false
      }
   */
   
   
   const obj = {a:42};
   d = Object.getOwnPropertyDescriptor(obj,'a');
   /*
      {
        value:'42',
        writable:true,
        enumerable:true,
        configurable:true
      }
   */

8. Object.getOwnPropertyNames()返回一个数组,它包含了指定对象所有可枚举或不可枚举的属性名。

大部分情况下Object.getOwnPropertyNames()与Object.keys(obj)功能一样。

Object.keys()会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。

共同点:都是返回自身的属性,不会返回原型链上的

不同点:Object.keys()返回可枚举的,Object.getOwnPropertyNames()返回所有的。

  var obj = {name:'张三'}
  obj.age = 18;
  Object.definProperties(obj,{
    age:{
       enumerable:flase
    }
  })
  
  console.log(Object.keys(obj));                      //['name']
  console.log(Object.getOwnPropertyNames(obj));       //['name','obj']

9. Object.keys()返回一个包含所有给定对象自身可枚举属性名称的数组

   //处理对象,返回可枚举的属性数组
   const person = {
     name:'张三',
     age:25,
     address:'山东省济南市',
     getName:function(){}
   }
   Object.keys(person)                 //['name','age','address','getName']
   
   
   //处理数组,返回索引值数组
   const arr = [1,2,3,4,5,6]
   Object.keys(arr)                     //['0','1','2','3','4','5']
   
   
   //处理字符串,返回索引值数组
   const str = '字符串'
   Object.keys(str)                     //['0','1','2']
   
   
   //构造函数,返回空数组或者属性名
   function Demo(name,age) {
     this.name = name;
     this.age = age;
   }
   console.log(Object.keys(Demo))        //[]

10. Object.is()比较两个值是否相同。所有NaN值都相等(与==和===不同)。

Object.is()方法判断两个值是否为同一个值,如果满足以下任意条件则两个值相等: 1)都是undefined 2)都是null 3)都是true或都是false 4)都是相同长度、相同字符、按相同顺序排列的字符串 5)都是相同对象 6)都是数字且都是+0、-0、NaN、都是同一个值,非零且都不是NaN

Object.is()与==不同。==运算符在判断相等前对两边的变量(如果他们不是同一类型)进行强制转换,而Object.is()不会强制转换两边的值。

Object.is()与===也不相同。差别是他们对待有符号的零与NaN不同,===/==运算符将数字-0和+0视为相等,而将Number.NaN与NaN视为不相等。

  Object.is(25,25)                      //true
  Object.is('obj','obj')                //true
  Object.is('obj','foo')                //false
  Object.is(null,null)                  //true
  Object.is(undefined,undefined)        //true
  Object.is([],[])                      //false
  const foo = {a:1};
  const obj = {a:1}
  Object.is(foo,foo);                   //true
  Object.is(foo,obj)                    //false
  Object.is(0,-0)                       //false

11. Object.values()返回给定对象自身可枚举值的数组。

Object.values()返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

   const obj = {foo:'bar',num:10}
   console.log(Object.values(obj))            //['bar',42]
   
   const obj = {0:'a',1:'b',2:'c'}
   console.log(Object.values(obj))            //['a','b','c']
   
   const obj = {100:'a',10:'b',20:'c'}
   console.log(Object.values(obj))             //['b','c','a']