面試:Function.prototype.a 請給出下列函數的執行輸出

問題

Function.prototype.a = () => {
  console.log(1);
}
Object.prototype.b = () => {
  console.log(2);
}
function A() {}
const a = new A();
a.a();
a.b();
A.a()

筆者第一反應就懵逼,搞不懂特地放一個 Function.prototype.a 幹什麼,由於 function A 的原型鏈屬性 prototype 只和 Object 有關係,和 Function 對象自己沒啥關係。面試

面試中筆者猜想函數

a.a() // 會沒法執行,由於 A 的原型的原型,我知道是 Object 而非 Function。
a.b() // 正常打印 2,由於 Object 的原型被加上了 b 方法,順着原型鏈能被找獲得。
A.a() // 第一反應和 a.a() 沒有區別,由於順着原型鏈仍是隻能找到 Object。可是面試官特地放上來這個,就讓筆者疑神疑鬼的。

輸出結果

最後面試完,特地去輸出了下結果.net

a.a() // Uncaught TypeError: a.a is not a function



a.b() // 2
A.a() // 1
A.b() // 2

也就是說 A 能夠找到 Function.prototype 和 Object.prototype 的屬性。而 a 只能找到 Object.prototype 的。prototype

嗯,這個 A 挺讓人困惑的。code

A instanceof Object // true
A instanceof Function // true

a instanceof A // true
a instanceof Object // true
a instanceof Function // false

分析

對於 new 出來的對象 a 的屬性,原型鏈查找的順序應該是對象

  1. a 自身
  2. a.__proto__ 至關於 A.prototype
  3. A.prototype.__proto__ 至關於 Object.prototype
  4. Object.prototype.__proto__ 這個爲 null,原型鏈查找到頭。

對於 function 定義的函數 A 的屬性,原型鏈查找順序應該是blog

  1. A 自身
  2. A.__proto__ 至關於 Function.prototype
  3. Function.prototype.__proto__ 等於 Object.prototype
  4. Object.prototype.__proto__ 這個爲 null,原型鏈查找到頭。

總之幾點原則:原型鏈

  • 全部構造函數的的 prototype 方法的 __proto__ 都指向 Object.prototype (除了 Object.prototype 自身)
  • Object 是 Function 的實例對象, Object.__proto__ === Function.prototype // true
  • Function.prototype 是 Object 的實例對象。Function.prototype.__proto__ === Object.prototype // true

參考

這篇對 Object 和 Function 的關係講得很好,能夠參考。get

js 原型的問題 Object 和 Function 究竟是什麼關係?原型

相關文章
相關標籤/搜索