原型和原型链

1.普通对象与函数对象

在JavaScript中,万物皆对象。对象分为普通对象和函数对象,那么怎么区分普通对象和函数对象呢?

function是js中自带的函数对象。通过new function()创建的对象都是函数对象。其他的都是普通对象。

<script>
  var a1 = function(){};
  var a2 = new Function('小明');
  function a3(){};

  var b1 = {};
  var b2 = new Object();
  var b3 = new a3();
  console.log(typeof a1);//function
  console.log(typeof a2);//function
  console.log(typeof a3);//function
  console.log(typeof b1);//object
  console.log(typeof b2);//object
  console.log(typeof b3);//object

</script>

从上面代码中可以看出a1,a2,a3为函数对象,b1,b2,b3为普通对象。

2.原型对象

  在JavaScript中每当定义一个函数对象,对象都会包含一些预定义的属性,每个函数都有一个prototype属性(原型属性),这个属性是一个指针,指向一个对象(原型对象),注:普通对象没有prototype,但有__proto__属性。

现在创建一个函数看看,原型是什么?

<script>
  var test=function(){};
  console.log(test.prototype);//object{}
</script>

我们可以看到原型就是一个空的对象,既然是一个对象,我们就可以为他添加属性和方法。

<script>

  var test=function(){};
  test.prototype.getName=function(){
    return this.name;
  }

</script>

原型对象是用来做什么的呢?主要作用是用于继承。举了例子:

var cart= function(name){
   this.name = name
  };
 cart.prototype.getName = function(){
     return this.name; 
  }
  var myCart= new cart(‘兰博基尼’);
  myCart.getName(); //兰博基尼

我们可以看到,原型对象上添加的属性和方法,在函数创建的实例中依然可以使用,这说明什么?

原型对象中的属性和方法是所有实例共享的。

3.原型链

JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。以上面的例子为例:

<script>
  var test=function(){};
  test.prototype.name="小明";
  test.prototype.sex="男";
  test.prototype.getName=function(){
    console.log(this.name);
  }
  var a1=new test();
  console.log(test.prototype);
  console.log(a1);
</script>

   我们可以看到,test的原型对象和一个实例对象都有一个__proto__对象,但是指向不同,原型对象中的__proto__指向Object,而实例中的__proto__指向内部明叫test的对象,展开这个对象可以看到就是原型对象。就是说每一个实例中有一个__proto__属性指向原型对象。每一个实例的内部都包含一个内部属性__proto__,指向了构造函数的原型,就是这个属性连接了实例和原型对象之间的关系,并且我们知道实例中不包含name属性和getName方法,但是我们却使用了getName(),就是通过这个__proto__属性查找的。

JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。

 console.log(zjh.__proto__ === person.prototype) //true

同样,person.prototype对象也有__proto__属性,它指向创建它的函数对象(Object)的prototype

  console.log(person.prototype.__proto__ === Object.prototype) //true

继续,Object.prototype对象也有__proto__属性,但它比较特殊,为null

  console.log(Object.prototype.__proto__) //null

我们把这个有__proto__串起来的直到Object.prototype.__proto__为null的链叫做原型链

4.isPrototypeOf查找原型

使用方法a.isprototypeOf(b),判断对象a是否是实例b__proto__指向的原型对象,如果是返回true,否则返回false。看个例子

 var test = function test(){}
  test.prototype.name = "小明";
  test.prototype.age = "25";
  test.prototype.getName = function(){console.log(this.name);}
  var o1 = new test();

  console.log(test.prototype.isPrototypeOf(o1));//true

五、总结

1.原型和原型链是JS实现继承的一种模型。
2.原型链的形成是真正是靠__proto__ 而非prototype。

亦心晗
原文地址:https://www.cnblogs.com/wanf/p/7207514.html