原型
简单来说,就是当我们创建一个函数的时候,系统就会自动分配一个 prototype
属性,可以用来存储可以让所有实例共享的属性和方法
- 每一个构造函数都拥有一个
prototype
属性,这个属性指向一个对象,也就是原型对象 - 原型对象默认拥有一个
constructor
属性,指向指向它的那个构造函数 - 每个对象都拥有一个隐藏的属性
__proto__
,指向它的原型对象
function Person(){}
var p = new Person();
p.__proto__ === Person.prototype // true
Person.prototype.constructor === Person // true
那么,原型对象都有哪些特点呢
原型特点
function Person(){}
Person.prototype.name = 'tt';
Person.prototype.age = 18;
Person.prototype.sayHi = function() {
alert('Hi');
}
var person1 = new Person();
var person2 = new Person();
person1.name = 'oo';
person1.name // oo
person1.age // 18
perosn1.sayHi() // Hi
person2.age // 18
person2.sayHi() // Hi
从这段代码我们不难看出:
- 实例可以共享原型上面的属性和方法
- 实例自身的属性会屏蔽原型上面的同名属性,实例上面没有的属性会去原型上面找
既然现在我们知道了什么是 prototype(原型)
以及它的特点,那么原型链又是什么呢?
原型链
JavaScript
中所有的对象都是由它的原型对象继承而来。而原型对象自身也是一个对象,它也有自己的原型对象,这样层层上溯,就形成了一个类似链表的结构,这就是原型链
- 所有原型链的终点都是
Object
函数的prototype
属性 -
Objec.prototype
指向的原型对象同样拥有原型,不过它的原型是null
,而null
则没有原型 - 从图可以看出指向Object和函数原型的箭头最多,Object和函数原型上每个箭头都是相等的,也就是:
// 函数原型
Function.prototype === function.__proto__ === Object.__proto__ === String.__proto__
// object原型
Function.prototype.__proto__ === function.__proto__.__proto__ === Object.prototype