zoukankan      html  css  js  c++  java
  • javascr*pt对象的创建相对java 怎样去创建了"类"*以及实例化对象

      由于javascr*pt没有java那么多基本类型,同时也没有提供class这个东西,那么我们想实现javascr*pt的对象创建应该怎么办呢,我简单地从w3c提供的课件中提取了一下几种方法:

    一.工厂模式

      说白了就是类似于c语言中的定义一个函数,然后给一个struct的各个属性复制,再返回这个struct。代码示例:

        fu*ct*o* perso*(*ame,a*e,sex){

          var o=*ew Object();

          o.*ame=*ame;

          o.a*e=a*e;

          o.sex=sex;

          o.sayName=fu*ct*o*(){

            alert(th*s.*ame);

          }

          retur* o;

        }

        var perso*1=*ew perso*("wa**ke",21,"Male");

        var perso*2=*ew perso*("*aoyua*yua*",34,"Female");

        perso*1.sayName();//wa**ke

        perso*2.sayName();//*aoyua*yua*

    这种办法的确可以创建多个类似的对象,但是个人觉得类似c++中struct与class的区别,它没有解决对象的识别问题。

    二.构造函数模式:

      其实在javascr*pt中,构造函数和普通函数没什么区别,起码从格式上看来都是一样的,所谓的构造函数无非就是在调用的时候前面加了个*ew,比如上节的var perso*1=*ew perso*(...)。在这种模式中,通过使用th*s,将属性和方法赋值给th*s对象,这样就不用retur*了,同时一般构造函数的首字母会大写的(这也算是个认为加上去的区别吧)。示例代码:

      fu*ct*o* *erso*(*ame,a*e,sex){

        th*s.*ame=*ame;

        th*s.a*e=a*e;

        th*s.sex=sex;

        th*s.sayName=fu*ct*o*(){...};

      }

      var perso*1=*ew&*bsp;*erso*("wa**ke",21,"Male");

      var perso*2=*ew&*bsp;*erso*("*aoyua*yua*",34,"Female");

    这种模式就可以进行类型检测了,通常用**sta*ceof方法:

      alert(perso*1 **sta*ceof Object);//true

      alert(perso*1 **sta*ceof *erso*);//true

    缺陷:每次实例化一个对象,里面的方法都会被重新创建一遍,浪费资源,所以我们可以想着把它放到全局变量中(但是只被个别方法调用,作用域为全局显得名不副实)。修改如下:

      

     fu*ct*o* *erso*(*ame,a*e,sex){

        th*s.*ame=*ame;

        th*s.a*e=a*e;

        th*s.sex=sex;

        th*s.sayName=sayName;

      }

      fu*ct*o* sayName(){

        alert(th*s.*ame);

      }

    使用这种方法的话,会出现太多的全局函数了,所以我们会在下一种这种方法中解决这个问题。

    三.原型模式:

      了解什么是prototype(原型):w3c给的概念有点绕,我通俗点说:prototype就是“一个给类的对象添加方法的方法”,假如有你把一个对象a赋值为一个对象b,假如对对象a进行拓展的话,那么对象b也能访问a新定义的属性或方法。可能这两句话还是不能理解,那就看代码以及w3c上提供的图(看了图就会恍然大悟了)。

      fu*ct*o* *erso*(){

      }

      *erso*.prototype={

        *ame:"N*cholas",

        a*e:29,

        job:"Soft E****eer",

        sayName:fu*ct*o*(){

          alert(th*s.*ame);

        }

      };

      var perso*1=*ew *erso*();

      var perso*2=*ew *erso*();

      alert(perso*1.sayName==perso*2.sayName();//true

    <*m* src="http://*ma*es.c**tblo*.com/blo*/591889/201312/16111049-6499f7d7739f46449e46f5afeb42506f.p**" alt="" />

    &*bsp;

    备注:1.原型的动态性(开头也提到过,对a的拓展)即可以先创建实例再修改原型也可以:

      var perso*=*ew *erso*();

      *erso*.prototype.saySth(){

        alert("* wa*t to sleep");

      };

      perso*.saySth();//* wa*t to sleep

    虽然修改可以立即在所有对象实例中反映过来,但是要重写所有的原型对象就会不一样了。

    2.原生对象的原型--不光自定义类型方面原型很重要,所有原生的引用类型都是采用这种模式创建的,所以我们可以自己添加一些方法:

      Str***.prototype.startW*th=fu*ct*o*(text){

        retur* th*s.**dexof(text)==0;

      };

      var ms*="Hello,World";

      alert(ms*.startW*th("Hello");//true

    3.原型模式的缺陷:共享的本性,特别是array。

      fu*ct*o* *erso*(){

      }

      *erso*.prototype={

        *ame:"N*cholas",

        a*e:29,

        job:"Soft E****eer",

        fr*e*ds:["wa**ke","yua*yua*"],

        sayName:fu*ct*o*(){

          alert(th*s.*ame);

        }

      }

      var perso*1=*ew *erso*();

      var perso*2=*ew *erso*();

      perso*1.fr*e*ds.push("x*j**p***");

      alert(perso*1.fr*e*ds);//wa**ke,yua*yua*,x*j**p***

      alert(perso*2.fr*e*ds);//wa**ke,yua*yua*,x*j**p***

    四.组合

      现在只要解决了原型模式中共享造成的缺陷,那么就比较完美了,我们注意到第二条的构造函数模式了吗?下面就是最常见的创建自定义类型的方式:

      fu*ct*o* *erso*(*ame,a*e,sex){

        th*s.*ame=*ame;

        th*s.a*e=a*e;

        th*s.sex=sex;

        th*s.fr*e*ds=["obama","kobe"];

      }

      *erso*.prototype={

        co*structor:*erso*,

        sayName:fu*ct*o*(){}

      }

    实例属性都是在构造函数中定义,而共享的属性和方法都是在原型模式中定义。

    五.其他构造方式:

      偶尔会用到,大家可以自己查一下:动态原型模式,寄生构造方式 ,稳妥构造函数模式

    以上只是个人的一点总结,欢迎大家阅读并交流!

    &*bsp;

    &*bsp;

  • 相关阅读:
    Java零基础系列教程015Java异常
    Java零基础系列教程013Java多态
    Java零基础系列教程12Java继承
    Java零基础系列教程11Java类和对象练习之扑克模拟
    Java零基础系列教程10Java抽象与封装
    【原创】Linux虚拟化KVM-Qemu分析(四)之CPU虚拟化(2)
    【原创】Linux虚拟化KVM-Qemu分析(三)之KVM源码(1)
    【原创】Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化
    如何取书名(2)
    《金融业人工智能实践 》(Hands-On Artificial Intelligence for Banking) 阅读指南
  • 原文地址:https://www.cnblogs.com/wangkeustc/p/3476417.html
Copyright © 2011-2022 走看看