1. 什么是原型?
给其它对象提供共享属性的对象,简称为原型。 你可以暂且吧原型理解为一个对象, 把__proto__理解为原型,吧prototype理解为原型,那么你要问我为什么要搞两个原型,那么你得听我慢慢道来
2. 原型有什么用?
- 可以让所有的对象实例共享它所包含的属性和方法,
- 继承 ⇒ JavaScript的继承就是基于原型的继承
3. 理解原型之前你需要知道的几个东西
3.1 构造函数丶实例对象丶原型对象分别是什么? 他们之间又有什么关系?
我们先来看一段代码
function Person(name, age) {
this.name = name
this.age = age
}
let p = new Person('pcy', 18)
console.log(p.__proto__)
console.log(Person.prototype);
console.log(p.__proto__ === Person.prototype); //true
上面代码的Person就是构造函数 p代表实例对象 p.__proto__代表原型对象
用一张图来展示他们的关系
上图可以看出, 构造函数通过new创建实例对象,实例对象通过__proto__可以访问原型对象,然后原型对象有一个constructor,这个constructor是原型对象自带的,constructor里保存了指向构造函数的一些信息, 在构造函数创建的时候,原型对象就创建了,然后构造函数的prototype指向了原型对象. 所以console.log(p.proto === Person.prototype); //true
3.2 什么是__proto__ ?
__proto__被称为隐式原型, 每个对象都有这么一个属性. 你可以在控制台输入{}, 然后回车, 你会发现打印出[[prototype]], 是一个对象, 这个[[prototype]]其实就是原型
我们可以通过__proto__访问这个对象,你会发现为什么我们明明只是创建一个对象.却可以使用toString,valueOf等方法,因为这些方法都在原型上
let obj = {}
console.log(obj.__proto__);
3.3 什么是prototype?
prototype被称为显式原型, 每个函数都有这么一个属性
let fn = function F() { }
console.log(fn.prototype);
3.4 __proto__和prototype的关系?
总结一下, 函数的原型叫prototype, 被构造函数创建的对象的原型叫__proto__, 函数.prototype === 实例对象.proto
4. 什么是原型链
原型链定义如何查找对象的属性
比如现在有一个对象obj,我要查找obj的某个属性,先看obj自身有没有这个属性,如果没有就去obj.__proto__上看看有没有,没有就去创建obj的构造函数的prototype的__proto__上找,这一层一层的查找链路,被称为原型链.
function Parent(name){
this.name = name;
}
var obj = new Parent('Ann');
console.log(obj.name); // Ann
console.log(obj.father); // undefined
查找会走如何步骤
关于原型链,你也可以参考下面这这张图, 左边半部分就和我3-1下面那张图意思差不多, 整张图一起看,就是一个完整的原型链
5. 结语
如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。
文章如有错误之处,希望在评论区指正🙏🙏。