一、原型
每一个构造函数都会带有一个 prototype (原型) 属性(天生就有的) ,它是一个对象数据库类型。每一个对象都会带有一个__proto__ 属性,指向所属构造函数的 prototype 属性,我们可以在原型对象中直接添加属性和方法,这些属性和方法可以被实例对象所共享。
分析说明: function Person() { }
二、原型链
当访问某对象的某个属性时,会先在这个对象本身上查找,如果没有找到,会沿着__proto__链一直查找,如果到null还没有找到,则返回undefined,
这样一层一层向上查找的链式结构,我们称为原型链。
注意:一定是沿着__proto__链寻找哦!
通过分析下面这两行代码去理解原型链:
<script>
function Person() {}
var p1 = new Person();
</script>
分析并回答下面问题:
1、 p1.__proto__指向谁?(就是在问p1的所属的构造函数是谁)
分析:指向其所属构造函数 Person 的 prototype;
p1.__proto__===Person.prototype
2、Person.prototype.__proto__ 指向谁?
分析:Person.prototype 是一个对象数据类型,我们知道在JS中所有的对象数据类型都是属于 Object 这个内置构造函数的,所以Person.prototype.__proto__ 指向Object.prototype
Person.prototype.__proto__===Object.prototype
3、Person.__proto__指向谁?
分析:Person 是一个函数,在Js中函数都属于 Function 这个内置构造函数,
所以就有Person.__proto__指向 Function.prototype
Person.__proto__===Function.prototype
4、Object.__proto__指向谁?
分析:Object 是一个内置构造函数,所以它属于内置构造函数 Function
就有了 Object.__proto__ 指向 Function.prototype
Object.__proto__===Function.prototype
5、Object.prototype .__proto__指向谁?
分析:按之前的思路就是,Object.prototype 是一个对象数据类型,它应该是属于Object,其实我觉得也没错,不过这样就形成了一个死循环, 那莫这里就有一个注意点了,Object.prototype 叫做顶级原型,在JS中一切皆对象,初始皆空 (null)
Object.prototype.__proto__===null
6、Function.__proto__指向谁?
分析:所有的函数都是属于内置构造函数 Function 的,所以不用怀疑,Function 自己创造了自己
Function.__proto__===Function.prototype
7、Function.prototype.__proto__指向谁?
分析:Function.prototype 是一个对象数据类型,所以它属于构造函数 Object
Function.prototype.__proto__===Object.prototype
Function.prototype.__proto__.__proto__===null
这是相应的图解
我们来看一个案例:
<script>
function One() {}
function Two() {}
function Three() {}
Two.prototype = new One();
Three.prototype = new Two();
var three = new Three();
//实例对象的.__proto__指向其所属构造函数的 .prototype
console.log(three.__proto__ === Three.prototype); //true
console.log(three.__proto__.__proto__ === Two.prototype); //true
console.log(three.__proto__.__proto__.__proto__ === One.prototype); //true
console.log(three.__proto__.__proto__.__proto__.__proto__ === Object.prototype); //true
</script>
图解