搞清楚原型链之前,先说明什么是函数,什么是实例,什么是构造函数,什么是原型,什么是原型链,带着问题往下看
// 函数
function Person (){} // 这是一个函数
let Person = function(){} // 这也是一个函数
// 两者都是函数,或者说两者都是构造函数,没有区别(暂不谈声明提前)
// 函数与显示原型对象的关系:函数都有 prototype(显示原型对象)。可以用来挂载方法,供实例对象使用。此对象中存在三样东西:
1方法和属性(需要自己添加)
2 constructor构造器,说明次函数由谁构造
3 __proto__ 因为prototype是一个对象{},而{}属于Object(构造函数)的实例,由此便有了 这个隐式原型链
// 实例
function Person (){} // 这不是一个函数吗?看下面
Person = new Function() // 每个函数,都是Function(构造函数)的实例
let Function = new Function() // Function也是Function(构造函数)的实例
// 总结:函数具有两面性,可以是实例对象,也可以是构造函数
// 实例与隐式原型的关系:实例都有__proto__(隐式原型对象),可以用来取到显示原型对象上的方法
// 声明公理
// 1.每个函数,都有一个显示原型
// 2.每个实例,都有一个隐式原型
// 3.实例的隐式原型 === 构造函数的显示原型
// 4.函数 === 构造函数.显示原型.constructor
// 5.每个函数,都是Function的实例,因此每个函数都有两条原型线,
// 6.所有实例对象的隐式原型都指向一个空的Object实例对象,【但不包括object实例对象,因为object实例对象的隐式原型为null】
// 构造函数的显示原型,指向object实例对象
console.log(Person.prototype)
// 函数 === 构造函数.显示原型.constructor
console.log(Person === Person.prototype.constructor) // true
// 因为 Person.prototype 指向空的object的实例 对象
console.log(Person.prototype.__proto__) // object 对象
// 空的object实例对象,他也有属于自己的隐式原型, 只不过它的隐式原型指向null,此时已经到了 Person函数对象显示原型链的尽头
console.log(Person.prototype.__proto__.__proto__) // null
// 同时它也是Function的实例对象,已知每个实例对象都有一个隐式原型
console.log(Person.__proto__)
// 根据公理,实例对象的隐式原型 === 构造函数的显 示原型
console.log(Person.__proto__ === Function.prototype) // true
// 根据公理: 函数对象 === 构造函数.显示原 型.constructor
console.log(Function === Function.prototype.constructor) // true
// Function是构造函数,也是实例对象,因为 Function是Function创建的,:Function = new Function(){}
// 根据公理:3.实例对象的隐式原型 === 构造函数的 显示原型
console.log(Function.prototype === Function.__proto__) // true
// Function同时又是构造函数,构造函数的显示原型 指向一个空的object实例对象
console.log(Function.prototype.__proto__) // 打印一个空的Object实例对象
// 根据公理:6.所有实例对象的隐式原型都指向一个空 的Object实例对象,但不包括object实例对象,因 为object实例对象的隐式原型为null
// 空的object实例对象,他也有属于自己的隐式原型, 只不过它的隐式原型指向null,此时已经到了 Function构造函数显示原型链的尽头
console.log(Function.prototype.__proto__.__proto__) // null
// 此时,相对的,内置的Object函数也是Function构 造函数的实例对象,
// 根据公理:(Object)实例对象的隐式原型 === (Function)构造函数的显示原型
console.log(Object.__proto__ === Function.prototype) // true