JavaScript中的面向对象。面向对象的三个基本特征:封装、继承、多态。

1、封装

js的封装如下

定义Person类

  1. function Person(name,age,sex) {
  2. this.name=name;
  3. this.age=age;
  4. this.sex=sex;
  5. this.showinfo=function () {
  6. alert('name:'+name+"age:"+age+"sex:"+sex)
  7. }
  8. }

这个类三个参数 name,age,sex,分别对应的参数的中文名 姓名,年龄,性别

初始化的过程

  1. var person=new Person('马良','31','男');
  2. person.showinfo();

以上就是一个简单的封装就实现了。然而我们对于Person类的定义可能实现了一部分,还要增加一些属性和方法。我们尝试使用原型进行拓展prototype

  1. Person.prototype={eat:function (sth) {
  2. alert("eat" + sth)
  3. },
  4. drink:function (sth) {
  5. alert("drink"+sth)
  6. }};

我们拓展两个方法 eat和drink。然后我们调用

  1. person.eat("干的")
  2. person.drink("湿的")

对于prototype的拓展我们还可以这样写

  1. Person.prototype.eat=function (sth) {
  2. alert("eat" + sth)
  3. };
  4.  
  5. Person.prototype.drink=function (sth) {
  6. alert("drink" + sth)
  7. };

Person.prototype=会覆盖Person.prototype.写的所有的方法和属性。

Person.prototype=需要是对象{},不是[],包括属性和方法。

关于prototype的更多内容,我们可以参考http://www.cnblogs.com/yjf512/archive/2011/06/03/2071914.html

对于方法除了刚才我们在类中定义的方法以外,还有一种方法就是类方法。

  1. Person.newID=function (id) {
  2. alert(id)
  3. }

调用

  1. Person.newID(10000)

这类似于静态方法

2、继承

2.1、js原型(prototype)实现继承

定义Person类

  1. function Person(name,age,sex) {
  2. this.name=name;
  3. this.age=age;
  4. this.sex=sex;
  5. this.showinfo=function () {
  6. alert('name:'+name+"age:"+age+"sex:"+sex)
  7. }
  8. }
  9.  
  10. Person.prototype.eat=function (sth) {
  11. alert("eat" + sth)
  12. };
  13.  
  14. Person.prototype.drink=function (sth) {
  15. alert("drink" + sth)
  16. };

现在我们定义Student类,继承于Person类

  1. function Student() {
  2.  
  3. }
  4. Student.prototype=new Person("马良",31,'男');
  5. Student.prototype.ShowStudentInfo=function () {
  6. alert("Welcome NewStudent")
  7. }

通过prototype来继承Person类,我们来调用

  1. var stu=new Student();
  2. stu.showinfo();
  3. stu.ShowStudentInfo();

2.构造函数实现继承

  1. <SPAN style="FONT-SIZE: 18px"><html>
  2. <body>
  3. <script type="text/javascript">
  4. function Parent(name){
  5. this.name=name;
  6. this.sayParent=function(){
  7. alert("Parent:"+this.name);
  8. }
  9. }
  10.  
  11. function Child(name,age){
  12. this.tempMethod=Parent;
  13. this.tempMethod(name);
  14. this.age=age;
  15. this.sayChild=function(){
  16. alert("Child:"+this.name+"age:"+this.age);
  17. }
  18. }
  19.  
  20. var parent=new Parent("江剑臣");
  21. parent.sayParent(); //输出:“Parent:江剑臣”
  22. var child=new Child("李鸣",24); //输出:“Child:李鸣 age:24”
  23. child.sayChild();
  24. </script>
  25. </body>
  26. </html></SPAN>

3.call , apply实现继承

  1. <SPAN style="FONT-SIZE: 18px"><html>
  2. <body>
  3. <script type="text/javascript">
  4. function Person(name,age,love){
  5. this.name=name;
  6. this.age=age;
  7. this.love=love;
  8. this.say=function say(){
  9. alert("姓名:"+name);
  10. }
  11. }
  12.  
  13. //call方式
  14. function student(name,age){
  15. Person.call(this,name,age);
  16. }
  17.  
  18. //apply方式
  19. function teacher(name,love){
  20. Person.apply(this,[name,love]);
  21. //Person.apply(this,arguments); //跟上句一样的效果,arguments
  22. }
  23.  
  24. //call与aplly的异同:
  25. //1,第一个参数this都一样,指当前对象
  26. //2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)
  27.  
  28. var per=new Person("武凤楼",25,"魏荧屏"); //输出:“武凤楼”
  29. per.say();
  30. var stu=new student("曹玉",18);//输出:“曹玉”
  31. stu.say();
  32. var tea=new teacher("秦杰",16);//输出:“秦杰”
  33. tea.say();
  34.  
  35. </script>
  36. </body>
  37. </html></SPAN>

