js原型与原型链与原型继承
js 中对象分为普通对象和函数对象,区别在于,普通对象的__proto__属性直接指向Object.prototype,所以对我们来说,讨论普通对象的原型并没有意义,下面我们主要讨论的是函数对象。
函数对象(也叫构造函数的实例),顾名思义是由函数构造的对象
function Person() {}
var person = new Person();
console.log(typeof person);
// object
我们可以用一个图来学习:

接下来我们来了解与原型有关的几个属性:
原型
1. prototype
函数才会有 prototype
function Person() {}
Person.prototype.name = "zhang";
var person = new Person();
console.log(person.name);
// zhang
每一个构造函数都会有一个prototype属性,他指向了该构造函数的原型对象
更新图片

2. constructor
构造函数的prototype指向了该构造函数的原型,那反过来构造函数的原型有没有指向构造函数的属性呢,答案是有的,就是constructor
function Person() {}
var person = new Person();
console.log(Person.prototype.constructor === Person);
// true
更新!

3. __proto__
对象才会有proto
实例对象有一个__proto__属性,他指向了该构造函数的原型对象
function Person() {}
var person = new Person();
console.log(person.__proto__ === Person.prototype);
// true
这就是原型链的开始!
更新!

原型链
原型对象也是对象,所以Person.prototype也会有__proto__属性,
Person.prototype.__proto__指向的是Object.prototype,也就是构造函数的终点,因为Object.prototype.__proto__ === null。
在对象中,查找变量的方式是从自身开始,如果没有就查找原型,原型再没有就查找原型的原型...,如果查找到就停止,如果没有就直到查找到null结束。
function Person() {}
Person.prototype.name = "zhang";
var person = new Person();
console.log(person.name);
// zhang
更新!
7-2e46944f58df.png)
图中绿色的线为原型链
原型继承
原型继承是 js 继承方法的一种,也是用的最多的一种。
function Person(name, age) {
this.name = name;
this.age = age;
}
function Gender(gender) {
this.gender = gender;
}
Person.prototype = new Gender("男");
Person.prototype.constructor = Person;
var a = new Person("zhang", 12);
console.log(a.gender); // 男
原型继承的方法只需要将要继承的构造函数挂载到原构造函数的prototype上,这样一来,在对象里找不到变量的时候,变会去找该对象的__proto__属性,也就是Person.prototype。
这里有一个问题就是我们在给 Person.prototype 赋值的时候,constructor 属性也一并带过去了,这就会出现 Person.prototype.constructor === Gender 的现象,但这明显是不合理的,所以在 12 行,重新使 Person.prototype.constructor 指向 Person,这样我们再回溯整个原型链的时候不至于混乱。
本文来自博客园,作者:jinzhepro,转载请注明原文链接:https://www.cnblogs.com/jinzhepro/p/19234055

浙公网安备 33010602011771号