天天看点

说透js的原型和原型链

1. 什么是原型?

给其它对象提供共享属性的对象,简称为原型。 你可以暂且吧原型理解为一个对象, 把__proto__理解为原型,吧prototype理解为原型,那么你要问我为什么要搞两个原型,那么你得听我慢慢道来

2. 原型有什么用?

  1. 可以让所有的对象实例共享它所包含的属性和方法,
  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__代表原型对象

用一张图来展示他们的关系

说透js的原型和原型链
上图可以看出, 构造函数通过new创建实例对象,实例对象通过__proto__可以访问原型对象,然后原型对象有一个constructor,这个constructor是原型对象自带的,constructor里保存了指向构造函数的一些信息, 在构造函数创建的时候,原型对象就创建了,然后构造函数的prototype指向了原型对象. 所以console.log(p.proto === Person.prototype); //true

3.2 什么是__proto__ ?

__proto__被称为隐式原型, 每个对象都有这么一个属性. 你可以在控制台输入{}, 然后回车, 你会发现打印出[[prototype]], 是一个对象, 这个[[prototype]]其实就是原型

说透js的原型和原型链

我们可以通过__proto__访问这个对象,你会发现为什么我们明明只是创建一个对象.却可以使用toString,valueOf等方法,因为这些方法都在原型上

let obj = {}
console.log(obj.__proto__);
           
说透js的原型和原型链

3.3 什么是prototype?

prototype被称为显式原型, 每个函数都有这么一个属性

let fn = function F() { }
console.log(fn.prototype);
           
说透js的原型和原型链

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
           

查找会走如何步骤

说透js的原型和原型链

关于原型链,你也可以参考下面这这张图, 左边半部分就和我3-1下面那张图意思差不多, 整张图一起看,就是一个完整的原型链

说透js的原型和原型链

5. 结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏。

继续阅读