前端面試題系列 - 繼承

大概會用一個系列,講一下面試過程當中常常會問的一些問題,以及我以爲應該能夠怎麼回答。面試

固然,個人回答也並非標準答案,只是我本身的一些理解,也歡迎其餘人發表本身的想法。函數

做爲本系列的第一篇文章,就先講講被問的最多的 js 繼承問題,可是應該不會寫原型鏈相關的東西,測試

先列舉一個最簡單的問題:es5

寫一個 inherit(superClass, subClass) 方法,實現 subClass 繼承 superClass

題目隱含的內容

繼承有哪些特徵,如何檢測一個繼承是否成功?
  1. 子類可使用父類的方法和屬性
  2. 子類能夠自定義方法和屬性,但應該不影響父類和其餘繼承同一個父類的子類
  3. 子類的原型鏈上能夠找到父類(子類的__proto__應指向父類)
  4. 子類的實例能夠經過 foo instanceof superClass 測試

常見的解法

es5
function inherit(p, s) {
  s.prototype = Object.create(p.prototype, {
    constructor: {
      value: s,
      enumerable: false,
      writebale: true,
      configurable: true
    }
  })

  Object.setPrototypeOf ? Object.setPrototypeOf(s, p) : s.__proto__ = p
}
es4
function inherit(p, s) {
  var f = new Function ()
  f.prototype = new p()
  var r = new f()
  s.prototype = r
  s.prototype.constructor = s
  s.__proto__ = p
  f = null
  r = null
}

引伸的問題:

  1. Object.create 是什麼?怎麼使用?
Object.create(proto, [propertiesObject])

Object.create 提供了一個建立對象的方法,使用現有的對象做爲新建立對象的__proto__,同時能夠傳入添加到新對象的可枚舉屬性, 這些屬性能夠對應到Object.defineProperties 的第二個參數中。prototype

返回值爲所建立的新對象.code

例如:對象

s.prototype = Object.create(f.prototype, {
  constructor: {
    value: s,
    enumberable: false,
    writealble: true,
    configurale: true
  }
})
  1. Object.defineProperties 是什麼?怎麼使用?能夠列舉一個 Object.definProperties 的實際應用嗎?

Object.defineProperties能夠直接在一個對象上定義或修改屬性,並返回該對象。繼承

例如:ip

target = Object.defineProperties(target, props)

本質上 Object.defineProperties 是對Object.defineProperty 的集中調用,能夠理解爲是Object.definePeropety的複數版。原型鏈

Object.defineProperty 的使用方法爲:

target = Object.defineProperty(target, prop, descriptor)

因此本質上Object.defineProperties 就是以下代碼:

Object.keys(props).forEach(function (prop) {
  let descriptor = props[prop]
  Object.defineProperty(target, prop, descriptor)
})

其中 descriptor 的可選值有如下集中:

  • configurable: 當且僅當該屬性的 configurable 爲 true 時,該屬性描述符纔可以被改變,同時該屬性也能從對應的對象上被刪除。默認爲 false
  • enumerable: 當且僅當該屬性的enumerable爲 true 時,該屬性纔可以出如今對象的枚舉屬性中。默認爲 false
  • value: 該屬性對應的值。能夠是任何有效的 JavaScript 值(數值,對象,函數等)。默認爲 undefined
  • writable: 當且僅當該屬性的writable爲true時,value才能被賦值運算符改變。默認爲 false。
  • get: 一個給屬性提供 getter 的方法,若是沒有 getter 則爲 undefined。該方法返回值被用做屬性值。默認爲 undefined
  • set: 一個給屬性提供 setter 的方法,若是沒有 setter 則爲 undefined。該方法將接受惟一參數,並將該參數的新值分配給該屬性。默認爲 undefined

若是一個 descriptor 不具備 value, writebale, getset 任意一個關鍵字,那麼將會被認爲是一個數據描述符。
若是一個描述符同時具備(valuewritbale)和(getset),將會產生一個異常.

  1. 繼承多個父類怎麼作?

繼承多個父類的話,可使用 Object.assign 方法。
例如:

targe = Object.assign({}, superClassA, superClassB, ...)

可是繼承多個父類的話,子類就不能經過 son instanceof superClass 這樣的驗證了.

  1. Object.assign 是什麼?怎麼用?用的時候有哪些須要注意?

Object.assign 方法用於將全部可枚舉屬性從一個或多個源對象複製到目標對象,並返回目標對象,例如:

target = Object.assign(target, source)

若是具備同名屬性,那麼在後面對象中的屬性,將會覆蓋目標對象中的屬性。

須要注意如下幾點:

  • 繼承屬性不可枚舉屬性是不能拷貝的。
  • 原始類型會被包裝爲對象,null, undefined 會被忽略,而且只有字符串的包裝對象纔可能有自身可枚舉的屬性.
  • 能夠拷貝 symbol 類型的屬性
  1. Object.assign 會調用 settergetter 嗎?調用的是哪裏的settergetter ?

Object.assign 會調用源對象的 getter,並把源對象的 getter 的返回值當作新對象的該屬性的值。
setter 則是會直接加在新建立的對象中,而不會沿用源對象的 setter.

  1. Object.getOwnPropertyDescriptor 是什麼?主要用來作什麼?

Object.getOwnPropertyDescriptor 返回直到對象上一個自有屬性對應的描述符,例如:

Object.getOwnPropertyDescriptor(obj, prop)
相關文章
相關標籤/搜索