以下是MDN docs 对Object.prototype 的看法:
所有对象都从 Object.prototype 继承方法和属性,尽管它们可能被覆盖(除了具有空原型的对象,即 Object.create(null))。
换句话说,Object.prototype 是几乎所有对象的根。 Object 和 Function 都是 Function.prototype 的子代,Function.prototype 本身就是 Object.prototype 的子代。
当我忽略构造函数并专注于原型链时,我发现 Javascript 中的继承更容易理解。对我来说,这样做会使问题和答案都变得更简单;像这样的问题:
- 什么是对象的原型链?
- 给定两个对象 x 和 y,x 在 y 的原型链中吗? (或者:y 是否继承自 x?)
您可以使用这个小 sn-p(有用的文档 here)轻松地自己研究原型链:
function getPrototypes(obj) {
var protos = [],
parent = obj;
while ( true ) {
parent = Object.getPrototypeOf(parent);
if ( parent === null ) {
break;
}
protos.push(parent);
}
return protos;
}
根据这个函数,primitives 没有原型:
> getPrototypes(3)
TypeError: Object.getPrototypeOf called on non-object
所以让我们把图元排除在外。
对于对象,层次结构看起来像这样(其中子级缩进到其父级的右侧)。据我所知,真正的多重继承在Javascript中是不可能的,所以每个对象都有一个父对象,除了Object.prototype,它没有父对象:
Object.create(null)
- Object.prototype
arguments
Object.create(Object.prototype)
-
{}
-
Object.create({}) -- 假设 {} 是上一行的对象,而不是单独的新对象
- JSON
- 数学
- Array.prototype
- Function.prototype
- 数组
- 对象
- 功能
- 号码
- 布尔值
- 字符串
- 正则表达式
function MyFunction() {}
Object.keys
Object.prototype.toString
Object.prototype.toString.call
getPrototypes
- MyFunction.prototype
- String.prototype
-
new String('abc')
Object.create(new String('abc'))
- Number.prototype
- Boolean.prototype
new Boolean()
new Object(false)
- RegExp.prototype
这很混乱!请注意,在大多数情况下,X.prototype 不是X 的原型!如果我们有一些更好的术语,情况可能会有所改善;但是......我们不 :( 如您所见,Number 和 Boolean 等构造函数与它们生成的对象处于单独的子层次结构中。此外,Object 本身继承自 Function.prototype 继承来自Object.prototype。
如果您尝试这些示例,您还会发现使用constructor 属性是检查对象原型的糟糕方法,原因有几个。鉴于var str1 = new String('abc'); var str2 = Object.create(str1);,原因如下:
一个对象可以是多个构造函数的实例:str1 instanceof String 和 str1 instanceof Object 都是 true。这未反映在 constructor 属性中:str1.contructor === String
有时,我们无法为对象原型链中的每个对象找到构造函数:Object.getPrototypeOf(str2).constructor === String。这是因为constructor 属性继承自String.prototype:str1.hasOwnProperty('constructor') 和str2.hasOwnProperty('constructor') 均为假,而Object.getPrototypeOf(str1).hasOwnProperty('constructor') 为真。幸运的是,您可以使用 Object.prototype.isPrototypeOf 方法来代替:str1.isPrototypeOf(str2) 是真的。