JS的面向对象
JS中没有传统意义上的面向对象概念,但是我们可以实现面向对象的功能。
一、封装。
封装很好理解,就是将客观事务封装成抽象的类。JS中有很多方法可以实现。
(1)工厂模式:
function Person(name,age){ var p=new Object(); p.name=this.name; p.age=this.age; p.showMessage=function(){ console.log("name:"+this.name+",age:"+this.age); } return p; } var p1=Person("阿刚",26); var p2=Person("阿阳",27); console.log(p1.showMessage===p2.showMessage);//false
工厂模式,无法识别对象,而且每个对象的函数方法都不是同一个方法,函数重复,资源浪费增加了开销
(2)函数构造模式:
function Person(name,age){ this.name=name; this.age=age; this.showMessage=function(){ console.log("name:"+this.name+",age:"+this.age); } } var p1=new Person("阿青",27); var p2=new Person("阿城",28); console.log(p1.showMessage===p2.showMessage);//false console.log(p1 instanceof Person);true
(3)原型模式:
function Person(){} Person.prototype.name="阿玲"; Person.prototype.age=28; Person.prototype.showMessage=function(){ console.log("name:"+this.name+",age:"+this.age); } var p1=new Person(); p1.showMessage(); var p2=new Person(); p2.showMessage(); console.log(p1.showMessage===p2.showMessage);//true console.log(p1 instanceof Person);//true console.log(Person.prototype.isPrototypeOf(p1));//true console.log(Object.getPrototypeOf(p1)==Person.prototype);//true
(4)复合模式:
使用构造函数模式为对象添加属性,使用原型模式为对象添加方法。通常我们使用这种方法来创建对象。
function Person(name,age){ this.name=name; this.age=age; } Person.prototype.showMessage=function(){ console.log("name:"+this.name+",age:"+this.age); } var p1=new Person("阿静",23); p1.showMessage();
二,继承
JS中可以有几种方法实现继承。
(1)使用prototype
function Person(name,age){ this.name=name; this.age=age; } Person.prototype.showMessage=function(){ console.log("name:"+this.name+",age:"+this.age); } function Man(){} Man.prototype=Person.prototype;
//Man.prototype=new Person();
Man使用prototype继承Person的方法,此时Man、Person拥有相同的方法,相同位置的内存,他们会相互影响,所以不建议直接使用。但我们清除这种造成的影响
man.prototype=new Person(); man.prototype.constructor=man; //这样当修改父类方法时就不会影响到子类,清除子类的影响。
(2)call(this,id)和apply(this,arg)
call(),apply()的使用方法类似,只是传递的参数有所不同。
父类名.call(本身,参数); 父类名.apply(本身,数组[参数一,参数二,····]);
当参数是数组类型,且调用的时候参数的列表是对应一致的,可以使用apply();
当调用对象的参数列表与被调用的对象参数列表不一致时,可以采用call(),直接制定参数列表对应值的位置。
三,多态
多态的定义这里说下多态的其中一种实现:重写。
重写
在JS中我们同样可以使用prototype来实现对象方法的重写,甚至可以对JS的String、array等原生的方法进行重写。
String.prototype.trim=function(){ //对String过滤空格的方法进行重写,这里使用正则表达式过滤左边,使用非正则过滤尾部 var str=this.replace(/^\s+/,""), end=str.length-1, ws=/\s/; while(ws.test(str.charAt(end))){ end--; } return str.slice(0,end+1); }
但是要注意的是,直接使用prototype重写方法会覆盖父类的原方法,原方法也会发生变化,所以一般项目中是不允许对string,object,array等顶级对象进行方法重写的。即使要进行重写,在使用完毕以后,也要对该方法进行清除处理。
待续。