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

1、封装

js的封装如下

定义Person类

        function  Person(name,age,sex) {
this.name=name;
this.age=age;
this.sex=sex;
this.showinfo=function () {
alert('name:'+name+"age:"+age+"sex:"+sex)
}
}

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

初始化的过程

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

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

        Person.prototype={eat:function (sth) {
alert("eat" + sth)
},
drink:function (sth) {
alert("drink"+sth)
}};

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

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

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

 Person.prototype.eat=function (sth) {
alert("eat" + sth)
}; Person.prototype.drink=function (sth) {
alert("drink" + sth)
};

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

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

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

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

Person.newID=function (id) {
alert(id)
}

调用

Person.newID(10000)

这类似于静态方法

2、继承

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

定义Person类

        function  Person(name,age,sex) {
this.name=name;
this.age=age;
this.sex=sex;
this.showinfo=function () {
alert('name:'+name+"age:"+age+"sex:"+sex)
}
} Person.prototype.eat=function (sth) {
alert("eat" + sth)
}; Person.prototype.drink=function (sth) {
alert("drink" + sth)
};

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

 function Student() {

        }
Student.prototype=new Person("马良",31,'男');
Student.prototype.ShowStudentInfo=function () {
alert("Welcome NewStudent")
}

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

            var stu=new  Student();
stu.showinfo();
stu.ShowStudentInfo();

2.构造函数实现继承

<SPAN style="FONT-SIZE: 18px"><html>
<body>
<script type="text/javascript">
function Parent(name){
this.name=name;
this.sayParent=function(){
alert("Parent:"+this.name);
}
} function Child(name,age){
this.tempMethod=Parent;
this.tempMethod(name);
this.age=age;
this.sayChild=function(){
alert("Child:"+this.name+"age:"+this.age);
}
} var parent=new Parent("江剑臣");
parent.sayParent(); //输出:“Parent:江剑臣”
var child=new Child("李鸣",24); //输出:“Child:李鸣 age:24”
child.sayChild();
</script>
</body>
</html></SPAN>

3.call , apply实现继承

<SPAN style="FONT-SIZE: 18px"><html>
<body>
<script type="text/javascript">
function Person(name,age,love){
this.name=name;
this.age=age;
this.love=love;
this.say=function say(){
alert("姓名:"+name);
}
} //call方式
function student(name,age){
Person.call(this,name,age);
} //apply方式
function teacher(name,love){
Person.apply(this,[name,love]);
//Person.apply(this,arguments); //跟上句一样的效果,arguments
} //call与aplly的异同:
//1,第一个参数this都一样,指当前对象
//2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以) var per=new Person("武凤楼",25,"魏荧屏"); //输出:“武凤楼”
per.say();
var stu=new student("曹玉",18);//输出:“曹玉”
stu.say();
var tea=new teacher("秦杰",16);//输出:“秦杰”
tea.say(); </script>
</body>
</html></SPAN>

3、多态

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

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

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

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

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

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

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

JS手册中对call的解释:

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

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

<SPAN style="FONT-SIZE: 18px"> function Person(name,age){   //定义一个类
this.name=name; //名字
this.age=age; //年龄
this.sayhello=function(){alert(this.name)};
}
function Print(){ //显示类的属性
this.funcName="Print";
this.show=function(){
var msg=[];
for(var key in this){
if(typeof(this[key])!="function"){
msg.push([key,":",this[key]].join(""));
}
}
alert(msg.join(" "));
};
}
function Student(name,age,grade,school){ //学生类
Person.apply(this,arguments);//比call优越的地方
Print.apply(this,arguments);
this.grade=grade; //年级
this.school=school; //学校
}
var p1=new Person("卜开化",80);
p1.sayhello();
var s1=new Student("白云飞",40,9,"岳麓书院");
s1.show();
s1.sayhello();
alert(s1.funcName);</SPAN>

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

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

5、this的指向问题

        function Person(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.showinfo = function () {
alert('name:' + name + "age:" + age + "sex:" + sex)
}
}

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. G1收集器的收集原理

    G1收集器的收集原理 来源 http://blog.jobbole.com/109170/ JVM 8 内存模型 原文:https://blog.csdn.net/bruce128/article/d ...

  2. adb is down 的解决方法

    今天装完android Eclipse 之后 ,运行时报出这么个错误 : The connection to adb is down, and a severe error has occured.  ...

  3. 【BZOJ4903】【UOJ#300】吉夫特(卢卡斯定理,动态规划)

    [BZOJ4903][UOJ#300]吉夫特(卢卡斯定理,动态规划) 题面 UOJ BZOJ:给的UOJ的链接...... 题解 首先模的质数更小了,直接给定了\(2\).当然是卢卡斯定理了啊. 考虑 ...

  4. matplotlib 刻度,坐标轴不可见

    plt.gray():只有黑白两色,没有中间的渐进色 1. 关闭坐标刻度 plt.xticks([]) plt.yticks([]) 关闭坐标轴: plt.axis('off') 注意,类似的这些操作 ...

  5. SpringBoot集成RocketMQ

    实战,用案例来说话 前面已经说了JMS和RocketMQ一些概念和安装,下面使用SpringBoot来亲身操作一下. 生产者的操作 SpringBoot项目创建完成,引入依赖是第一步: <dep ...

  6. 再谈一次关于Java中的 AIO(异步IO) 与 NIO(非阻塞IO)

    今天用ab进行压力测试时,无意发现的: Requests per second:    xxx [#/sec] (mean) ab -n 5000 -c 1000 http://www:8080/up ...

  7. BRIEF特征简介

    引言 该文是由EPFL的Calonder在ECCV2010上提出了一种可以快速计算且表达方式为二进制编码的描述子.主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串 ...

  8. Object,equals,toString

    一.Object类 说明:Object类是Java中所有的类的直接或者间接的父类(基类). 该类中定义的是所有的类中的都有的的功能. 位置:可以从API中查找. 二.Object类之 equals 方 ...

  9. k8s部署prometheus

    https://www.kancloud.cn/huyipow/prometheus/527092 https://songjiayang.gitbooks.io/prometheus/content ...

  10. C#多线程和异步(三)——一些异步编程模式

    一.任务并行库 任务并行库(Task Parallel Library)是BCL中的一个类库,极大地简化了并行编程,Parallel常用的方法有For/ForEach/Invoke三个静态方法.在C# ...