1. 程式人生 > >ES6 物件的擴充套件

ES6 物件的擴充套件

1、Object.assign()

方法用於將所有可列舉屬性的值從一個或多個源物件複製到目標物件。它將返回目標物件。
注意該方法實行的是淺拷貝,而不是深拷貝。

const object1 = {
  a: 1,
  b: 2,
  c: 3
};
const object2 = Object.assign({c: 4, d: 5}, object1);
//{c: 3, d: 5, a: 1, b: 2}

用途很多;
1、為物件新增屬性

class Point {
  constructor(x, y) {
    Object.assign(this, {x, y}
); } }

2、合併多個物件

const merge =  (target, ...sources) => Object.assign(target, ...sources);

如果希望合併後返回一個新物件,可以改寫上面函式,對一個空物件合併。

const merge = (...sources) => Object.assign({}, ...sources);

2、Object.is()

它用來比較兩個值是否嚴格相等,與嚴格比較運算子(===)的行為基本一致。
不同之處只有兩個:一是+0不等於-0,二是NaN等於自身。

+0 === -0 //true
NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true

3、Object.key() 、Object.values()、Object.entries()

這3個都會返回一個數組

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

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

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

結合for…of使用

let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };

for (let key of keys(obj)) {
  console.log(key); // 'a', 'b', 'c'
}

for (let value of values(obj)) {
  console.log(value); // 1, 2, 3
}

for (let [key, value] of entries(obj)) {
  console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}

4、Object.create()

Object.create()方法建立一個新物件,使用現有的物件來提供新建立的物件的__proto__

Object.create(proto, [propertiesObject])

方法接受兩個引數
proto新建立物件的原型物件;
propertiesObject可選。如果沒有指定則為undefined,則是要新增到新建立物件的可列舉屬性;
返回一個新物件,帶著指定的原型物件和屬性。
廢話不多說,上例子;

var Car = function(){
     this.name  = 'car';
     this.color = 'gray'
 }
 Car.prototype = {
     getInfo(){
         return 'name:' + this.name + ' color:' + this.color
     }
 }
 var child = Object.create(Car.prototype, {
     color: {
         writable: false,       // 是否是可改寫的
         configurable:true,    // 是否能夠刪除,是否能夠被修改
         value: 'red',
         enumerable:true       //是否可以用for in 進行列舉
     },
     gender: {
         configurable:true,
         get:function () {  
             return "我是男的";    // 獲取物件 gender 屬性時觸發的方法
         },  
         set:function (value) {  // 設定物件 gender 屬性時觸發的方法 
             console.log(value);
             return value;
         }    
     }
 })

 console.log(child.getInfo())   //name:undefined color:red
 console.log(child.gender)      //觸發get

 child.gender = '我是女的';      //觸發set

首先我們來看看Object.create時發生了什麼?
Object.create()方法建立一個新物件,並使用現有的物件來提供新建立的物件的__proto__,其原理如下;

Object.create = function(obj){
	function F(){}
	F.prototype = obj
	return new F()
}

上上程式碼中child.name == undefined,是因為Object.create內部的新物件是new F()建立的,跟Car建構函式沒有關係,想要獲取name的值,改成 new Car(),就可以了。

var newCar = new Car()
var child = Object.create(newCar, {
     color: {
         writable: true,       // 是否是可改寫的
         configurable:true,    // 是否能夠刪除,是否能夠被修改
         value: 'red',
         enumerable:true       //是否可以用for in 進行列舉
     },
     gender: {
         configurable:true,
         get:function () {  
             return "我是男的";    // 獲取物件 gender 屬性時觸發的方法
         },  
         set:function (value) {  // 設定物件 gender 屬性時觸發的方法 
             console.log(value);
             return value;
         }    
     }
 })
 console.log(newCar.isPrototypeOf(child));  //true

其實相當於實現了原型繼承方式(注意不是原型鏈繼承),本質上來說是對一個物件進行了淺拷貝。