一、prototype
prototype是一个显示原型属性,当我们声明一个函数时,这个属性就自动创建了。

constructor对应着构造函数,也就是Foo。一旦我们重写了原型,这个属性就不存在了,这里有疑问。
function Foo(){
}
Foo.prototype = {
a : 1
};
console.log(Foo.prototype);
function Person(){
}
Person.prototype = {
name:'kimi'
};

___proto__ : 这是每个对象都会有的隐式原型属性,指向了创建该对象的原型。其实这个属性指向了[[prototype]],但是[[prototype]]是内部属性,我们返问不到,所以用__proto__来访问。
实例对象的__proto__是如何产生的?
当我们使用new操作符时,生成的实例对象拥有了__prototype__;
function Foo() {}
// 这个函数是 Function 的实例对象
// function 就是一个语法糖
// 内部调用了 new Function(...)new的过程
function Person(name){
this.name = name;
};
function create(o,name) {
// 创建一个空的对象
let obj = new Object();
// 获得构造函数
let Con = [].shift.call(arguments);
console.log(Con);
// 链接到原型
obj.__proto__ = Con.prototype;
// 绑定 this,执行构造函数
let result = Con.apply(obj,arguments);
// 确保 new 出来的是个对象
console.log(result); //undefined 因为apply函数的内部result = context.fn()没有返回值。
return typeof result === 'object' ? result : obj
}
console.log(create(Person,'kimi'));Function.proto === Function.prototype
首先引擎创建了 Object.prototype ,然后创建了 Function.prototype ,并且通过 __proto__ 将两者联系了起来。
有了 Function.prototype 以后才有了 function Function() ,其他所有的构造函数都可以通过原型链找到 Function.prototype ,并且 function Function() 本质也是一个函数,为了不产生混乱就将 function Function() 的 __proto__ 联系到了 Function.prototype 上。
总结
Object是所有对象的爸爸,所有对象都可以通过__proto__.constructor找到它Function是所有函数的爸爸,所有函数都可以通过__proto__.constructor找到它Function.prototype和Object.prototype是两个特殊的对象,他们由引擎来创建- 除了以上两个特殊对象,其他对象都是通过构造器
new出来的 - 函数的
prototype是一个对象,也就是原型 - 对象的
__proto__指向原型,__proto__将对象和原型连接起来组成了原型链