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等顶级对象进行方法重写的。即使要进行重写,在使用完毕以后,也要对该方法进行清除处理。

待续。

原文地址:https://www.cnblogs.com/cm1236/p/5489495.html