浅谈_proto_和prototype

为什么要有原型

  用构造函数生成实例对象时,缺点是无法共享属性和方法。

  每一个实例对象,都有自己的属性和方法的副本。即每生成一个实例对象时,js都会为实例分配一个内存,用来存储那些公共的属性和方法。这不仅无法做到数据共享,也是极大的资源浪费

  prototype属性就是用来解决这个问题的

  prototype属性包含一个对象,所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面

  实例对象一旦创建,将自动引用prototype对象的属性和方法。即实例对象的属性和方法,分为两种,一种是本地的,另一种是引用的

原型(prototype)

  每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

原型链

  每一个对象都会有一个指向它的原型(prototype)对象的内部链接(__proto__)。每个原型对象又有自己的原型,直到某个对象的原型为null为止,组成这条链的最后一环。

 Object

  js中所有的对象都是Object的实例,并继承Object.prototype的属性和方法。

__proto__

  定义普通对象的时候,就会生成一个_proto_,指向自己构造函数的prototype对象。(每一个对象都会有的一个属性)

function Person(){}; 

var p = new Person();

Person.prototype.antion = function(){
  console.log(123);
} consol.log(p._proto_ === Person.prototype);
//true console.log(p.__proto__); //{anition:f, constructor:ƒ, __proto__:Object}

注意:proto左右是英文状态下的两个下划线!!!

prototype

  拥有内部方法的对象才有的属性(这个属性指向一个对象,也可以称其为对象),例如函数,对象的方法,Object(内置方法为toString、valueOf)。指向一个原型对象,可以访问

  指向的这个原型对象其实就是自身的原型,可以为这个原型添加属性和对象(方法),甚至可以指向一个现有的对象

  函数在被定义的时候就拥有了一个prototype对象

function Person(){}; 
var p = new Person(); 

 Person.prototype.func = function(){} 
 
 consol.log(p.prototype); //undefined,因为 p 只是一个普通对象,没有内部方法
console.log(Person.prototype); //{func:f, constructor:f, __proto__:Object}

2、Object.prototype 是原型链上最后一个有属性的原型,也就是说,Object.prototype 的原型是 null。所有对象都继承了 Object.prototype 的属性,我们也可以向 Object.prototype 中添加属性

function Person(){};
var p = new Person(); Object.prototype.F = function(){ console.log(“我是最后一个原型了~”); }

p.F(); //“我是最后一个原型了~”
Person.F();
//“我是最后一个原型了~”


//p为什么有 F 方法呢?以为它会沿着 __proto__ 一层一层向上寻找,直到找到 Object.prototype
//p.__proto__指向Person.prototype,p.__proto__.__proto__ === Person.prototype.__proto__ === Object.__proto__

 3、prototype 对象的另一个属性是constructor,这个属性指向了函数本身,也就是它自己的构造函数。

图示

 

 

参考:

https://segmentfault.com/a/1190000011801127

https://blog.csdn.net/lc237423551/article/details/80010100

https://www.cnblogs.com/dglblog/p/10553740.html

posted @ 2019-07-18 18:17  足迹#  阅读(416)  评论(1编辑  收藏  举报