Object-API—01

new 一个对象,查看它原型的构造函数:

 接下来一个一个说:

(1)Object.assign()——ES6

Object.assign()方法用于对象的合并,将源对象(第一个参数)的所有可枚举属性,复制到目标对象(后面所有参数)。即将其他对象的属性复制到某个对象中

1 const obj = {a:1}
2 const obj01 = {b:2}
3 const obj02 = {c:3}
4 Object.assign(obj,obj01,obj02)
5 console.log(obj);  // {a: 1, b: 2, c: 3}

注意:

  • 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
  • 如果只有一个参数,Object.assign()会直接返回该参数
  • 由于undefinednull无法转成对象,所以如果它们作为参数,就会报错。这两个不是出现在第一个目标对象时,处理规则有所不同。这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefinednull不在首参数,就不会报错。
  • 其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
    • 1 const v1 = 'abc';
      2 const v2 = true;
      3 const v3 = 10;
      4 
      5 const obj = Object.assign({}, v1, v2, v3);
      6 console.log(obj); // { "0": "a", "1": "b", "2": "c" }
    • 上面代码中,v1v2v3分别是字符串、布尔值和数值,结果只有字符串合入目标对象(以字符数组的形式),数值和布尔值都会被忽略。这是因为只有字符串的包装对象,会产生可枚举属性。
    • 1 Object(true) // {[[PrimitiveValue]]: true}
      2 Object(10)  //  {[[PrimitiveValue]]: 10}
      3 Object('abc') // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
    • 上面代码中,布尔值、数值、字符串分别转成对应的包装对象,可以看到它们的原始值都在包装对象的内部属性[[PrimitiveValue]]上面,这个属性是不会被Object.assign()拷贝的,只有字符串的包装对象,会产生可枚举的实意义属性,那些属性则会被拷贝
  • Object.assign()拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。
    • 1 Object.assign({b: 'c'},
      2   Object.defineProperty({}, 'invisible', {
      3     enumerable: false,
      4     value: 'hello'
      5   })
      6 )
      7 // { b: 'c' }
  • 属性名为 Symbol 值的属性,也会被Object.assign()拷贝。

(2)Object.create()

用于在没有构造函数的情况下,也能创建子对象

语法:

const 子对象名 = Object.create(父对象)

 create()创建出来的新对象的__proto__被自动设置为create()的参数,也就是自动继承了父对象了

 1 const son = Object.create(father,{
 2     // 这里的格式与Object.defineProperties中格式一样
 3     name: {
 4         value: "张三",
 5         writable:true,
 6         enumerable:true,
 7         configurable:true
 8     },
 9     age:{
10         value:26,
11         writable:true,
12         enumerable:true,
13         configurable:true
14     }
15 })
16 
17 console.log(son.type);  //
18 console.log(son.name);  // 张三
19 console.log(son.age);  // 26

说明:

  • create()第二个参数可选,不填就是创建一个空的子对象

(3)Object.defineProperty() & Object.defineproperties()

①Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

1 const obj ={}
2 Object.defineProperty(obj,'name',{
3     value: '张三',
4     writable:true,
5     enumerable:true,
6     configurable:true
7 })
8 console.log(obj);  //{name: "张三"}

说明:

  • value:定义的属性的值
  • writable:属性是否可被修改
  • enumerable:是否可被枚举(无法被for...in..获取到,但是可以直接访问)
  • configurable:控制是否可以修改writable和enumerable
  • 还有另外两个可选键值:get & set :可用于控制属性的修改时控制,vue双向绑定就是基于Object.defineproperty这个方法
    •  1 const obj ={}
       2 let val = ""
       3 
       4 Object.defineProperty(obj,'name',{
       5     enumerable:true,
       6     configurable:true,
       7     get(){
       8         console.log("get:",val);
       9         return val
      10     },
      11     set(newVal){
      12         console.log("set:",newVal);
      13         val=newVal
      14     }
      15 })
      16 
      17 val="赵四"
      18 obj.name=val  // set
      19 console.log(obj.name);  // get

②Object.defineproperties用于同时在对象上定义多个属性,用法与defineproperty类似

 1 var obj = {};
 2 Object.defineProperties(obj, {
 3   'property1': {
 4     value: true,
 5     writable: true
 6   },
 7   'property2': {
 8     value: 'Hello',
 9     writable: false
10   }
11   // etc. etc.
12 });

(4)Object.entries()/Object.fromEntries() & Object.keys() & Object.values()  —ES6

作用与数组的这三个同名办法相同,都是用来遍历对象的

①Object.entries()返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

1 const obj = { foo: 'bar', baz: 42 };
2 Object.entries(obj)

②Object.fromEntries()是Object.entries的逆操作,用于将一个键值对数组转换为对象

1         let obj = Object.fromEntries([
2             ['a', 1], ["b", 2]
3         ])
4         console.log(obj);  // {a: 1, b: 2}

该方法的主要目的,是将键值对的数据结构还原为对象,因此特别适合将 Map 结构转为对象。

③Object.keys()返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

1 var obj = { foo: 'bar', baz: 42 };
2 Object.keys(obj)
3 // ["foo", "baz"]

④Object.values()回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。

1 const obj = { foo: 'bar', baz: 42 };
2 Object.values(obj)
3 // ["bar", 42]

(5)Object.preventExtensions() & Object.seal() & Object.freeze() 

这三个属性都是用来控制对象的扩展
①Object.preventExtensions():禁止给对象添加新属性

