这是MDN 文档必须Object.prototype
说的:
所有对象都从 Object.prototype 继承方法和属性,尽管它们可能被覆盖(除了具有空原型的对象,即 Object.create(null))。
换句话说,Object.prototype
是几乎所有对象的根。两者Object
和Function
都是 的子级Function.prototype
,而后者本身就是 的子级Object.prototype
。
当我忽略构造函数并专注于原型链时,我发现 Javascript 中的继承更容易理解。对我来说,这样做会使问题和答案都变得更简单;像这样的问题:
- 什么是对象的原型链?
- 给定两个对象 x 和 y,x 在 y 的原型链中吗?(或者:y 是否从 x 继承?)
您可以使用这个小片段(此处的有用文档)轻松地自己研究原型链:
function getPrototypes(obj) {
var protos = [],
parent = obj;
while ( true ) {
parent = Object.getPrototypeOf(parent);
if ( parent === null ) {
break;
}
protos.push(parent);
}
return protos;
}
根据这个函数,原语没有原型:
> getPrototypes(3)
TypeError: Object.getPrototypeOf called on non-object
所以让我们把图元排除在外。对于对象,层次结构看起来像这样(其中子级缩进到其父级的右侧)。据我所知,真正的多重继承在 Javascript 中是不可能的,所以每个对象都有一个父对象,除了Object.prototype
没有父对象:
Object.create(null)
- 对象.原型
arguments
Object.create(Object.prototype)
{}
Object.create({})
--假设{}
是上一行的对象,而不是单独的新对象
- JSON
- 数学
- Array.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)
- 正则表达式原型
这非常令人困惑!请注意,在大多数情况下,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
都为真。这没有反映在constructor
属性中:str1.contructor === String
有时,我们在对象的原型链中找不到每个对象的构造函数: Object.getPrototypeOf(str2).constructor === String
. 这是因为该constructor
属性继承自String.prototype
:bothstr1.hasOwnProperty('constructor')
和str2.hasOwnProperty('constructor')
为假,而Object.getPrototypeOf(str1).hasOwnProperty('constructor')
为真。幸运的是,您可以使用该Object.prototype.isPrototypeOf
方法来代替: str1.isPrototypeOf(str2)
是真的。