3、多态

多态就比较简单了,之前我们定义的方法如下

  1. Person.prototype.eat=function (sth) {
  2. alert("eat" + sth)
  3. };

现在我们进行重写实现多态

  1. Person.prototype.eat=function () {
  2. };

大功告成。希望大家受益。

4、call和apply的用法(详细介绍)

js中call和apply都可以实现继承,唯一的一点参数不同,func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])。

JS手册中对call的解释:

  1. <SPAN style="FONT-SIZE: 18px">call 方法
  2. 调用一个对象的一个方法,以另一个对象替换当前对象。
  3.  
  4. call([thisObj[,arg1[, arg2[, [,.argN]]]]])
  5.  
  6. 参数
  7. thisObj
  8. 可选项。将被用作当前对象的对象。
  9.  
  10. arg1, arg2, , argN
  11. 可选项。将被传递方法参数序列。
  12.  
  13. 说明
  14. call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
  15.  
  16. 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。</SPAN>

说简单一点,这两函数的作用其实就是更改对象的内部指针,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。下面以apply为例,说说这两个函数在 js中的重要作用。如:

  1. <SPAN style="FONT-SIZE: 18px"> function Person(name,age){ //定义一个类
  2. this.name=name; //名字
  3. this.age=age; //年龄
  4. this.sayhello=function(){alert(this.name)};
  5. }
  6. function Print(){ //显示类的属性
  7. this.funcName="Print";
  8. this.show=function(){
  9. var msg=[];
  10. for(var key in this){
  11. if(typeof(this[key])!="function"){
  12. msg.push([key,":",this[key]].join(""));
  13. }
  14. }
  15. alert(msg.join(" "));
  16. };
  17. }
  18. function Student(name,age,grade,school){ //学生类
  19. Person.apply(this,arguments);//比call优越的地方
  20. Print.apply(this,arguments);
  21. this.grade=grade; //年级
  22. this.school=school; //学校
  23. }
  24. var p1=new Person("卜开化",80);
  25. p1.sayhello();
  26. var s1=new Student("白云飞",40,9,"岳麓书院");
  27. s1.show();
  28. s1.sayhello();
  29. alert(s1.funcName);</SPAN>

另外,Function.apply()在提升程序性能方面有着突出的作用:
我们先从Math.max()函数说起,Math.max后面可以接任意个参数,最后返回所有参数中的最大值。
比如

  1. <SPAN style="FONT-SIZE: 18px">alert(Math.max(5,8)); //8
  2. alert(Math.max(5,7,9,3,1,6)); //9
  3.  
  4. //但是在很多情况下,我们需要找出数组中最大的元素。
  5.  
  6. var arr=[5,7,9,1];
  7. //alert(Math.max(arr)); // 这样却是不行的。NaN
  8.  
  9. //要这样写
  10. function getMax(arr){
  11. var arrLen=arr.length;
  12. for(var i=0,ret=arr[0];i<arrLen;i++){
  13. ret=Math.max(ret,arr[i]);
  14. }
  15. return ret;
  16. }
  17.  
  18. alert(getMax(arr)); //9
  19.  
  20. //换用apply,可以这样写
  21. function getMax2(arr){
  22. return Math.max.apply(null,arr);
  23. }
  24.  
  25. alert(getMax2(arr)); //9
  26.  
  27. //两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。
  28.  
  29. //再比如数组的push方法。
  30. var arr1=[1,3,4];
  31. var arr2=[3,4,5];
  32. //如果我们要把 arr2展开,然后一个一个追加到arr1中去,最后让arr1=[1,3,4,3,4,5]
  33. //arr1.push(arr2)显然是不行的。 因为这样做会得到[1,3,4,[3,4,5]]
  34.  
  35. //我们只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身)
  36.  
  37. var arrLen=arr2.length;
  38. for(var i=0;i<arrLen;i++){
  39. arr1.push(arr2[i]);
  40. }
  41.  
  42. //自从有了Apply,事情就变得如此简单
  43.  
  44. Array.prototype.push.apply(arr1,arr2); //现在arr1就是想要的结果</SPAN>

