zoukankan      html  css  js  c++  java
  • Javascript中的prototype

    Js中的prototype

    一直对prototype理解的不深,只是晓得如果一个类(实际上是类的构造函数)通过prototype来定义一个函数,那么通过这个类衍生的实例就可以直接使用这个方法。比如:

    function Person(name){

       this.name=name; 

       this.showMe=function(){ 

               alert(this.name);

            } 

    };  

    Person.prototype.from=function() {  

      alert('I come from prototype.'); 

    }       

    var one=new Person('js'); 

    one.showMe();//js

    one.from();//I come from prototype.

    One实例就能直接调用prototype定义的函数from。但是更深入的原理不是很清楚。比如上周就出了用new出来的对象使用prototype这样的错误,下来后就对prototype进行了深入的学习。

    我们在定义函数的时候,函数定义的时候函数本身就会默认有一个prototype的属性,prototype属性又指向了一个prototype对象。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身。如图:

    而我们如果用new 运算符来生成一个对象的时候就没有prototype属性。例如

     function Person(name){ 

        this.name=name; 

        this.showMe=function() 

             { 

                alert(this.name); 

             } 

     };

     var one=new Person('js'); 

     alert(one.prototype)//undefined 

     alert(typeof Person.prototype);//object 

     alert(Person.prototype.constructor);//function Person(name) {...};

    再回到第一个例子中,当new操作进行的时候,为什么one可以直接掉用from函数,就要仔细研究一下new这个操作符了。

    new形式创建对象的过程实际上可以分为三步:

    第一步是建立一个新对象(叫A吧);

    第二步将该对象(A)内置的原型对象设置为构造函数(就是Person)prototype 属性引用的那个原型对象;

    第三步就是将该对象(A)作为this 参数调用构造函数(就是Person),完成成员设置等初始化工作。

    其中第二步中内置的原型对象,跟prototype对象不是一回事,叫__proto__,__proto__就指向了函数Person的prototype对象。在person的prototype对象中出现的任何属性或者函数都可以在one对象中直接使用,这个就是javascript中的原型继承了。

    发现prototype对象包含了2个属性,一个是constructor ,另外一个是__proto__。这个constructor 就是我们的构造函数,上面说过了,那这个__proto__就是内置原型对象。

    这个就涉及到了原型链的概念:

      每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去。

    按照这样的解释,var one=new Person('js');这个语句执行的过程可以分成下面的语句:

    var one={};

    one.__proto__=Person.prototype;

    Person.call(one,'js');

    这样one对象通过内置的原型对象__proto__就可以直接访问Person的prototype对象中的任何属性与方法了。这也就解释了上面的代码中为什么one可以访问form函数了。因为prototype对象中有一个constructor属性,那么one也可以直接访问constructor属性。

    接着看继承是如何实现的。

    继承的实现很简单,只需要把子类的prototype设置为父类的一个对象即可。那么通过prototype属性实现继承的原理是什么呢。

    function Person(name){

       this.name=name;

       this.showMe=function()

            {

               alert(this.name);

            }

    };

    Person.prototype.from=function(){

      alert('I come from prototype.');

    }

    function SubPerson(){

    }

    SubPerson.prototype=new Person();

    var subOne=new SubPerson();

    subOne.from();//I come from prototype.

    alert(subOne.constructor);//function Person(name) {...};

    alert(SubPerson.prototype.constructor);//function Person(name) {...};

  • 相关阅读:
    398. Random Pick Index
    382. Linked List Random Node
    645. Set Mismatch
    174. Dungeon Game
    264. Ugly Number II
    115. Distinct Subsequences
    372. Super Pow
    LeetCode 242 有效的字母异位词
    LeetCode 78 子集
    LeetCode 404 左叶子之和
  • 原文地址:https://www.cnblogs.com/fredshare/p/2810878.html
Copyright © 2011-2022 走看看