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

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

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();
  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);

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

如何理解并学习javascript中的面向对象(OOP) [转]的更多相关文章

  1. 简单分析JavaScript中的面向对象

    初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...

  2. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  3. 前端开发:面向对象与javascript中的面向对象实现(一)

    前端开发:面向对象与javascript中的面向对象实现(一) 前言: 人生在世,这找不到对象是万万不行的.咱们生活中,找不到对象要挨骂,代码里也一样.朋友问我说:“嘿,在干嘛呢......”,我:“ ...

  4. 理解和使用 JavaScript 中的回调函数

    理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报  分类: JavaScript(4)    目录( ...

  5. 前端开发:javascript中的面向对象

    前端开发:面向对象与javascript中的面向对象实现(一) 面向对象理解: 面向对象是一种对现实世界理解和抽象的方法,是一种先进的程序设计理念,是一种比较抽象的,多形态的设计模式.我们可以这么理解 ...

  6. [转]理解与使用Javascript中的回调函数

    在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...

  7. 【JavaScript】理解与使用Javascript中的回调函数

    在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...

  8. JavaScript从初见到热恋之深度讨论JavaScript中的面向对象。

    JavaScript中的面向对象.面向对象的三个基本特征:封装.继承.多态. 1.封装 js的封装如下 定义Person类 function Person(name,age,sex) { this.n ...

  9. 理解与使用Javascript中的回调函数

    在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...

随机推荐

  1. @SpringContext通过实现ApplicationContextAware接口动态获取bean

    场景: 在代码中需要动态获取spring管理的bean 目前遇到的主要有两种场景:1.在工具类中需要调用某一个Service完成某一个功能,如DictUtils2.在实现了Runnable接口的任务类 ...

  2. @Java中使用Jedis操作Redis之一

    依赖的jar包:jedis <dependency> <groupId>redis.clients</groupId> <artifactId>jedi ...

  3. WhyEngine游戏合集2014贺岁版

    WhyEngine游戏合集2014贺岁版 自去年9月份开始写我的第一个小游戏,到现在为止,共实现了14个小游戏,10个屏保程序,7个DEMO程序.开发环境是VS2008,渲染使用的是D3D,所有代码都 ...

  4. HDU4183 起点到终点再到起点 除起点每点仅经过一次 网络流

    题意: T个测试数据 n个圆 下面 fre x y r 表示圆的频率 坐标和半径 要求: 从频率为400(最小的) 圆 走到频率为789(最大)的圆,再走回来,除起点每个点只能经过一次 问这样的路径是 ...

  5. 根据外网ip地址定位用户所在城市

    package com.henu.controller; import java.io.BufferedReader; import java.io.DataOutputStream; import ...

  6. nginx配置解决vue单页面打包文件大,首次加载慢的问题

    cnpm run build 文件过大,其中主要是vender.js有1.5M,代码部署到服务器,首次访问加载页面时比较慢,耗时6.5s左右,所以需要优化下. 1.Nginx开启gzip 找到ngin ...

  7. Inner Classes with TypeScript

    原文:https://blog.oio.de/2014/03/21/inner-classes-typescript/ b.ts class Foo { sex:string; say(){ new ...

  8. 取消Eclipse SVN的自动链接方式

    1. 选中指定的项目名(有文件夹样子的那个) 2. 右键,在在弹出菜单选择 Team 3. 然后再点击, Disconnect 即可.

  9. php5.2以下版本无json_decode函数的解决办法

    function json_decode2($json) { $comment = false; $out = '$x=';   for ($i=0; $i<strlen($json); $i+ ...

  10. 【Javascript Demo】无刷新预览所选择的图片

    1.效果如下,可测试 2.代码如下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...