内部原型(`_proto_`) or 构造器的原型(`prototype`)

1
2
3
> 1. A function's .prototype is actually the prototype of things made by it, not its prototype.
> 2. __proto__ is the actual prototype, but don't use it.
>

通过官方定义,我们应该认识的一个问题是,js中的继承是指对__proto__的继承,而不是prototype!

所有构造函数的__proto__都指向Function.prototype,他是一个空函数(Empty function)

1
2
3
4
5
6
7
8
9
1. Number.__proto__ === Function.prototype // true
2. Boolean.__proto__ === Function.prototype // true
3. String.__proto__ === Function.prototype // true
4. Object.__proto__ === Function.prototype // true
5. Function.__proto__ === Function.prototype // true
6. Array.__proto__ === Function.prototype // true
7. RegExp.__proto__ === Function.prototype // true
8. Error.__proto__ === Function.prototype // true
9. Date.__proto__ === Function.prototype // true

还有些内置对象比如MathJSON是以对象形式存在的,无需new。它们的__proto__是Object.prototype

1
2
1. alert(Math.__proto__ === Object.prototype); //true
2. alert(Math.__proto__); //Object

想调试上面的代码吗?来怼我一炮

所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身。所有构造器都继承了Function.prototype的属性及方法,如length、call、apply、bind(ES5)。

所有的构造器也都是一个普通JS对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。

注意:Function.prototype本身是没有这些属性和方法的,他之所以可以调用这些方法是因为Function.prototype是一个对象,既然是一个对象就好说了,那么他的原型链指向的就会是Object.prototype了。

总的来说, 原型的所以知识点都可以用这么一张图来简单概括:
通过上面这张图, 我们可以这样理解:

.prototype是一个对象的原型对象,而.proto则是对原型对象的引用!