关于前端:深入理解JavaScriptJavaScript-中的始皇

3次阅读

共计 2487 个字符,预计需要花费 7 分钟才能阅读完成。

JavaScript 中的始皇

前言

笔者在 继承 中发了一题对于原型链关系图的题,题目起源自颜海镜的 如何答复面试中的 JavaScript 原型链问题,这题的确很好,当画完它时,会有种看到这幅图的感觉

的确,这图一看很懵,搞不懂。再来看看这几段代码

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

为什么会如此,Object 和 Function 谁才是始皇,还有 Object.prototype 处于什么地位,Function.prototype 呢?

在知乎曾探讨过这个话题,JS 中先有 Object 还是先有 Function?

这里,笔者查一查谁是最先呈现的皇

注释

在写 所有皆对象 时,笔者阐释 JavaScript 中的对象有内置对象,而这些内置对象是语言外部创立,这些内置对象都是构造函数,即又被称为内置构造函数,它们存在的目标是为了让开发者更不便的书写代码。这些内置构造函数包含 Object、Function、Array、String、Number、RegExp 等等

因为它们是构造函数,所以它们必然属于函数,因为是函数,所以它们都是 Function 创立的,因为是 Function 创立的,所以它们都是 Function 的实例,即

String instanceof Function // true
Array instanceof Function // true
Function instanceof Function // true
Object instanceof Function // true

所以它们的原型链关系图是

又因为 Function 是函数,所以它有 prototype 属性。因为函数也是对象,所以 Function 也有 constructor 和 [[Prototype]],它的关系图是

所以就有了

Function.__proto__ === Function.prototype

即:

在 原型 中,咱们讲到了原型链,因为每个对象都有 [[Prototype]] 属性,它会指向它的原型对象,一层一层,最终指向 null。而 null 的上一站是 Object.prototype

无论你是构造函数的原型,还是自定义对象的原型,都会先指向 Object.prototype,再由 Object.prototype 指向 null

String.prototype.__proto__ === Object.prototype // true
Number.prototype.__proto__ === Object.prototype // true
Array.prototype.__proto__ === Object.prototype // true
Function.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null // true

var obj = {};
var arr = [];
function func() {}
obj.__proto__ ===  Object.prototype // true
arr.__proto__.__proto__ === Object.prototype // true
// arr.__proto__ 指向 Array.prototype
func.__proto__.__proto__ === Object.prototype // true
// func.__proto__ 指向 Function.prototype

它们的原型链关系图如下所示:

所以看代码和图咱们晓得,所有原型继承的源头都在 Object.prototype,Object.prototype 对象上的属性,会被任何值应用,所以判断类型最精确的方法是 Object.prototype.toString.call(source)

如果咱们将构造函数的源头和原型的源头联合一下,就成了这样:

此图和 Object Layout 的图大差不差,关键在于 Object 和 Function

Object.prototype 的原型之母,任何原型都源自它

Function.prototype 是构造函数之母,任何构造函数都由它创立,包含它本人

了解了这两点,咱们再回过头看这个问题

Object instanceof Object // true
// Object 由 Function.prototype 创立,Function.prototype 的原型对象指向 Object.prototype
Function instanceof Function // true
// Function 由 Function.prototype 创立
Object instanceof Function // true
// Object 由 Function.prototype 创立
Function instanceof Object // true
// Function 由 Function.prototype 创立,Function.prototype 的原型对象指向 Object.prototype

留神一点:构造函数也是实例,找出创立他们的构造函数和原型就能明确

总结

谁是始皇,无疑。Object.prototype 才是真正的始皇,任何原型都源自它;而 Function.prototype 是仅次于 Object.prototype 的存在,它是内置构造函数的创建者,任何构造函数都源自它

系列文章

  • 深刻了解 JavaScript- 开篇
  • 深刻了解 JavaScript-JavaScript 是什么
  • 深刻了解 JavaScript-JavaScript 由什么组成
  • 深刻了解 JavaScript- 所有皆对象
  • 深刻了解 JavaScript-Object(对象)
  • 深刻了解 JavaScript-new 做了什么
  • 深刻了解 JavaScript-Object.create
  • 深刻了解 JavaScript- 拷贝的机密
  • 深刻了解 JavaScript- 原型
  • 深刻了解 JavaScript- 继承
正文完
 0