zoukankan      html  css  js  c++  java
  • 如何理解并学习javascript中的面向对象(OOP) [转]

    如果你想让你的javascript代码变得更加优美,性能更加卓越。或者,你想像jQuery的作者一样,写出属于自己优秀的类库(哪怕是基于 jquery的插件)。那么,你请务必要学习javascript面向对象,否则你无法更灵活的使用javascript这门语言。

    什么事闭包?到底什么是原型?(知道闭包和原型的,就算得上是javascript的高手了。但真正能够理解,并且灵活运用的人并不多)到底该如何学习javascript中的面向对象呢?在javascript这么语言正如日中天,相信不少人正在为此而困惑。

    本文中,我讲用代码+详细注释的方式,一行行一步步讲述javascript中的面向对象编程。当然有些只是我个人的理解,不足之处,敬请谅解!

    1.下面部分的代码,将是从目前十分流行的JSON数据格式以及javascript数组,来一步步像大家阐述javascript中的面向对象思想。

      1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      2 <html xmlns="http://www.w3.org/1999/xhtml">
      3 <head>
      4     <title>JSON数据格式</title>
      5     <script src="Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
      6      <script type="text/javascript">
      7          function jsonTest() {
      8              //定义json数据格式 -- 以文本的形式存在,转换为javascript对象或者数组
      9          //对象中可以包含数组,数组中也可以包含对象,可以存在相互嵌套的关系
     10              var json1 = "[1,2,{a:123,b:'str',c:[100,200]}]";//数组形式
     11              var parsejson1 = eval(json1);//将纯文本的内容转换为javascript原生支持的json
     12              var json2 = "{name:'dinglang',age:21,hobby:['武术','电影']}";//对象形式
     13              //var parsejson2 = eval(json2); //这样直接转换会报错 
     14              //当被eval()转换的纯文本json数据为对象形式时,需要在前后加上"()"
     15              var parsejson2 = eval("(" + json2 + ")"); //这样转换就可以了
     16             
     17              alert("");
     18          }
     19 
     20 
     21 
     22 
     23          //探索一下JSON这种数据格式的由来
     24 
     25          //1.首先是回顾一下javascript数组的相关知识
     26          function arrTest() {
     27             // 1)数组的基本定义与赋值
     28              var arrOne = new Array(); //第一种创建方法
     29              var arrTwo =  new Array(0,1,2);//第二种创建方式(创建的时候就给数组赋初始值)
     30              var arrThree = []; //第三种方式 --定义一个空数组
     31              var arrFour = [1, 2, 3, 5]; //第四种方式--定义一个数组,并给数组赋初始值
     32              //创建多维数组
     33              var arrFive = new Array(1, new Array(2, 3), 4, 5); //创建一个多维数组(嵌套的)
     34              var arrSix = [1, [2, 3], 4];//创建一个多维数组
     35              // 2)数组的基本操作(数组是javascript语言中一种很重要的数据结构)
     36              alert(arrSix[1]);  //通过数组下标,来获取数组中对应的某个元素
     37              arrSix[0] = 100; //给数组中下标对应的元素赋值(如果该元素还未创建,就创建该元素并赋值)
     38              arrSix[99] = 888; //arrSix中会自动创建下标为99的元素,并给其赋值 --javascript中数组的长度是可以随时改变的
     39              // 3)javascript当中数组常用的一些方法
     40              //concat方法的使用 --可以做数组的连接或者合并,原数组的内容不变,将返回一个新的数组对象
     41              var arrFour1 = arrFour.concat(101, 102, 103);//第一种连接方式
     42              var arrFour2 = arrFour.concat([104, 105]);//第二种连接方式
     43              var arrFour3 = arrFour.concat(arrFour1); //将已经定义的数组进行连接
     44              //join方法--将数组中元素,按照指定的分隔符连接成字符串输出,原数组的内容不变
     45              //slice方法--返回当前数组中的子数组,原数组中的内容不会改变
     46              //push/pop  在数组的尾端追加(push)或弹出(pop),将会修改原数组的内容
     47              arrFive.push(107);//在数组尾部追加一个元素
     48              arrFive.pop(); //弹出数组中最后一个元素
     49              //在数组的开头追加(shift)和unshift(弹出)操作
     50              arrFive.reverse(); //反转数组中的元素
     51              arrFive.sort(); //按照字母是顺序,对数组中的元素进行升序排列
     52              arrFive.sort(function (a, b) {
     53                  return a - b;
     54              }); //按照数值大小,进行升序排列。如果返回的是负值,那么a就会出现在b的前面
     55              arrFive.sort(function (a, b) {
     56                  return b - a;
     57              }); //按照降序排列
     58              //splice  可以删除数组中一部分元素,并把部分元素进行返回。也可以在指定位置添加元素
     59              var arrSplice1 = arrSix.splice(3, 2); //从下标为3的元素开始删除,删除2个元素
     60              var arrSplice2 = arrSix.splice(4); //从下标为4的元素开始删除,一直删除到数组的末尾
     61              arrSix.splice(1, 0, 401, 402); //在下标为1的元素前面,插入401,402这两个元素
     62              arrSix.splice(1, 0[188, 189]);//在下标为1的元素前面,插入[188,199]
     63          }
     64          
     65          //2.javascript中的对象的定义、使用
     66          var obj1 = new Object(); //定义一个对象
     67          var obj2 = {};  //使用"{}"也可以定义一个对象
     68          //给对象增加属性
     69          obj1.num = 1;
     70          obj1.str = "string";
     71          obj1.sayHello = function () {
     72              alert("Hello");
     73          }
     74          obj2.srcObj = obj1; //将obj1对象作为obj2对象的属性
     75 
     76          //属性的访问 --第一种访问方式
     77          obj1.num; //也可以这么访问  obj2.srcObj.num;
     78          obj1.str;           //obj2.srcObj.str;
     79          obj1.sayHello();   //obj2.srcObj.sayHello();
     80 
     81          //属性的访问 --第二种方式
     82          obj1["num"];        //obj2["srcObj"]["num"];
     83          obj1["str"];        //obj2["srcObj"]["str"];
     84          obj1["sayHello"](); //obj2["srcObj"]["sayHello"]();
     85 
     86          //通过对象直接量的方式,定义和调用对象、属性
     87          var obj3 = {
     88              num: 1,
     89              str: "string",
     90              sayHello: function () {
     91                  alert('Hello');
     92              }
     93          }
     94          //访问方式同上,例如
     95          obj3.num; //obj3["num"];
     96 
     97          //看清楚了吗?这就是javascript中JSON数据格式的原型
     98 
     99 
    100 
    101          //下面来深入讲解javascript语言的面向对象特性
    102          //javascript中定义类,需要用function来模拟
    103 
    104 //         function Teacher(){
    105 //         
    106          //         } 
    107          //建议使用下面这种方法来创建一个类,以便将类和函数区分开来(建议定义类时首字母大写)
    108          var Teacher = function () {
    109 
    110          }
    111          //定义一个book类,这里的function还承担了构造函数的工作
    112          //在使用new操作符创建Book对象时,这个funtion里面的代码将会被执行一次
    113          //this关键字代表的是当前对象
    114          function Book(name) {
    115          //定义公有的属性
    116              this.name = name;
    117              //定义公有的函数
    118              this.getName = function () {
    119                  return this.name;
    120              }
    121              this.setName = function (nname) {
    122                  this.name = nname;
    123              }
    124          }
    125          function ooTest() {
    126              var tech = new Teacher();
    127              alert(tech instanceof Teacher); // instanceof函数,表示是否属于某对象类型
    128              var book1 = new Book("C#");//这里的new操作相当于先创建了一个简单对象,调用了类的构造函数
    129              var book2 = new Book("JAVA");
    130              alert(book1.name);//弹出C#
    131              alert(book2.name);//弹出JAVA
    132              book1.setName(".NET");
    133              alert(book1.name);//弹出.NET
    134              alert(book2.name); //弹出JAVA
    135 
    136              //function上面都有一个原型对象 --prototype
    137              var proto = Book.prototype;
    138              proto.str = "string";
    139              proto.hello = function () {
    140                  alert("Hello");
    141              }
    142              //给原型定义了属性和方法后,拥有这个原型对象的function模拟出来的类,也具有该属性和方法
    143              alert(book1.str); //弹出string
    144              book1.hello(); //弹出hello
    145 
    146          }
    147          
    148      </script>
    149 </head>
    150 <body>
    151 <input  type="button" value="测试json" onclick="jsonTest()"/>
    152 </body>
    153 </html>
    View Code

    2.下面部分代码,是从另外一个角度讲解javascript中的面向对象编程。是借鉴EasyJF开源团队的讲解,我个人做了一些补充和说明。

      1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      2 <html xmlns="http://www.w3.org/1999/xhtml">
      3 <head>
      4     <title>javascript面向对象编程</title>
      5     <script src="Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
      6     <script type="text/javascript">
      7         $(function () {
      8 
      9             //            function animal(name) {
     10             //                this.name = name;
     11             //                this.age = 0;
     12             //            }
     13             //            var a1 = animal;
     14             //            alert(a1);//弹出整个函数体
     15             //            var a2 = animal("dinglang");
     16             //            alert(a2); //弹出undefined
     17             //            var a3 = new animal();
     18             //            alert(a3);//弹出object
     19             //            var a4 = new animal;
     20             //            alert(a4);//弹出object
     21 
     22 
     23             //求值
     24             //alert(sum(1, 3)); //要求弹出结果为4
     25             // alert(sum(1, 3, 5, 4, 7)); //要求弹出结果为20
     26             //根据java或者C#的编程经验,首先想到的是函数重载。
     27             //            function sum(a, b) {
     28             //                return a + b;
     29             //            }
     30             //            function sum(a, b, c, d, e) {
     31             //                return a + b + c + d + e;
     32             //            }
     33             //不幸的是,javascript并不支持函数重载。如果照上面那么写,只有下面的那个函数才会生效
     34 
     35             //javascript支持可变参数的函数
     36             function sum() {
     37 
     38                 var n = 0;
     39                 for (var i = 0; i < arguments.length; i++) {
     40                     n += arguments[i];
     41                 }
     42                 return n;
     43             }
     44 
     45             //javascript高级知识 -- 闭包
     46             //函数里面嵌套函数,且在外部被引用了,所以这个对象i不会被垃圾回收机制清除,所以i递增
     47             function f1() {
     48                 var i = 0;
     49                 var f2 = function () {
     50                     i++;
     51                     alert(i);
     52                 }
     53                 return f2; //f2对象指的是整个函数体
     54             }
     55             var f3 = f1(); // "f1()"就是指该函数的执行结果或者返回值 --f2
     56             //           f3();//1
     57             //            f3();//2
     58             //            f3();//3
     59 
     60 
     61             //作用域与this关键字
     62             //            var obj = new Object();
     63             //            obj.v = "v is a object";
     64             //            //相当于这么写
     65             //           var obj2 = { v: "v is a object" };
     66             //作用域Scope
     67             var b1 = { v: "this is b1" };
     68             var b2 = { v: "this is b2" };
     69             function b(x, y) {
     70                 //  alert(this.v + "," + x + "," + y);
     71             }
     72             b("ding", "lang"); //undefined,"ding","lang" 
     73             //调用b函数时,b函数中的this关键字指的是window对象.而Window对象中没有v对象,所以undefined
     74             //window.b("ding", "lang"); //undefined,"ding","lang"   --与 b("ding", "lang");意义相同
     75             //b.call();//就等于b();
     76             //call函数的第一个参数表示的是函数的上下文 --表示b函数中的this 所以this关键字=b1
     77             // b.call(b1, "ding", "lang"); //this is b1,ding,lang
     78             //注意apply函数的用法:第一个参数表示的也是函数中的上下文。不过后面的参数要以数组的形式传递
     79             // b.apply(b2, ["ding", "lang"]); // //this is b1,ding,lang
     80 
     81             //关于作用域,再补充一点
     82             var b3 = { v: "this is b3",
     83                 sayHello: function () {
     84                     alert(this.v);
     85                 }
     86             }
     87             // b3.sayHello(); //this is b3
     88             //b3.sayHello.call(b1); //会调用b1对象中的sayHello函数  -- this is b1
     89 
     90 
     91             // for ... in
     92             //            var arr = new Array(); //new 一个js数组,与c#、java等编程语言不同,可以不指定长度
     93             //            arr[0] = 1; //赋值
     94             //            arr[1] = 2;
     95             //            arr[2] = 3;
     96             //javascript支持直接定义赋值
     97             var arr = new Array(1, 2, 3);
     98             for (var i = 0; i < arr.length; i++) {
     99                 // alert(arr[i]); //弹出 1,2 ,3 
    100             }
    101             //注意:javascript中的for...in ,看起来与C#或者java中的foreach类似,但是不同
    102             for (var key in arr) {
    103                 // alert(key);// 弹出0,1,2   key指的是键,而不是值。在C#的foreach中,“in”前的变量指的是值
    104                 //alert(arr[key]);//可以使用这种方式取值 --key指的是键,也就是某个对象中包含的所有的对象,而不是值
    105             }
    106             //假如我没有firebug,想使用IE实现类似与firebug控制台中console.dir的功能,可以这样
    107             for (var key in window) {
    108                 // 这样就能将window对象中,包含的全部对象迭代显示出来。也就实现了firebug中console.dir的功能
    109                 //document.getElementById("key").innerHTML += (key + ":" + window[key] + "</br>");
    110             }
    111 
    112             //对象的删除(释放内存-- 在extjs组件中常用)
    113             //            delete b3.v; //删除b3对象中的v成员
    114             //            alert(b3.v); // undefined --因为v这个成员已经被删除了
    115 
    116             //类的修改,扩展(重点,难点)
    117             //1.假如我要实现一个简单的加法计算
    118             //       var numOne = 5;//如果直接这么定义,那么下面的numOne.add(8);执行会报错
    119             //如果我这么写,下面调用就不会报错了(因为此时的numOne,是个类.相当于java或C#语言中原始的基本数据类型、包装类型)
    120             var numOne = new Number(5);
    121             numOne.add = function (numTwo) {
    122                 return this + numTwo;
    123             }
    124             //alert(numOne.add); //undefined
    125             // alert(numOne.add(8));//这样写看起来没错,但是会报错--numOne.add is not a function
    126             var numThree = new Number(100);
    127             //如果我现在想要给numThree对象中也加上add这么一个函数
    128             //直接使用prototype这个特殊的属性来实现,给所有的Number类型实例都加入add函数
    129             Number.prototype.add = function (numTwo) {
    130                 return this + numTwo;
    131             }
    132 
    133             alert(numThree.add(200).add(300)); //弹出600   100+200+300=600  
    134             //说明所有的Number类型确实都具有了add这么一个函数   超级延时绑定--类的扩展
    135 
    136             //小例子 --扩展String类,给所有的String类加上sayILoveYou
    137             //            String.prototype.sayILoveYou = function () {
    138             //                alert(this.toString() + ", I Love You");
    139             //            }
    140             //            var strOne = "dinglang";
    141             //            strOne.sayILoveYou();
    142 
    143             //javascript中的类的用法
    144             //使用构造函数的方式,定义简单的Person类(javascript函数也是一个类)
    145         function Person(name, year) {
    146             this.name = name;
    147             this.year = year;
    148             var _currentYear = 2014;//私有变量
    149             
    150             this.nianLing = function () {
    151                 window.alert("原来方法:姓名:" + this.name + ",今年:" + (_currentYear - this.year) + "岁");
    152             }
    153 
    154             this.getCurrentYear = function () {
    155                 return _currentYear;
    156             }
    157         }
    158 
    159         Person.prototype.duoDaLe = function () {
    160             window.alert("扩展方法:姓名:" + this.name + ",今年:" + (this.getCurrentYear() - this.year) + "岁");
    161         }
    162 
    163         var p = new Person("wyp", 1981);
    164         p.nianLing();
    165         p.duoDaLe();
    166 
    167             //实现javascript中的继承
    168 
    169             function classA(name) {
    170                 this.name = name;
    171                 this.showName = function () {
    172                     alert(this.name);
    173                 }
    174             }
    175             function classB(name) {
    176                 //1)使用newMethod的方式实现继承
    177                 //                this.newMethod = classA;
    178                 //                this.newMethod(name);
    179                 //                delete this.newMethod; //释放对象
    180                 //2)调用claasA这个函数,并把他的上下文(作用域)指向this(也就是classB类的实例)
    181                 //这样也能实现继承效果(使用call或者apply)
    182                 classA.call(this, name);
    183                 //classA.apply(this,[name]);
    184             }
    185             objA = new classA("操作系统");
    186             objB = new classB("组成原理");
    187             objA.showName(); //弹出“操作系统”
    188             objB.showName(); //弹出“组成原理”
    189 
    190         })
    191     </script>
    192 </head>
    193 <body>
    194 <div id="key"> </div>
    195 </body>
    196 </html>
    View Code

    3. function,object

     1         function aa() {
     2 
     3         }
     4         var bb = function () {
     5 
     6         };
     7         var cc = new Function("a", "return a");
     8         var obj1 = new Object();
     9         var obj2 = new Array();
    10         var obj3 = {};
    11         var a = new aa();
    View Code
     1 function Person(name , age) {
     2             this.name = name;
     3             this.age = age;
     4             this.show = function () {
     5                 window.alert(this.name);
     6             }
     7             this.say = say;
     8         }
     9         function say() {
    10             window.alert(this.name);
    11         }
    12         Person.prototype.output = function () {
    13             window.alert(this.name);
    14         };
    15         var person1 = new Person("wyp",33);
    16         var person2 = new Person("wyp", 33);
    17         person1.say();
    18         person1.show();
    19         person1.output();
    20         window.alert(person1 instanceof Person);
    21         window.alert(person1.show == person2.show);
    22         window.alert(person1.say == person2.say);
    23         window.alert(person1.output == person2.output);
    View Code

    http://blog.csdn.net/dinglang_2009/article/details/6911622

  • 相关阅读:
    Zookeeper Acl权限 超级用户权限 怎么跳过ACL密码/账户验证
    白名单与黑名单
    通过mstsc复制粘贴失败需要重新启动RDP剪切板监视程序rdpclip.exe
    go命令帮助
    go build 与go install
    1.Python编程基础
    使用 JMeter 进行压力测试
    js控制手机保持亮屏的库,解决h5移动端,自动息屏问题
    Linux安装配置redis 、启动redis、redis设置密码
    Linux安装部署FTP服务器
  • 原文地址:https://www.cnblogs.com/qiyebao/p/4100295.html
Copyright © 2011-2022 走看看