1、JavaScript面向对象的三大特性
JavaScript的三大特性:封装性、继承性、多态性。
2、JavaScript实现封装特性
在一些静态类型的语言如java中,本身语法就提供了这些功能。js当中只能依靠变量的作用域来实现封装的特性,并且只能模拟出public和private两种特性。封装实现就是是对象内部的变化对外界是透明的,不可见。这种做法使对象之间低耦合,便于维护升级,团队协作开发。
3、JavaScript实现继承特性
继承可以解决代码复用,让编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。
JS中实现继承的方式:
1、通过call或者apply实现继承
//1.把子类*有的属性和方法抽取出,定义一个父类Stu
function Stu(name,age){
//window.alert("确实被调用.");
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
}
//2.通过call或者apply来继承父类的属性的方法
function MidStu(name,age){
//这里这样理解: 通过call修改了Stu构造函数的this指向,
//让它指向了调用者本身.
Stu.call(this,name,age);
//如果用apply实现,则可以
//Stu.apply(this,[name,age]); //说明传入的参数是 数组方式
//可以写MidStu自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
function Pupil(name,age){
Stu.call(this,name,age);//当我们创建Pupil对象实例,Stu的构造函数会被执行,当执行后,我们Pupil对象就获取从 Stu封装的属性和方法
//可以写Pupil自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}
//测试
var midstu=new MidStu("zs",15);
var pupil=new Pupil("ls",12);
midstu.show();
midstu.pay(100);
pupil.show();
pupil.pay(100);
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
function Animal(name,age){
this.name=name;
this.age=age;
this.shout=function(){
alert("我是:"+this.name+",今年:"+this.age);
};
this.action=function(){
alert("会吃");
};
} function Dog(name,age){
Animal.apply(this, [name,age]);
} var jack=new Dog("jack",1);
alert(jack.name);
alert(jack.age);
jack.shout();
jack.action();
</script>
</body>
</html>
2、原型继承方式实现继承
原型继承是js中最通用的继承方式,不用实例化对象,通过直接定义对象,并被其他对象引用,这样形成的一种继承关系,其中引用对象被称为原型对象。
function A(){
this.color = 'red';
}
function B(){}
function C(){}
B.prototype = new A();
C.prototype = new B();
// 测试原型继承
var c = new C();
console.log(c.color); // red
原型继承显得很简单,不需要每次构造都调用父类的构造函数,也不需要通过复制属性的方式就能快速实现继承。但它也存在一些缺点:
③ 占用内存多,每次继承都需要实例化一个父类,这样会存在内存占用过多的问题。
4、JavaScript实现多态特性
JS的函数重载
这个是多态的基础,JS函数不支持多态,事实上JS函数是无态的,支持任意长度,类型的参数列表。如果同时定义了多个同名函数,则以最后一个函数为准。
1、js不支持重载,通过判断参数的个数来模拟重载的功能。
/*****************说明js不支持重载*****/
function Person(){
this.test1=function (a,b){
window.alert('function (a,b)');
}
this.test1=function (a){
window.alert('function (a)');
}
}
var p1=new Person();
//js中不支持重载.
//但是这不会报错,js会默认是最后同名一个函数,可以看做是后面的把前面的覆盖了。
p1.test1("a","b");
p1.test1("a");
//js怎么实现重载.通过判断参数的个数来实现重载
function Person(){
this.test1=function (){
if(arguments.length==1){
this.show1(arguments[0]);
}else if(arguments.length==2){
this.show2(arguments[0],arguments[1]);
}else if(arguments.length==3){
this.show3(arguments[0],arguments[1],arguments[2]);
}
}
this.show1=function(a){
window.alert("show1()被调用"+a);
}
this.show2=function(a,b){
window.alert("show2()被调用"+"--"+a+"--"+b);
}
function show3(a,b,c){
window.alert("show3()被调用");
}
}
var p1=new Person();
//js中不支持重载.
p1.test1("a","b");
p1.test1("a");
2、多态基本概念
多态是指一个引用(类型)在不同情况下的多种状态。也可以理解成:多态是指通过指向父类的引用,来调用在不同子类中实现的方法。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
function Animal(){
this.say=function(){
alert("我是动物");
};
} function Dog(){
this.say=function(){ //多态的实现需要重写父类对象的方法
alert("我是狗");
};
}
Dog.prototype=new Animal();//多态的实现需要原生继承 function Cat(){
this.say=function(){ //多态的实现需要重写父类对象的方法
alert("我是猫");
};
}
Cat.prototype=new Animal(); function say(animal){
if(animal instanceof Animal){
animal.say();
}
} var dog=new Dog();
var cat=new Cat();
say(dog);
say(cat);
</script>
</body>
</html>
备注:多态利于代码的维护和扩展,当我们需要使用同一类树上的对象时,只需要传入不同的参数就行了,而不需要再new 一个对象。