如果你读过之前的两篇文章,就会对原型链和原型方法有一定的理解。
下面这篇文章是对原型链最重要的总结
学习原型链是必须要有一个基本的概念:所有的对象都是Object
的实例。 而所有的实例的__proto__
都指向函数原型,即所有的实例和对象的__proto__
属性都指向了Object
的原型prototype
属性
下面附上代码和图片进行理解:
这是我在学习期间一直很有用的图。那么就根据图上的指向我们来用代码验证一下。
function Foo() { }
//首先创建来个实例
var f1 = new Foo()
var f2 = new Foo()
实例最底层指向大家应该都很清楚,这没有什么难的,
f1
实例的隐式原型__proto__
指向函数显式原型prototype
显式原型的constructor
属性指向构造函数本身
console.log( f1.__proto__ === Foo.prototype) //true
console.log(Foo.prototype.constructor === Foo) //true
那么构造函数Foo
是本质上也是一个函数,而所有的函数都是Function
的实例,所以构造函数和函数类型之间有一条原型链。构造函数Foo
的隐式原型指向了 Function
的显式原型,既然存在 Function
的显示原型,那么必然存在constructor
属性指向构造函数.
//构造函数Foo的隐式原型指向了 Function的显式原型
console.log(Foo.__proto__ === Function.prototype) //true
// 我们将Function的构造函数输出来看看是什么
console.log(Function.prototype.constructor) //[Function: Function]
``
一定要能区别开这两特殊的对象。
**Object和Function既是对象,又是函数,两者内部同时含有proto和prototype属性,他们关系较为复杂,以下做归纳。
*。
console.log(Object.__proto__ === Function.prototype) //true
console.log(Object.__proto__ === Function.__proto__) //true
console.log(Object.prototype === Function.prototype.__proto__) //true
// 一般可以做类型对比区别,因为原型指向一致,所有instanceof操作符默认相等
console.log(Function instanceof Object) //true
请仔细对比代码与图中原型链的位置,如果不能理解,请记住!!
原型链的终端
在原型链的终端一定是Object.prototype
实例。
所有的实例和函数的原型链最终端一定是如此
//请跟着上图原型链查找
console.log(f1.__proto__.__proto__ === Object.prototype) //true
console.log(Function.prototype.__proto__ === Object.prototype) //true
那么Object.prototype
指向哪里?一定指向的是NULL
console.log(Object.prototype.__proto__ === null) //true