原型与原型链
- 1 学前先了解一些概念
- 1.1 构造函数和普通函数的区别
- 1.1.1 调用方式
- 1.1.2 函数中this的指向不同
- 1.1.3 写法不同
- 1.2 问题明确
- 2 原型与原型链
- 2.1 原型
- 2.2 显式原型与隐式原型
- 2.3 原型链
- 3 原型链环形结构
1 学前先了解一些概念
1.1 构造函数和普通函数的区别
构造函数是用来创建实例对象的,普通函数是用来调用执行的
1.1.1 调用方式
构造函数也是一个普通函数,创建方式和普通函数一样。
function func(){}
func(); // 普通函数调用方式
// 构造函数命名通常使用大驼峰
function Stru(){}
let obj = new Stru(); // 构造函数调用方式
1.1.2 函数中this的指向不同
- 普通函数遵循谁调用指向谁的思想;
- 构造函数的this则是指向它创建的对象实例 。
1.1.3 写法不同
- 普通函数
function person(name){
let obj = {};
obj.name = name;
return obj;
}
var p = person('john');
- 构造函数
function Person(name){
this.name = name;
}
let p = new Person('John');
1.2 问题明确
- 万物皆对象,构造函数、原型、实例对象都是对象。
- 每个对象都有一个__proto_,它指向该对象的原型。
- 每个函数都有一个名为prototype的属性,它的值是一个对象,这个对象就是通过调用构造函数创建的对象的原型。
- constructor属性只存在于原型对象中,它用于返回创建该原型对象的函数,也就是构造函数。
- 原型对象和实例对象都来源于构造函数,只不过原型对象比实例对象更加抽象。
[prototype]]和__proto__意义相同,均表示对象的内部属性,其值指向对象原型。前者在一些书籍、规范中表示一个对象的原型属性,后者则是在浏览器实现中指向对象原型。
2 原型与原型链
2.1 原型
- 每创建一个函数,该函数都会自动带有一个prototype属性。该属性是一个指针,指向一个对象,该对象称之为原型对象。
- 原型对象上默认有一个属性constructor,该属性也是一个指针,指向其相关联的构造函数。
- 原型对象用来存放实例对象的公有属性和公有方法。
2.2 显式原型与隐式原型
- 构造函数和原型对象之间有直接连接,即构造函数的prototype属性;
- 实例对象和原型对象之间也有直接连接,即实例对象的__proto__属性
- per1.__proto__ === Person.prototype
2.3 原型链
过对象__proto__属性指向函数的原型对象(函数.prototype)一层一层往上找,直到找到Object的原型对象(Object.prototype)为止,层层继承的链接结构叫做原型链。
查找过程都是顺着__proto__属性,一步一步往上查找,形成了像链条一样的结构,这个结构,就是原型链。所以,原型链也叫作隐式原型链。
3 原型链环形结构
所有函数都可以看做是Function()的实例,而Person()和Object()都是函数,所以它们的构造函数就是Function()。Function()本身也是函数,所以Function()也是自己的实例