zoukankan      html  css  js  c++  java
  • javascript构造函数与原型

    http://www.link888.cn/index.php?load=read&id=500

    对Javascript来说,方法在本质上也是一种属性。

    构 造方法 和构造属性一样,它是分别存储于每个实例之中的,相互之间是完全独立。

    原型方法 和原型属性一样,他是存储于原型中的,每个实例中存储的实际上一 个指向原型的指针。

    所有对原型方法的修改会影响到所有实例,而构造方法实际上只能通过实例来访问和修改,也只会影响到相应的实例。

    先写结论:方法通常应该使用原型模式定义,并且在必要时通过原型来动态重定义,避免使用构造模式定义方法。

     

    看看示例代码吧: 我们首先构造一个简单的类car,定义2个方法,分别是构造方式定义的constructFunction 和 原型方式定义的 prototypeFunction

    function echo(str){document.write('<div>'+str+'<div>');}
     
     function car(){
     this.constructFunction = function(){
     echo('This is constructFunction');
     };
     }
     
     car.prototype.prototypeFunction = function(){
     echo('This is prototypeFunction');
     };
     
     aCar = new car();
     bCar = new car();
     
     aCar.constructFunction();
     aCar.prototypeFunction();
     bCar.constructFunction();
     bCar.prototypeFunction();

    输出结果:

    This is constructFunction
    This is prototypeFunction
    This is constructFunction
    This is prototypeFunction

    原型方法可以随时动态定义和修改,修改的方法当然是通过类的原型访问,通过重新定义原型方法可以影响到类的所有实例:

    aCar = new car();
     bCar = new car();
     
     car.prototype.prototypeFunction = function(){
     echo('This a new prototypeFunction');
     };
     
     aCar.prototypeFunction();
     bCar.prototypeFunction();

    输出结果为:

    This a new prototypeFunction
    This a new prototypeFunction

     

    可以看到,即使在实例已经创建以后,对原型的修改也可以反映到影响到所有实例上来。

    构造方法是无法通过原型来访问的,只能通过实例访问,也只能通过实例来重定义。下面代码尝试修改实例:aCar的方法constructFunction

    aCar = new car();
     bCar = new car();
     cCar = new car();
     
     // car.constructFunction() 尝试通过类或者类的原型访问构造定义的方法是无效的,会报错
     // car.prototype..constructFunction() 尝试通过类或者类的原型访问构造定义的方法是无效的,会报错
     
     aCar.constructFunction = function(){
     echo('This a new constructFunction');
     }
     
     aCar.constructFunction();
     bCar.constructFunction();
     cCar.constructFunction();

    输出结果:

    This a new constructFunction
    This is constructFunction
    This is constructFunction

     

    对实例aCar的构造方法和影响到了aCar而没有影响到其它实例

    事实上,原型方法也是可以通过实例直接修改的,如果直接修改实例的原型方法会出现什么情况呢?

    本 段开头已经指出:“每个实例中原形方法存储的实际上一个指向原型的指针”,如果你尝试修改实例的原型方法,就改变这个指针,使其指向新定义的方法函数;而 原型中的方法定义并没有受到影响。同时,指针既然转向,那么该实例的这个原型方法也就脱离了原型的定义,而成为一个独立方法。 通过下面的代码可以清晰的明白这种过程:

    aCar = new car();
     bCar = new car();
     cCar = new car();
     
     //修改aCar的原型方法 prototypeFunction
     aCar.prototypeFunction = function(){
     echo('This a new prototypeFunction');
     }
     //检查修改结果
     aCar.prototypeFunction();
     bCar.prototypeFunction();
     cCar.prototypeFunction();
     
     //修改原型方法 prototypeFunction ,就会发现奥妙之处了
     car.prototype.prototypeFunction = function(){
     echo('This a new prototypeFunction modified by prototype');
     }
     //检查修改结果
     aCar.prototypeFunction();
     bCar.prototypeFunction();
     cCar.prototypeFunction();


    输出结果:

    //第一段的输出结果
    This a new prototypeFunction                   //在修改aCar的原型方法prototypeFunction时,仅aCar受到了影响
    This is prototypeFunction
    This is prototypeFunction
    //第二段的输出结果
    //我们重新定义了car的原型方法prototypeFunction,但是aCar没有受到影响,aCar的方法prototypeFunction已经脱离了原型的影响。
    This a new prototypeFunction
    This a new prototypeFunction modified by prototype
    This a new prototypeFunction modified by prototype

    注意:直接修改实例的原型方法虽然是可行的,但是会带来代码上的混淆和混乱,要尽可能避免使用这种方式.

  • 相关阅读:
    数据包发送
    linux 进程调度3
    linux 进程调度2
    linux 进程调度1
    进程间通信:信号
    fork vfork clone学习
    跳表
    【转】Linux内存管理综述
    如何优雅的写出链表代码
    This function or variable may be unsafe Consider using xxx instead
  • 原文地址:https://www.cnblogs.com/daishuguang/p/3130621.html
Copyright © 2011-2022 走看看