导语
说到 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 为止。如果没有,报错,这就是原型链的查找规则。
本文就到这里了,应该明白了吧,如果对你有帮助,还不点赞转发一波~