原型链及原型链的作用
- 要用原型,先要有构造函数
- 构造函数一创建,系统就自动分配一个原型对象:
Person.prototype
- new一下,即创建一个构造函数的实例对象,每个实例对象被创建的时候,都带有一个隐式的
__ proto__
指向原型对象
原型链
概念:
当实例对象,在自身找不到方法时,会向上一级原型(Person.prototype)对象上查找,如果找不到,又会到原型对象上一级的原型对象(Object.prototype) 上查找,这种链试查找机制,就叫原型链。
简单理解
每一个对象都有原型,原型也是对象,也有自己的原型,以此类推形成链式结构,叫原型链
当调用实例的某个属性或方法时,内部会在实例对象p的原型的原型的原型身上一层层查找,找到为止,直到原型链终点null
扩展
原型链是一条引用的链,实例的隐式原型__ proto__
指向构造函数的显式原型(prototype)
- 可以使用A instanceof B来判断B是否在A的原型链上
原型链访问规则
- 就近原则:对象优先访问自己的成员,自身没有,才去原型找,原型也没有,就往上-级原型找
原型链作用
- 实现继承
- 几乎所有的框架底层都是用原型链实现的继承
构造函数,原型对象,实例对象的三角关系
构造函数
- 创建构造函数
Person
,它有一个porotype
属性,指向原型对象Person.prototype
(由系统自动创建分配)
2.原型对象
- 原型对象
Person.prototype
, 有一个constructor
属性,指回构造函数Person ( 构造函数和原型对象互指) - 同时原型对象也是对象,也有一个隐式的
__ proto__
属性, 指向它自己的原型对象
Object.prototype
-
Object.prototype
也是对象, 也有自己的原型对象,自身同时也有constructor
属性,指回它的构造函数Object
3.实例对象
- new一下,调用Person构造函数,创建一 个新的实例对象p (p对象包含构造函数Person的所有属性和方法)
- 每个实例对象创建的时候,都带有一个隐式的
__ proto__
, 指向它的原型对象 - 原型对象身上又有一个
__ proto__
,又指向上一级原型对象,一级一往上指,形成链式查找(原型链)
<script>
// 创建一个构造函数Person,Person本身具有原型对象
function Person(name, age) {
this.name = name;
this.age = age;
}
// 给Person的原型对象添加属性和方法
Person.prototype.sex = 'girl';
Person.prototype.sing = function() {
// Person.prototype.constrctor指向Person构造函数
console.log('唱歌');
}
// 生成一个实例对象xh
// 实例对象的__proto__指向Person.prototype
var xh = new Person('xiaohong', 12, );
// xh本身带有age属性,可以直接访问
console.log(xh.age); //12
// xh本身没有没有sing方法,在自身找不到,就去原型Person.prototype身上找
console.log(xh.sing()); //undefined
console.log(xh.hobby); //undefined
console.log(Person.prototype);
// 关系验证
console.log(xh.__proto__.__proto__ === Object.prototype) //true
console.log(xh.__proto__.__proto__.constructor) //Object
// 原型对象身上的constructor指向的就是Person构造函数
console.log(Person.prototype.constructor === Person) //true
// 原型链重点null
console.log(xh.__proto__.__proto__.__proto__) //null
</script>