了解JS原型是什么

78 阅读2分钟

「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

今天我们来聊聊原型

  • 概念 原型是function对象的一个属性,它定义了构造函数构造出对象的共有祖先。通过该构造函数生成的对象可以继承原型上的属性和方法。原型也是对象。

怎么理解这句话呢 我们知道构造函数是为了生产出对象,如:

//定义构造函数
function Person() {}
// 生成对象
var tom = new Person();

构造函数上有个属性prototype,这个属性是该构造函数构造的对象的共有祖先,通过该构造函数生产出的对象都可以使用原型上的属性和方法。如:

//定义构造函数
function Person() {}
//原型Person.prototype上的属性和方法可以给后代使用
Person.prototype.job = "teacher";
Person.prototype.school = "一中";
Person.prototype.skill= function (s){
    console.log("I have a skill:" + s);
}
// 生成对象
var tom = new Person();
var alice = new Person();
console.log(tom.job);
console.log(alice.job);

到这里,我们再进一步了解原型。经过上面我们知道对象可以继承原型上的属性和方法,但是为什么对象能找到对应的原型呢?他们之前应该是存在某些特殊的关系或者联系吧?对象生成的时候到底发生了什么导致这个现象

事实上,要揭开谜底,还是的回到new关键字生成对象的那一刻。 我们知道new生成出对象,其内部原理是:

  • 隐式生成this对象
  • 执行this.xxx=xxx
  • return this

this指代的就是生成出来的对象。在第一步中,隐式生成的this对象并非空对象{},它里面其实一开始有东西,有个属性叫__proto__,这个属性的值默认就是构造出该对象的构造函数的原型。

function Person() {}
var tom = new Person();
//new生成tom的时候
//this = {
//  __proto__ : Person.prototype;
//}
//所以
console.log(tom.__proto__ === Person.prototype);//true

tom.__proto__ === Person.prototype 这下真相大白了。 在查找对象的属性时,它会先找到自己,如果自己身上没有,就会沿着__proto__的指向,找到自己的祖先。

对象如果要查找自己的原型,可以通过属性__proto__查找。

对象如果要查找自己的构造函数,对象身上还有一个属性叫constructor,用于查看该对象的构造函数。即:

tom.constructor === Person;//true