5、this的指向问题

  1. function Person(name,age,sex) {
  2. this.name = name;
  3. this.age = age;
  4. this.sex = sex;
  5. this.showinfo = function () {
  6. alert('name:' + name + "age:" + age + "sex:" + sex)
  7. }
  8. }

this指向当前的环境。现在结合案例来说

1、当前的环境指向person,所以person就是this

var person=new Person('马良','22','男');

person.showinfo()

2、Person('马良','22','男')

window.showinfo()

当前的环境指向window,所以window能调用showinfo

3、使用call或者apply改变this的指向

var o={};

Person.call(o,"马良",22,"男");

JavaScript从初见到热恋之深度讨论JavaScript中的面向对象。的更多相关文章

  1. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  2. JavaScript中的面向对象的讨论(转)

    前言 今天,WEB2.0时代的到来,给了JavaScript又一次大展身手的机会.Web2.0借助JavaScript技术,使得客户端的Web体验更加丰富多彩,同时JavaScript面对的问题域也变 ...

  3. 深度解析javaScript常见数据类型检查校验

    前言 在JavaScript中,数据类型分为两大类,一种是基础数据类型,另一种则是复杂数据类型,又叫引用数据类型 基础数据类型:数字Number 字符串String 布尔Boolean Null Un ...

  4. 再次讨论javascript 中的this

    原文: http://www.jb51.net/article/77519.htm 核心总结: 1.不论函数在哪里被调用,只要没有指定调用方,则this都指向window.指定了调用方,就指向调用方. ...

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

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

  6. 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统

    面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...

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

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

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

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

  9. 深度理解Jquery 中 offset() 方法

    参考原文:深度理解Jquery 中 offset() 方法

随机推荐

  1. IDEA常见设置

    对于eclipse实在忍无可忍,各种功能各种bug..换回IDEA IDEA常见问题(其实不是问题,代码规范而已) 1.解决无限 This file is indented with tabs ins ...

  2. MT【224】反解系数

    (2011安徽省赛)$f(x)=ax^3+bx+c(a,b,c\in R),$当$0\le x \le 1$时,$0\le f(x)\le 1$,求$b$的可能的最大值. 提示:取三个点$f(0),f ...

  3. 自学Python5.2-类和对象概念

    自学Python之路 自学Python5.2-类和对象概念 面向对象编程的2个非常重要的概念:类和对象 对象是面向对象编程的核心: 在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出 ...

  4. Prometheus-operator架构详解

    Prometheus是一个开源的系统监视和警报工具.一款非常优秀的监控工具.监控方案:Prometheus 提供了数据搜集.存储.处理.可视化和告警一套完整的解决方案. Prometheus的关键特性 ...

  5. luogu4849 寻找宝藏 (cdq分治+dp)

    设f[i]是已经走到i号点的值. 先要给第四维离散化.然后去重 第一维排序,第二维cdq分治,第三维cdq分治,第四维树状数组,找到满足j(x,y,z,w)<=i(x,y,z,w)的j,给i统计 ...

  6. 手动实现staticmethod和classmethod装饰器

    首先,staticmethod和classmethod装饰器是通过非数据描述符实现的.用法简单,这里就不细说了. 这里主要分析一下staticmethod和classmethod是如何通过描述符实现的 ...

  7. SQL Server 查

    注:where语句是条件,后面加and或者or 时间日期:比时间需要时间加引号 模糊查询:where语句后面加like  '%包含此关键字%'或者'以此关键字开头%'或者'%结尾' 排序查询:列名 o ...

  8. 【SPOJ10628】Count on a tree

    题目大意:给定一棵 N 个节点的树,点有点权,要求回答 M 个询问,每次询问点 u 到点 v 的简单路径(链)上权值第 K 小是多少. 题解:学习到了树上主席树. 主席树维护序列时,每次将后一个点的树 ...

  9. 收藏:FLASH中键检测与右键屏蔽

    原文:http://space.flash8.net/space/?591172/viewspace-708726.html <!DOCTYPE html PUBLIC "-//W3C ...

  10. 元组&哈希&字典

    1.元组(1)特性:不可变(不能修改.添加.删除),可以做切片 元组本身不可变,如果元组中还包含其他可变元素,这些可变元素可以改变(元组里套用列表,列表中的值可变)(2)功能: index count ...