es6對象筆記

object.is()判斷兩個值是否相等

  • es5中經過==和===判斷兩個值是否相等,可是卻沒法判斷NaN、-0、+0; NaN不等於自身,-0等於+0;
Object.is(NaN, NaN); //true;
Object.is(-0, +0); //false
  • es5能夠經過一下代碼來部署Object.is:
Object.defineProperty(Object, 'is', {
  value: function(x, y) {
    if (x === y) {
      // 針對+0 不等於 -0的狀況
      return x !== 0 || 1 / x === 1 / y;
    }
    // 針對NaN的狀況
    return x !== x && y !== y;
  },
  configurable: true,
  enumerable: false,
  writable: true
});

Object.assign(target,...source1)

  • 該方法用於合併對象,將源對象(source)的可枚舉屬性加到target上
  • 不可枚舉的屬性和源對象的繼承屬性都是不會複製到目標對象上
  • 若是target與源對象(source)有同名屬性,或多個源對象有同名屬性,則後面的屬性會覆蓋前面的屬性。
  • 關於參數,其餘基礎類型的數據只有字符串的包裝類對象會產生克枚舉的屬性
  • 注意:淺拷貝
Object.assign({
name:'zhan'
},'test')
// {0: "t", 1: "e", 2: "s", 3: "t", name: "zhan"}
  • 數組處理:
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
  • 克隆對象:
function cloneObj (obj) {
return Object.assign({}, obj);
}
// 若是要保持克隆的對象的繼承性
function cloneObj (obj) {
let proto = Object.getPrototypeOf(obj);
return Object.assign(Object.creat(proto), obj);
}
  • 設置默認的屬性
const DEFAULTS = {
  logLevel: 0,
  outputFormat: 'html'
};

function processContent(options) {
  options = Object.assign({}, DEFAULTS, options);
  console.log(options);
  // ...
}
  • 取值函數的處理
// Object.assign只能進行值的複製,若是要複製的值是一個取值函數,那麼將求值後再複製。
// source對象的foo屬性是一個取值函數,Object.assign不會複製這個取值函數,只會拿到值之後,將這個值複製過去
const source = {
  get foo() { return 1 }
};
const target = {};

Object.assign(target, source)
  • 關於對象屬性遍歷:html

    1. for...in數組

      • for...in循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
    2. Object.keys(obj)函數

      • Object.keys返回一個數組,包括對象自身的(不含繼承的)全部可枚舉屬性(不含 Symbol 屬性)的鍵名。
    3. Object.getOwnPropertyNames(obj)this

      • Object.getOwnPropertyNames返回一個數組,包含對象自身的全部屬性(不含 Symbol 屬性,可是包括不可枚舉屬性)的鍵名。
    4. Object.getOwnPropertySymbols(obj)es5

      • Object.getOwnPropertySymbols返回一個數組,包含對象自身的全部 Symbol 屬性的鍵名。
    5. Reflect.ownKeys(obj)prototype

      • Reflect.ownKeys返回一個數組,包含對象自身的全部鍵名,無論鍵名是 Symbol 或字符串,也無論是否可枚舉。
  • 以上的 5 種方法遍歷對象的鍵名,都遵照一樣的屬性遍歷的次序規則。code

    1. 首先遍歷全部數值鍵,按照數值升序排列。
    2. 其次遍歷全部字符串鍵,按照加入時間升序排列。
    3. 最後遍歷全部 Symbol 鍵,按照加入時間升序排列。

Object.getOwnPropertyDescriptors()

  • ES2017 引入了Object.getOwnPropertyDescriptors方法,返回指定對象全部自身屬性(非繼承屬性)的描述對象
  • Object.getOwnPropertyDescriptor(obj,prop) 獲取目標對象的某個自身屬性(非繼承屬性)的描述對象
  • 主要是爲了解決Object.assign()沒法正確拷貝get屬性和set屬性的問題。
  • 使用見下例子:
const source = {
  set foo(value) {
    console.log(value);
  }
};

const target1 = {};
Object.assign(target1, source);

Object.getOwnPropertyDescriptor(target1, 'foo')
// { value: undefined,
//   writable: true,
//   enumerable: true,
//   configurable: true }

//若是採用Object.defineProperties()和Object.getOwnPropertyDescriptors()將源對象的屬性(非繼承)添加到目標對象上
Object.defineProperties(target1,Object.getOwnPropertyDescriptors(source))
Object.getOwnPropertyDescriptor(target1, 'foo')
// { get: undefined,
  //   set: [Function: set foo],
  //   enumerable: true,
  //   configurable: true }

Object.create(proto [...prop]); es5

  • proto:建立對象的原型orm

  • 第二參數是對象的描述對象htm

  • 結合Object.create複製對象,且保持繼承性,見代碼:對象

let obj = {
name: 'zhan'
}
let obj1 = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj))

// 第二種:
let obj1 = Object.assign(Object.create(Object.getPrototypeOf(obj)),obj)

Object.setPrototypeOf(object, prototype)(寫操做)

  • 設置目標對象的原型

Object.getPrototypeOf(obj)(讀操做)

  • 獲取目標對象的原型

super關鍵字

  • 指向當前對象的原型對象
const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};

Object.setPrototypeOf(obj, proto);
obj.find()  // hello
//super.foo等同於Object.getPrototypeOf(this).foo(屬性)
或Object.getPrototypeOf(this).foo.call(this)(方法)。
  • super關鍵字表示原型對象時,只能用在對象的方法之中,只有對象方法的簡寫法能夠讓 JavaScript 引擎確認,定義的是對象的方法。
// 報錯
const obj = {
  foo: () => super.foo
}

// 報錯
const obj = {
  foo: function () {
    return super.foo
  }
}
//只有以下對象方法的簡寫才正確
const obj = {
  foo () {
    return super.foo
  }
}

Object.keys(),Object.values(),Object.entries()

  • 都忽略對象的繼承屬性
  • Object.keys() 返回對象屬性的鍵值對名數組
  • Object.values() 返回對象屬性的鍵值對值數組
  • Object.entries() 返回對象屬性的鍵值對數組

對象擴展運算符...

  • 結合結構賦值
    • 注意:解構賦值必須是最後一個參數
    • 解構賦值的拷貝是淺拷貝
    • 擴展運算符的解構賦值,不能複製繼承自原型對象的屬性
例子1:
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }

例子2:
let { ...x, y, z } = obj; // 句法錯誤
let { x, ...y, ...z } = obj; // 句法錯誤

例子3:
let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b // 2

例子4:
let o1 = { a: 1 };
let o2 = { b: 2 };
Object.setPrototypeOf(o2,o1)
// o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined
相關文章
相關標籤/搜索