Javascript 中 prototype到底是什么?

prototype是Javascript原生对象的一个属性,比如Array有这个属性,String也有这个属性,

  

  console.log(Array.prototype);   //输出 [] 

  console.log(String.prototype);  //输出 String {} 

  

  另外一个比较特殊的Object如何呢?

  console.log(Object.prototype);  //输出 Object {}

  

  因为这个prototype跟Function对象联系最紧密(在涉及到javascript面向对象时),

  这里重点说下 Function这个原生对象.

  console.log(Function.prototype); //输出 function Empty() {} 

  

  这里的Function相当于一个类,我们在定义function是,就是在创建一个一个Function的实例.

  比如:

  

  function Animal()

  {

    this.species = "动物"; 

  }

  

  这个就相当于定义: 

  var Animal = new Function ('Animal','this.species = "动物";');

  

  在new()的时候,js主要干了下面几件事情:

  

  1. js运行环境首先创建一个空对象

  2. 把this变量指向这个对象

  3. 把__proto__指向这个构造器的prototype属性

  4. 通过this把属性和方法加在这个对象上

  5. 最后会把this指向的对象return出来(当然你也可以显示的return别的对象,这是情况跟我讨论的有点不一样)

  

  所以上面 console.log(Animal.__proto__);  //输出为 function Empty() {} ,这个其实是Function的prototype属性

  

  一旦一个构造函数(即,类(function))定义了prototype,则在new 调用构造函数,创建实例时,会自动创建一个__proto__属性,指向构造器的prototype属性

  

  并且,在访问实例属性时,假如在当前的实例属性中没有这个属性,js会自动沿着__proto__指向的prototype属性查找这个属性,

  

  如果__proto__指向的prototype属性中任不包含这个属性,则会查找__proto__指向的prototype属性的__proto__指向的下一层prototype属性,

  

  以此类推,知道找到这个属性,假如还没有找到,则返回undefined,因为最终prototype属性指向Object的prototype属性为空.

 

这里从__proto__对象中查找属性时,是根据属性名称查找的,比如aObject.prop,查这个prop属性,假如prop属性其实是在__proto__找到的,仍然使用aObject.prop调用,就好像prop是aObject的一个属性一样.

  

  这中链式查找prototype的方式构成了prototype链.

  

  console.log(Animal.__proto__);  //输出为 function Empty() {} ,这个其实是Function的prototype属性,因为定义的function Animal 其实是 Function的一个实例.

  

  这样Function就是一个类,而这个类是定义了prototype属性的.

  

  如果: var anAnimal = new Animal(); 

  console.log(anAnimal.__proto__);// 因为Animal类没有定义prototype属性,js会自动加一个默认属性.指向构造函数 Animal {} 

  //因为每一个实例都需要有一个constructor对象指向这个实例的构造函数(即类定义function),

  //而这个constructor对象是构造函数(即类定义function)的prototype的一个属性,所以js需要给没有定义prototype的构造函数

  //增加一个默认的prototype属性

  

  

  prototyp这个属性只有Function对象,以及创建的function才有的,就相当于一个静态属性.

  

  new 出来的一般实例一般没有这个属性,

  假如在构造函数中,定义了一个prototype属性,会怎样呢?

  如下:

  //定义一个基类

  function Animal()

  {

    this.species = "动物"; 

    this.prototype = '自定义prototype';

  }

  这里的prototype其实是实例的一个属性而已,只属于该实例.对该实例的构造函数的prototype属性不构成影响.

  实例的.__proto__这个属性,仍然指向构造函数的prototype属性.

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
    this.prototype = '自定义prototype';
  }
  
  Animal.prototype.show = function(){alert('This is an animal!');};
  console.log(Animal.prototype);
  var anAnimal = new Animal(); 
  console.log(anAnimal.prototype); //实例的一个普通属性而已,正常使用
  console.log(anAnimal.__proto__);//同 console.log(Animal.prototype);

 

假如定义一个function时没有显式指定prototype属性,和显式指定prototype属性,在chrome中显示的function对象是不一样的,如下:

a.不显式指定prototype

    

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
    this.prototype = '自定义prototype';
  }
  console.log(Animal.prototype);
  //输出 Animal {}

 

b. 显式指定prototype

   

//定义一个基类
  function Animal()
  {
    this.species = "动物"; 
    this.prototype = '自定义prototype';
  }
  
  Animal.prototype.show = function(){alert('This is an animal!');};
  console.log(Animal.prototype);

     上面的输出是一个对象的形式

      Animal {show: function}

 
  1. constructorfunction Animal()
  2. showfunction (){alert('This is an animal!');}
  3. __proto__Object

 

 

 参考: http://www.leonzhang.com/2011/12/20/javascript-prototype/

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值