深入了解js原型与原型链——继承

导语

说到 js原型、原型链、继承,是个令人头疼的问题,说懂吧,只懂一点,说不懂,倒是知道一点。
看到网上很多关于这几个知识点的文章,不过大都会把人讲懵,今天你刷到我,那么你就舒服了

js 原型

话不多说,先上代码:

function Person(){

 }
 Person.prototype.name = "养猪的王某人";
 Person.prototype.age = 18;
 Person.prototype.getAge = function (){
      console.log(this.age);
 }

1.这段代码非常简单,定义了一个函数Person(),在其原型上定义了属性与方法

 let person1 = new  Person();
 console.log(Person.prototype);	//  Object
 console.log(person1);	// undefined

2.新建一个Person的实例对象:person1 。从上代码可知,函数拥有prototype,而普通对象没有

原型链与继承

console.log(person1.name);	// 养猪的王某人
person1.getAge()	// 控制台打印:18

这里出现了一个问题:person1 并没有 name 属性,为什么能够正常打印?这就涉及到继承(如图)
在这里插入图片描述
person1 本身是没有 name 属性的,但是通过 _ proto _ 这条原型链可以往上找,找到构造函数 Person(),从而拿到 name 属性。

原型链查找规则

如果我们在实例 person1 上再去添加一个 name 属性,如下:

let person1 = new  Person();
person1.name= "养猪的刘某人";
console.log(name)	// 养猪的刘某人

我们会发现打印变成了 “养猪的刘某人”,这就是就近原则:程序运行的时候,先在对象基本属性中查找,如果找不到,顺着原型链往上找。看到这个图,是不是新建的 name 离 person1 近一些:
在这里插入图片描述
那有的同学可能又要问了,那我怎么判断这个属性是对象的基本属性还是通过原型链查找的呢?那就要用到 hasOwnProperty(), 我们可以这么做:

 // 建一个基本属性
 person1.a = "person1基本属性";

 let item;
 for(item in person1){
     // 基本的
     if(person1.hasOwnProperty(item)){
         console.log(item);	// a
     }
 }

那又有同学懵逼了,这个**hasOwnProperty()**哪里来的?person1 也没有,Person()也没有,不要急,如图:
在这里插入图片描述

是不是一目了然?person1 顺着原型链找到 Person()的原型,然后没找到,那怎么办,继续往上找。
找到Person的原型链,指向Object的原型。这个时候找到了hasOwnProperty(),从而继承这个方法(通过原型链)。

FAQ : _proto_指向创建它的函数的prototype

那如果还没有呢?顺着原型链一级一级往上找,知道找到 null 为止。如果没有,报错,这就是原型链的查找规则。

本文就到这里了,应该明白了吧,如果对你有帮助,还不点赞转发一波~

猜你喜欢

转载自blog.csdn.net/qq_35942348/article/details/105774243