zoukankan      html  css  js  c++  java
  • javascript对象创建及继承

      1 //******************************************************************************
      2 //创建类的多种方式
      3 //------------------------------------------------------------------------------
      4 //1.这种创建模式类似于c#中的静态类,不能创建实例,成员都是属于类的.在全局中只有一个.
      5 var class1= {
      6     item1:'item1.value',
      7     item2:'item2,value',
      8     func1:function(){
      9         console.log('我是在创建类时就创建的方法');
     10     }
     11 }
     12 //这种类不能直接使用prototype属性去添加类成员,且class1的__proto__(原型对象:这个东西
     13 //暂时不做解释,会在下面的继承中解释)是Object对象
     14 //因为Object对象是一个基对象,不存在父级,所以这个方法没法去添加修改
     15 //class_name.prototype.method_name = function(first_argument) {
     16     // body...
     17 //};
     18 //如果这个类再添加属性的话,可以直接编写类方法
     19 class1.func2 = function() {
     20     // body...
     21     console.log('我是创建类后扩充的方法');
     22 };
     23 //------------------------------------------------------------------------------
     24 //2.构造函数创建类的形式.也可以直接写成 function class2(i1,i2).这样创建类的方式就
     25 //  相当于创建了一个非静态的类,需要使用 new 关键字来实例,如果不用 new关键字实例,
     26 //  则里面的this则为父级this,可能就会成为window对象
     27 function class2(i1,i2){
     28     this.item1=i1;
     29     this.item2=i2;
     30     this.fun1=function(){
     31         console.log('我是在创建类时就创建的方法');
     32     }
     33 }
     34 //添加静态方法的形式,使用这种方式添加的类成员在 new 出的对象中是不存在的,其实就相
     35 //当于重新创建了一个重名的class2的静态类,当然如果使用 new 关键字去创建,则相当于创
     36 //建了一个新的class2.func2对象
     37 class2.func2 = function(i1,i2)
     38 {
     39     this.item1=i1;//如果使用的是class2.func2()的调用形式,这这里的this指的是class2这个静态类
     40     this.item2=i2;//如果使用的是fun2 = new class2.func2(); 那么这里的this指的是fun2这个对象,
     41     console.log('我是创建类后扩充的方法:直接使用[类名.属性=function]方式创建的');
     42 }
     43 //这种方式是在创建的对象中去添加方法的扩展形式,这些方法被扩展在创建的对象中的__proto__ (原型对象)
     44 //属性中,当然创建的对象也可以直接使用这个方法.这个里面的this依然指向创建的对象
     45 class2.prototype.func2 = function(i1,i2) {
     46     // body...
     47     this.item1=i1;
     48     this.item2 = i2;
     49     console.log('我是创建类后扩充的方法:使用prototype属性扩充的方法');
     50 };
     51 //--------------------------------------------------------------------------------
     52 //3.使用new Object()创建对象,这种创建对象的形式和第一种类似,一样是一个静态的方法
     53 //  这种方式在使用过程中,类中定义的成员在编写的时候可能不在一起,结构不太清晰.(个人不太推荐使用这种方式扩展)
     54 var class3 = new Object();
     55 class3.item1='123';
     56 class3.item2='345';
     57 class3.func1=function(){
     58     console.log('我是在创建类时就创建的方法');
     59 }
     60 //这个地方就不在做解释为什么不可以了,详情可以去看一下案例1
     61 //class3.prototype.func2 = function(i1,i2) {
     62 //    this.item1=i1;
     63 //    this.item2 = i2;
     64 //    console.log('我是创建类后扩充的方法:使用prototype属性扩充的方法');
     65 //};
     66 //---------------------------------------------------------------------------------
     67 //4.使用构造函数方法去创建对象,这种创建形式是不需要new的,但是这种形式创建的类也是没
     68 //  较好的方法去扩展的,其实这个对象并不是class4,而是的到的一个object对象.
     69 //  如果不做继承的情况下可以使用这个方式,(个人不太推荐这种使用方式,扩展性过差)
     70 function class4(i1,i2)
     71 {
     72     var o =new Object();
     73     o.item1=i1;
     74     o.item2=i2;
     75     o.func1=function(){
     76         console.log('我是在创建类时就创建的方法');
     77     }
     78     return o;
     79 }
     80 //----------------------------------------------------------------------------------
     81 //**********************************************************************************
     82 //类的继承
     83 //个人心得:
     84 //    在js中没有过于明确的继承写法.继承写法页多种多样.网上一搜一大堆.在这里我在
     85 //    写出的案例中主要是应用了__proto__(原型对象),和call()添加静态方法
     86 //个人解释:
     87 //    __proto__[原型对象]:
     88 //        这个对象其实是指向这个对象到底都是什么,我们如果打开调试工具去查看这个对象,会发现这个对象有可能还有一个__proto__属性
     89 //        但是我们按照层级去一级一级的找下去,发现最后一层必然是Object对象,然而Object是没有__proto__属性的,这也就是说为什么在上
     90 //        面的静态类是没有办法使用prototype属性去扩展的原因.prototype其实是把方法添加到了他的上一层的对象中.当然也可以在当前对
     91 //        象中使用.这也就是说为什么在我的继承方式中会用到prototype属性去设置对象的__proto__
     92 //    call()[这个方法是用于改变this指向的]:
     93 //        obj.call(this[,paras]);这个方法是用于改变this的指向,意思是在obj方法在调用的过程中改变其中的this对象.当然我们也可以在call方法调用的时候传递参数.传递时在this后面追加.
     94 //        下面我们会举例说明call方法的作用
     95 //----------------------------------------------------------------------------------
     96 //1.call()方法作用
     97 var i1=10,i2=10;//创建两个变量,这两个变量是属于window的,我们全局的this其实就是window
     98 function test()
     99 {
    100     console.log('i1+i2='+(this.i1+this.i2));//我们输出,i1与i2的和;这里要记得写 this.i1 不要直接写 i1.因为 call方法只是改变this,单纯的写i1指的还是window下的i1
    101 }
    102 test();//先执行一次,看下输出结果
    103 var obj ={i1:20,i2:20};
    104 test.call(obj);//这时候我们使用call方法,这个方法中我们传入一个对象,这个对象中有i1和i2两个属性值为20,看一下输出结果为40
    105 //解释:在第一次执行的时候test方法中的 this 是 window对象,在使用 call方法后,test中的this 变化成了 obj对象
    106 //-----------------------------------------------------------------------------------
    107 //2.类的继承正题
    108 /*
    109 父级类:包含属性有名称/长度/高度/体重
    110 */
    111 function Animal(){
    112     this.name='';
    113     this.length = 0;
    114     this.height = 0;
    115     this.weight = 0;
    116     this.hello=function(){
    117         console.log("我是"+this.name+'...');
    118     }
    119 }
    120 /*
    121 子类:包含游泳方法/并且重写父级的hello方法
    122 */
    123 function Duck(){
    124     //for(var item in this.__proto__)
    125     //{
    126     //    eval('this.'+item+'= this.__proto__[item]');
    127     //    console.log(item);
    128     //};
    129     var base = this.__proto__ = new Animal();//注解1
    130     Animal.call(this);//注解2
    131     this.hello=function(){
    132         console.log("我是"+this.name+",我是一只小鸭子.");
    133         base.hello.call(this);//注解3
    134     }
    135     this.swim =function(){
    136         console.log('我在游泳')
    137     }
    138 }
    139 //[注解]
    140 //1:把duck对象的原型对象设置为一个新的Animal对象,并且存到base变量中,用于让子集重写父级方法时调用父级方法使用.
    141 //2:把当前的duck对象的this 放入 Animal方法中去执行,这样的话 duck中的this 就可以被附上Animal类中同样的成员从而实现继承
    142 //3:因为base里面存放的是一个Animal对象,这样的话如果直接执行base.hello的话,base的this是Animal.
    143 //  然而我们现在并不是想输出Animal对象的name属性,而是输出duck对象的name属性,所以这个地方用call方法替换base.hello的this为duck对象
    144 //--------------------------------------------------------------------------------------
    145 //3.继承中的方法扩展测试
    146 Duck.prototype.getWeight=function(){
    147     console.log(this.weight);
    148 }
    149 //说明:如果按照上面的继承方式,Duck的__proto__对象被改变为了Animal,所以在此之前使用prototype向__proto__中添加的方法就被覆盖了.
    150 //     所以就没有办法添加到Duck类中了.如果想通过prototype属性添加方法的情况下,则需要把Duck方法中的注释去除,执行遍历语句.
    151 //     先把扩展方法添加到this对象中,然后再去替换__proto__对象中的内容
    152 //建议:
    153 //     这里就建议在创建类的时候直接把里面的属性方法创建完全,尽量不要使用prototype这种方式去扩充成员.
    154 //     因为这种形式是在当前对象的__proto__(原型对象)中去添加的.
  • 相关阅读:
    幂等性知识学习梳理
    使用Less,FontAwesome 重写EasyUI TreeGrid样式
    根据表达式树动态生成Lambda表达式
    elasticsearch-query-builder, 一款可以基于配置化以及参数绑定的ES语句构造神器
    hadoop2 5个环境配置文件
    hadoop3.0.0 分布式集群安装过程
    linux 常用命令
    securecrt 常用快捷键
    java 面试题
    Spark Streaming 读取 Kafka 数据的两种方式
  • 原文地址:https://www.cnblogs.com/flybeijing/p/9293786.html
Copyright © 2011-2022 走看看