const obj ={ 
    name:"张三",
    age: 26
 }

 Object.preventExtensions(obj)

 obj.sex = 1
 console.log(obj);  // {name: "张三", age: 26}  

说明:

  • 这里没有使用严格模式,所以默认是修改失败的。严格模式下会报错:Uncaught TypeError: Cannot add property sex, object is not extensible

原理:

  每个对象内部有一个内部属性extensible = true。此方法就是将对象的内部属性extensible = false

②Object.seal():禁止添加新属性禁止删除现有属性

 1 const obj ={ 
 2     name:"张三",
 3     age: 26
 4  }
 5 
 6  Object.seal(obj)
 7 
 8  obj.sex = 1
 9  console.log(obj);  // {name: "张三", age: 26}
10  delete obj.age
11  console.log(obj);  // {name: "张三", age: 26}

说明:

  • 同样是在严格模式下会报错

原理:

  • extensible = false
  • configurable = false

③Object.freeze():禁止添加删除属性,不能修改任何属性值

 1 const obj ={ 
 2     name:"张三",
 3     age: 26
 4  }
 5 
 6  Object.freeze(obj)
 7 
 8  obj.sex = 1
 9  console.log(obj);  // {name: "张三", age: 26}
10  delete obj.age
11  console.log(obj);  // {name: "张三", age: 26}
12  obj.name = "李四"
13  console.log(obj);  // {name: "张三", age: 26}

说明:

  • 同样的,需要开启严格模式才会报错

原理:

  • extensible = false
  • configurable = false 
  • writable = false

(6)Object.getOwnPropertyDescriptor()

Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自由属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

1 const obj = {
2     name : "张三"
3 }
4 const desc = Object.getOwnPropertyDescriptor(obj,'name')
5 
6 console.log(desc);  // {value: "张三", writable: true, enumerable: true, configurable: true}

说明: 

  • 如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回 undefined
  • 可以获取的属性有:
    • writable
    • enumerable
    • configurable
    • value
    • get
    • set
      • get和set这两个访问器函数,只有在定义了才有,否则是undefined

注意:

  • 在 ES5 中,如果该方法的第一个参数不是对象(而是原始类型),那么就会产生出现 TypeError。而在 ES6,第一个的参数不是对象的话就会被强制转换为对象。

(7)Object.getOwnPropertyDescriptors()——ES6

Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的描述对象。

 1 const obj = {
 2   foo: 123,
 3   get bar() { return 'abc' }
 4 };
 5 
 6 Object.getOwnPropertyDescriptors(obj)
 7 // { foo:
 8 //    { value: 123,
 9 //      writable: true,
10 //      enumerable: true,
11 //      configurable: true },
12 //   bar:
13 //    { get: [Function: get bar],
14 //      set: undefined,
15 //      enumerable: true,
16 //      configurable: true } }

 上面代码中,Object.getOwnPropertyDescriptors()方法返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象。

 此方法的实现

该方法的引入目的,主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。

Object.getOwnPropertyDescriptors()方法的另一个用处,是配合Object.create()方法,将对象属性克隆到一个新对象。这属于浅拷贝

1         const obj = {name:"张三"}
2         const clone = Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj))
3 
4         console.log(obj === clone);  // false

 说明:

  • getPrototypeOf()方法返回指定对象的原型
  • Object.getOwnPropertyDescriptors(obj)相当于直接获取自身属性当作第二个参数

 - 另外,Object.getOwnPropertyDescriptors()方法可以实现一个对象继承另一个对象。以前,继承另一个对象,常常写成下面这样。

1 const obj = {
2   __proto__: prot,
3   foo: 123,
4 };

ES6 规定__proto__只有浏览器要部署,其他环境不用部署。如果去除__proto__,上面代码就要改成下面这样。

 1 const obj = Object.create(prot);
 2 obj.foo = 123;
 3 
 4 // 或者
 5 
 6 const obj = Object.assign(
 7   Object.create(prot),
 8   {
 9     foo: 123,
10   }
11 );

 有了Object.getOwnPropertyDescriptors(),我们就有了另一种写法。

1 const obj = Object.create(
2   prot,
3   Object.getOwnPropertyDescriptors({
4     foo: 123,
5   })
6 );

 (8)Object.getOwnPropertyNames()

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

Object.getOwnPropertyName()返回一个数组,该数组对元素是obj自身拥有的枚举或不可枚举属性名称字符串。数组中枚举属性的顺序与通过for...in...循环(或Oject.keys)迭代对象属性时一致。

 1 var arr = ["a", "b", "c"];
 2 console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
 3 
 4 // 类数组对象
 5 var obj = { 0: "a", 1: "b", 2: "c"};
 6 console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
 7 
 8 // 使用Array.forEach输出属性名和属性值
 9 Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
10   console.log(val + " -> " + obj[val]);
11 });
12 // 输出
13 // 0 -> a
14 // 1 -> b
15 // 2 -> c
16 
17 //不可枚举属性
18 var my_obj = Object.create({}, {
19   getFoo: {
20     value: function() { return this.foo; },
21     enumerable: false
22   }
23 });
24 my_obj.foo = 1;
25 
26 console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

 如果你只要获取到可枚举属性,可以使用Object.keys或用for...in循环(还会获取到原型链上的可枚举属性,不过可以使用hasOwnProperty()方法过滤掉)。

原文地址:https://www.cnblogs.com/codexlx/p/14311749.html