zoukankan      html  css  js  c++  java
  • 到底原型是个什么鬼?

    先贴一篇文章

    写了这么久JS,从来没有真正去思考过这个问题,在java时代我们是

    class Animal{

    public myFunc(){

      

    }

    }

    class Dog extend Animal{

    public sayWangwang(){

      

    }

    }

    haqishi=new Animal();

    haqishi.myFunc();

    haqishi.sayWangwang();

    ///////////

    来到了javascript的时代,我们没了class

    Dog还想用Animal的方法,该怎么办

    一定要建立一些关系,其中有两个问题是必须解决的

    1.继承了Animal的Dog可以调用Animal上的方法,且不可轻易修改

    2.Dog实例同时可以拥有自己的同名方法,有同名方法时就先用自己的

    javascript是过程性语言

    我们需要用一种简单的方法:建立一个审查链条,这个链条上是实例对象,他们有自己的方法,

    在这条链上寻找方法,找到了就可以返回调用。同时this指针要保证他的正确性

    来路演一下:

    var Animal=new function (name){

      this.name='animal'||name;

    }

    //此时

    一个名叫Animal函数实例被创建了,我们不去思考它之前的东西,假设它有一个属性是对象,姑且叫做Animal.Dad,我们在Animal.Dad上挂一个函数

    Animal.Dad.breath=function(){console.log(this.name+'xixi huhu')}

    //接下来我们来创建一个animal

    var animal=new Animal('dog');

    //这时有一些奇妙的事情发生了,我们将它分成三步

    1.建立空对象2.建立和Animal的联系3.调用Animal的构造函数

    var animal  = {};//建立一个对象,这一步没有疑问

    animal._dad_=Animal.Dad;//我们创建一个叫做_dad_的属性将他指向Animal.Dad;
    Animal.call(animal,'dog');//这时animal拥有了Animal函数上的所有方法属性
    当我们调用animal.breath()时这个方法本身是不存在的,去内部属性_dad_上找,发现有
    这时实际的过程则是:Animal.Dad.breath.call(animal);
    到这里我们实际上已经解决了对象继承的初步,
    那么在JAVASCRIPT里,Animal函数的Dad的真名叫做prototype,而animal实例的内部属性_dad_在标准浏览器里名字则是__proto__;
     
    //再接下来我们试试创造一个叫做Dog的方法
    var Dog=new Function(){
      
    }
    Dog.prototype.wangwang=function(){
    console.log('wangwang')
    }
    这时我们的Dog拥有了自己的Dad对象上有一个方法叫做wangwang
    那么我们现在想让这个Dog对象拥有Animal对象的方法breath
    Dog.prototype.breath=Animal.prototype.breath;
    这是一种解决方案,
    如果有很多方法都想继承过来
    我们可以循环遍历,这是一种办法
    还有没有其他方法呢
    Dog.prototype=Animal.prototype;
    Dog.prototype.wangwang=function(){
    console.log('wangwang')
    }
    似乎可以,但是很快发现这不是继承,这是修改
    如何让Dog.prototype指向一个有Animal方法的对象,同时却不会破坏Animal.prototype呢
    方法是有的,我们需要在Dog.prototype和Animal.prototype之间创建一个关联对象,我们叫他海龟HG
     
    var HG=function(){
    }
    HG.prototype=Animal.prototype;//让HG拥有Animal上的所有原型方法
    var hg=new HG();//创建一个HG对象,它拥有了Animal的原型方法
    Dog.prototype=hg;//将Dog函数的原型指向实例,hg
     
    //接下来我们调用
    var xiaohuier=new Dog('xiaohuier');
    xiaohuier.breath();//此时就像上面讲的创建对象时的第三步,追溯到了HG(也是Animal)原型方法
    //修改时
    Dog.prototype.eatBone=funciton(){
     
    }//等价于hg.eatBone,这时Animal的原型已经被HG成功了分开了。
     
    //最后我们把这个继承封装成一个函数
    function extend(child,parent){
    var F=function(){
    }
    F.prototype=parent.prototype;
    child.prototype=new F();
    }
     
     
  • 相关阅读:
    判断表字段是否存在default约束
    在Eclipse mars 4.5.2 中安装spring 插件 spring tool suite
    MySql (mysql-5.6.37) 在Windows的安装及使用
    在CentOS7.2中搭建Tomcat9 并启用http/2 协议
    CentOS 7.2 中 Kafka,Zookeeper的单机部署,伪分布式部署以及真正的分布式部署
    博客歇菜后的总结
    通过WiFi连接手机(device), 出去数据线的烦恼
    Android Studio 使用三星 Note4 真机调试
    在Mac team 工作的那段日子里(一)
    又到年底了,没钱回家咋办?
  • 原文地址:https://www.cnblogs.com/tom-chang/p/5591474.html
Copyright © 2011-2022 走看看