JavaScript从初见到热恋之深度讨论JavaScript中的面向对象。
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中的面向对象。的更多相关文章
- 深度解析javascript中的浅复制和深复制
原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...
- JavaScript中的面向对象的讨论(转)
前言 今天,WEB2.0时代的到来,给了JavaScript又一次大展身手的机会.Web2.0借助JavaScript技术,使得客户端的Web体验更加丰富多彩,同时JavaScript面对的问题域也变 ...
- 深度解析javaScript常见数据类型检查校验
前言 在JavaScript中,数据类型分为两大类,一种是基础数据类型,另一种则是复杂数据类型,又叫引用数据类型 基础数据类型:数字Number 字符串String 布尔Boolean Null Un ...
- 再次讨论javascript 中的this
原文: http://www.jb51.net/article/77519.htm 核心总结: 1.不论函数在哪里被调用,只要没有指定调用方,则this都指向window.指定了调用方,就指向调用方. ...
- 前端开发:面向对象与javascript中的面向对象实现(一)
前端开发:面向对象与javascript中的面向对象实现(一) 前言: 人生在世,这找不到对象是万万不行的.咱们生活中,找不到对象要挨骂,代码里也一样.朋友问我说:“嘿,在干嘛呢......”,我:“ ...
- 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统
面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...
- 简单分析JavaScript中的面向对象
初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...
- 深度理解Jquery 中 offset() 方法
参考原文:深度理解Jquery 中 offset() 方法
随机推荐
- IDEA常见设置
对于eclipse实在忍无可忍,各种功能各种bug..换回IDEA IDEA常见问题(其实不是问题,代码规范而已) 1.解决无限 This file is indented with tabs ins ...
- 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 ...
- 自学Python5.2-类和对象概念
自学Python之路 自学Python5.2-类和对象概念 面向对象编程的2个非常重要的概念:类和对象 对象是面向对象编程的核心: 在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出 ...
- Prometheus-operator架构详解
Prometheus是一个开源的系统监视和警报工具.一款非常优秀的监控工具.监控方案:Prometheus 提供了数据搜集.存储.处理.可视化和告警一套完整的解决方案. Prometheus的关键特性 ...
- luogu4849 寻找宝藏 (cdq分治+dp)
设f[i]是已经走到i号点的值. 先要给第四维离散化.然后去重 第一维排序,第二维cdq分治,第三维cdq分治,第四维树状数组,找到满足j(x,y,z,w)<=i(x,y,z,w)的j,给i统计 ...
- 手动实现staticmethod和classmethod装饰器
首先,staticmethod和classmethod装饰器是通过非数据描述符实现的.用法简单,这里就不细说了. 这里主要分析一下staticmethod和classmethod是如何通过描述符实现的 ...
- SQL Server 查
注:where语句是条件,后面加and或者or 时间日期:比时间需要时间加引号 模糊查询:where语句后面加like '%包含此关键字%'或者'以此关键字开头%'或者'%结尾' 排序查询:列名 o ...
- 【SPOJ10628】Count on a tree
题目大意:给定一棵 N 个节点的树,点有点权,要求回答 M 个询问,每次询问点 u 到点 v 的简单路径(链)上权值第 K 小是多少. 题解:学习到了树上主席树. 主席树维护序列时,每次将后一个点的树 ...
- 收藏:FLASH中键检测与右键屏蔽
原文:http://space.flash8.net/space/?591172/viewspace-708726.html <!DOCTYPE html PUBLIC "-//W3C ...
- 元组&哈希&字典
1.元组(1)特性:不可变(不能修改.添加.删除),可以做切片 元组本身不可变,如果元组中还包含其他可变元素,这些可变元素可以改变(元组里套用列表,列表中的值可变)(2)功能: index count ...