JavaScript基础之原型和原型链

172 阅读2分钟

原型和__proto__和prototype

构造函数

function Person(){
    
}
var person1=new Person();
person1.name ='asd';
console.log(person1.name)//asd

Person就是一个构造函数,通过new创建了person1对象实例。

其实构造函数就和普通函数没有多大区别,关键是调用它的方式——通过new新建一个实例。

prototype

function Person(){
    
}
Person.prototype.name ='asd';
var person1=new Person();
var person2=new Person();
console.log(person1.name)//asd
console.log(person2.name)//asd

每个函数都会有一个prototype属性,只有函数具有,而Person.prototype就是原型对象,也就是实例person1和person2的原型。

综合上面的信息

我们得知构造函数Preson的prototype属性指向构造函数原型Preson.prototype。实例具有的prototype属性为[[prototype]],指向构造函数原型Preson.prototype。构造函数原型具有constructor属性,指向构造函数本身。而实例也可以通过指向其原型函数来获得constructor:person1.constructor=Person;//ture

isPrototypeOf()方法

用来确定实例与构造函数原型之间有没有关系

console.log(Preson.prototype.isPrototypeOf(preson1));//ture
console.log(Preson.prototype.isPrototypeOf(preson1));//ture

__proto__

是每个对象都有的属性,如果想要访问prototype,没有标准方式可以访问,但大多数浏览器上会支持一个属性:_proto_,这个属性可以指向原型。

function Person(){
	}
var person1= new Person(); 
console.log(person1.__proto__===Person.prototype)//true

[[prototype]]可以使用proto访问

下面图解:实例通过_proto_访问到构造原型

JS中没有直接从实例preson到构造函数Preson的属性或方法,所以我们通过__proto__访问原型Preson.prototype然后通过构造函数原型的constructor找到构造函数。console.log(person.__prototype__.constructor === Person); //ture

我们在读取一个实例的属性过程中,如果属性在实例中没有找到,就会沿着__proto__指定的原型上去寻找,如果找不到就接着寻找原型的原型,同样通过__proto__指向构造原型再回到新原型......

巩固概念

  • 原型指的就是一个对象,实例“继承”那个对象的属性。在原型上定义的属性,通过“继承”(在 new 操作符内部实现的),实例也拥有了这个属性。
  • 函数对象作为构造函数创建实例时,该 prototype 属性值将被作为实例对象的原型。如上文中提到的Person.prototype就是一个原型对象,也就是实例person1和person2的原型。

原型链

原型同样也可以通过__proto__访问到他的原型,比方说这里有个构造函数 Person 然后“继承”构造函数 People,再 new People() 得到实例 p

当访问 p 中的一个非自有属性(type)的时候,就会通过__proto__ 作为桥梁连接起来People再连接People,直到 Object构造函数为止。

function Person(){};
Person.prototype.name='kiki';

function People(){};
People.prototype= new Person() ;

p = new People();

console.log(p.__proto__);// Person{}

console.log(p.__proto__.__proto__);// Object {name: "kiki", constructor: function}

console.log(p.__proto__.__proto__.__proto__);// {}

console.log(p.__proto__.__proto__.__proto__.__proto__);// null

上面的代码中

  1. p. __proto__等于 People.prototype (__proto__指向原型)
  2. p.__proto __.__proto__等于Person.prototype (__proto__指向原型*2)
  3. p. __proto __.__proto __.__proto__等于Object.prototype (__proto__指向原型*3)
  4. p. __proto __.__proto __.__proto __.__proto__等于null(__proto__指向原型*4)

(上图缺少People环节)

最后null说明访问的属性不存在。

参考文献: 🍭 图解原型和原型链 :juejin.cn/post/684490…