JS之原型和原型链

吐槽君 分类:javascript
  • __proto__每个对象都有的一个属性,而prototype函数才会有的属性。
  • constructor属性本质上只有prototype属性才有

先上图

20210327_1.jpg

prototype属性

上面说了,prototype函数独有的属性。

对应上面的图,就是

  • function Foo()指向Foo.prototype
  • function Object()指向Object.prototype
  • function Function()指向Function.prototype

各自对应的prototype就是用来放各自的原型属性和原型方法的,可以用来共享这些属性和方法

Foo.prototype.name = 'zk'
 

像这样就是原型属性,也可以根据同样的方法来创建原型方法

我们一般使用的Object.prototype.toString.call()来判断类型,就是使用的Object中的原型方法来判断的。

__proto__属性

__proto__是对象具有的属性,指从一个对象指向此对象的原型对象(类似指向Java中的父类)。

prototype中的属性和方法(也就是原型属性、原型方法),此构造函数的实例都可以访问和调用。那么这里的原型属性和原型方法是怎么和构造函数的实例联系起来的?就是通过__proto__属性。

现在可以知道,万物继承自Object.protptype

比如:在调用f1.toString()的时候,首先在f1本身找,没有找到再通过f1.__proto__找到Foo.prototype,如果还是没有找到,就通过Foo.prototype.__proto__找到Object.prototype,一直重复操作,直到找到为止;若最后还是没有,就返回undefined

constructor属性

constructor属性是prototype属性才会有的属性

构造函数.prototype.constructor === 该构造函数

总的看来,constructor似乎没起到什么作用,不一定

constructor的作用是什么?

function Person(area){
  this.type = 'person';
  this.area = area;
}
Person.prototype.sayArea = function(){
  console.log(this.area);
}
let Father = function(age){
  this.age = age;
} 
Father.prototype = new Person('Beijin');
console.log(Person.prototype.constructor); // function person()
console.log(Father.prototype.constructor); // function person()
Father.prototype.constructor = Father; // 修正
console.log(Father.prototype.constructor); // function father()
 

如果没有上面修正的那句代码

let temp = new Father(25)
console.log(temp.constructor) // function Person() {}
 

Father构建出来的对象temp的构造函数指向是Person,而不是你new它的时候用的构造函数Father。这就导致了原型链的错乱。

Father.prototype = new Person('Beijin');中,Father的原型指向了一个新对象,这个新对象的constructor指向的是Person,所以才需要那句修正的代码,来保证了原型链的正确。

若有不当之处,欢迎指出

回复

我来回复
  • 暂无回复内容