1. 程式人生 > 實用技巧 >【JavaScript】Object 靜態方法(三)

【JavaScript】Object 靜態方法(三)

以下內容為學習記錄,可以參考 MDN 原文。

環境

  • node v12.18.1
  • npm 6.14.5
  • vscode 1.46
  • Microsoft Edge 83

概念

定義在 Object 建構函式之上的方法,稱為靜態方法(static method)。

getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor() 方法返回指定物件上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該物件的屬性,不需要從原型鏈上進行查詢的屬性)

Object.getOwnPropertyDescriptors() 方法返回指定物件所有自有屬性對應的屬性描述符。

var o, d;

o = { get foo() { return 17; } };
d = Object.getOwnPropertyDescriptor(o, "foo");
// d {
//   configurable: true,
//   enumerable: true,
//   get: /*the getter function*/,
//   set: undefined
// }

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d {
//   configurable: true,
//   enumerable: true,
//   value: 42,
//   writable: true
// }

o = {};
Object.defineProperty(o, "baz", {
  value: 8675309,
  writable: false,
  enumerable: false
});
d = Object.getOwnPropertyDescriptor(o, "baz");
// d {
//   value: 8675309,
//   writable: false,
//   enumerable: false,
//   configurable: false
// }

getOwnPropertyNames

Object.getOwnPropertyNames()方法返回一個由指定物件的所有自身屬性的屬性名(包括不可列舉屬性但不包括Symbol值作為名稱的屬性)組成的陣列。

Object.getOwnPropertySymbols() 方法返回一個給定物件自身的所有 Symbol 屬性的陣列。

var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]

// 類陣列物件
var obj = { 0: "a", 1: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]

// 使用Array.forEach輸出屬性名和屬性值
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
// 輸出
// 0 -> a
// 1 -> b
// 2 -> c

//不可列舉屬性
var my_obj = Object.create({}, {
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});
my_obj.foo = 1;

console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

getPrototypeOf

Object.getPrototypeOf() 方法返回指定物件的原型(內部 [[Prototype]] 屬性的值)。

/* eslint-disable no-new-object */
// JavaScript中的 Object 是建構函式(建立物件的包裝器)。
// 一般用法是:
const obj = new Object();

// 所以:
Object.getPrototypeOf(Object); // ƒ () { [native code] }
Object.getPrototypeOf(Function); // ƒ () { [native code] }

Object.getPrototypeOf(Object) === Function.prototype; // true

// Object.getPrototypeOf(Object)是把Object這一建構函式看作物件,
// 返回的當然是函式物件的原型,也就是 Function.prototype。

// 正確的方法是,Object.prototype是構造出來的物件的原型。
Object.prototype === Object.getPrototypeOf(obj); // true

Object.prototype === Object.getPrototypeOf({}); // true

setPrototypeOf

Object.setPrototypeOf() 方法設定一個指定的物件的原型 ( 即, 內部 [[Prototype]] 屬性)到另一個物件或 null。

警告: 由於現代 JavaScript 引擎優化屬性訪問所帶來的特性的關係,更改物件的 [[Prototype]] 在各個瀏覽器和 JavaScript 引擎上都是一個很慢的操作。其在更改繼承的效能上的影響是微妙而又廣泛的,這不僅僅限於 obj.proto = ... 語句上的時間花費,而且可能會延伸到任何程式碼,那些可以訪問任何 [[Prototype]] 已被更改的物件的程式碼。如果你關心效能,你應該避免設定一個物件的 [[Prototype]]。相反,你應該使用 Object.create() 來建立帶有你想要的 [[Prototype]] 的新物件。