• 如何理解并学习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

  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/qiyebao/p/4100295.html
Copyright © 2020-2023  润新知