JavaScript Object 對象與繼承

2018-07-24 11:51 更新

目錄

通過原型鏈,對象的屬性分成兩種:自身的屬性和繼承的屬性。JavaScript 語言在Object對象上面,提供了很多相關(guān)方法,來處理這兩種不同的屬性。

Object.getOwnPropertyNames()

Object.getOwnPropertyNames方法返回一個數(shù)組,成員是對象本身的所有屬性的鍵名,不包含繼承的屬性鍵名。

Object.getOwnPropertyNames(Date)
// ["parse", "arguments", "UTC", "caller", "name", "prototype", "now", "length"]

上面代碼中,Object.getOwnPropertyNames方法返回Date所有自身的屬性名。

對象本身的屬性之中,有的是可以枚舉的(enumerable),有的是不可以枚舉的,Object.getOwnPropertyNames方法返回所有鍵名。只獲取那些可以枚舉的屬性,使用Object.keys方法。

Object.keys(Date) // []

Object.prototype.hasOwnProperty()

對象實例的hasOwnProperty方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。

Date.hasOwnProperty('length')
// true

Date.hasOwnProperty('toString')
// false

hasOwnProperty方法是JavaScript之中唯一一個處理對象屬性時,不會遍歷原型鏈的方法。

in 運算符和 for…in 循環(huán)

in運算符返回一個布爾值,表示一個對象是否具有某個屬性。它不區(qū)分該屬性是對象自身的屬性,還是繼承的屬性。

'length' in Date // true
'toString' in Date // true

in運算符常用于檢查一個屬性是否存在。

獲得對象的所有可枚舉屬性(不管是自身的還是繼承的),可以使用for...in循環(huán)。

var o1 = {p1: 123};

var o2 = Object.create(o1, {
  p2: { value: "abc", enumerable: true }
});

for (p in o2) {console.info(p);}
// p2
// p1

為了在for...in循環(huán)中獲得對象自身的屬性,可以采用hasOwnProperty方法判斷一下。

for ( var name in object ) {
  if ( object.hasOwnProperty(name) ) {
    /* loop code */
  }
}

獲得對象的所有屬性(不管是自身的還是繼承的,以及是否可枚舉),可以使用下面的函數(shù)。

function inheritedPropertyNames(obj) {
  var props = {};
  while(obj) {
    Object.getOwnPropertyNames(obj).forEach(function(p) {
      props[p] = true;
    });
    obj = Object.getPrototypeOf(obj);
  }
  return Object.getOwnPropertyNames(props);
}

上面代碼依次獲取obj對象的每一級原型對象“自身”的屬性,從而獲取Obj對象的“所有”屬性,不管是否可遍歷。

下面是一個例子,列出Date對象的所有屬性。

inheritedPropertyNames(Date)
// [
//  "caller",
//  "constructor",
//  "toString",
//  "UTC",
//  "call",
//  "parse",
//  "prototype",
//  "__defineSetter__",
//  "__lookupSetter__",
//  "length",
//  "arguments",
//  "bind",
//  "__lookupGetter__",
//  "isPrototypeOf",
//  "toLocaleString",
//  "propertyIsEnumerable",
//  "valueOf",
//  "apply",
//  "__defineGetter__",
//  "name",
//  "now",
//  "hasOwnProperty"
// ]

對象的拷貝

如果要拷貝一個對象,需要做到下面兩件事情。

  • 確??截惡蟮膶ο螅c原對象具有同樣的prototype原型對象。
  • 確??截惡蟮膶ο螅c原對象具有同樣的屬性。

下面就是根據(jù)上面兩點,編寫的對象拷貝的函數(shù)。

function copyObject(orig) {
  var copy = Object.create(Object.getPrototypeOf(orig));
  copyOwnPropertiesFrom(copy, orig);
  return copy;
}

function copyOwnPropertiesFrom(target, source) {
  Object
  .getOwnPropertyNames(source)
  .forEach(function(propKey) {
    var desc = Object.getOwnPropertyDescriptor(source, propKey);
    Object.defineProperty(target, propKey, desc);
  });
  return target;
}

參考鏈接

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號