js被描述为基于原型的语言
原型:在 javascript 中,函数可以有属性。每个函数默认都有一个特殊的属性叫作原型(prototype),每个对象创建之后默认都拥有一个原型对象,对象以原型为模板,从原型中继承方法和属性,具体的继承方式为将函数(Foobar())的一个特殊属性prototype整个赋值给了对象(new Foobar())的__proto__,其中__proto__即为对象原型,也就是(new Foobar()).__proto__=Foobar.prototype,也可以认为new Foobar().getPrototypeOf(new Foobar())=Foobar.prototype,(其中getPrototypeOf()为ES5的方法),所以构造函数的prototype中一般都存放用于继承的属性和方法。
原型=原型对象=对象原型,三者指向的其实是同一个东西
原型链:原型对象也可能拥有原型,并从中继承方法和属性,一层一层,以此类推,这种关系被称为原型链。
能被继承的属性和方法 都被定义在对象的构造器函数的prototype属性上,而非对象实例本身。
理解对象的原型(可以通过Object.getPrototypeOf(obj)或者已被弃用的__proto__属性获得)与构造函数的prototype属性之间的区别是很重要的。前者是每个实例上都有的属性,后者是构造函数的属性。也就是说,Object.getPrototypeOf(new Foobar())和Foobar.prototype指向着同一个对象
构造函数constrctor
实例化的对象会自动获取一个构造函数属性(person.constructor),此属性指向构造函数原型的构造函数(Person.prototype.constructor),当获取person.constructor时,其实person中并没有constructor属性,当不能读取到constructor属性时,会从person的原型(也就是Person.prototype)中读取,正好person的原型中有该属性,就会返回此属性值((Person.prototype.constructor),这个查找的过程所反映出来的关系就是原型链
function Person(name, age){
this.name = name;
this.age = age;
}
var person1 = new Person('Echo', 19);
//person1的构造函数是Person
person1.constructor = Person
// Person.prototype的构造函数也是Person
Person.prototype.constructor = Person
说明Person.prototype也是Person的一个实例
原型对象(Person.prototype)是构造函数(Person)的一个实例