Javascript 封装方法 基本封装方法

请看下面的例子:

var Person = function(name,age){
  this.name = name;
  this.age = age || "未填写";
  this.hobbys = [];
}

Person.prototype = {
  sayName:function(){
    console.log(this.name);
  },
  sayAge:function(){
    console.log(this.age);
  },
  addHobby:function(hobbys){
    this.hobbys = this.hobbys.concat(hobbys);
  }
}

var person1 = new Person("Jane","20");
var person2 = new Person("TabWeng","21");

person1.addHobby(['sing','drawing']);
person2.addHobby(['football','study','running']);

person1.sayName();
console.log(person1.hobbys.toString());

person2.sayName();
console.log(person2.hobbys.toString());

运行结果:

Jane  
sing,drawing
TabWeng  
football,study,running

这在JavaScript创建对象中讲过,把可以共用的属性和方法写在原型上,需要每个实例各自都有的副本的属性和方法放在构造函数中。

现在有个问题,名称的输入不能有数字,要怎么解决呢?解决的方法可以写一个检查名称的函数,这个函数写在原型上。

var Person = function(name,age){
  //校验名称
  if(this.checkName(name)){
    throw new Error("名字 "+name+" 不能存在数字");
  }
  this.name = name;
  this.age = age || "未填写";
  this.hobbys = [];
}

Person.prototype = {
  //校验函数
  checkName:function(name){
    re = /\d/;
    return re.test(name);
  },
  sayName:function(){
    console.log(this.name);
  },
  sayAge:function(){
    console.log(this.age);
  },
  addHobby:function(hobbys){
    this.hobbys = this.hobbys.concat(hobbys);
  }
}

var person1 = new Person("Helen666","20");
var person2 = new Person("TabWeng","21");

person1.addHobby(['sing','drawing']);
person2.addHobby(['football','study','running']);

person1.sayName();
console.log(person1.hobbys.toString());

person2.sayName();
console.log(person2.hobbys.toString());

这段代码中,我们写了一个checkName()函数,来校验名称,暂且只是校验不能有数字吧,然后再构造函数里的第一行代码中进行校验,若校验不通过,则抛出异常。

这里我传入一个名称Helen666,结果抛出如下异常:

Error: 名字 Helen666 不能存在数字

这样就做到了一个基本的封装,实现内部校验。

但是又有个问题,我们还可以这样来定义名称:

var person1 = new Person("Helen","20");
person1.name = "Helen666";
person1.sayName(); //Helen666

这样名称还是可以修改为不合法的名称,于是我们想到用get方法 和set方法来做控制,只能通过set方法来赋值,同时通过set方法进行校验,而通过get方法来获得值。现在的代码修改如下:

// Interface
var People = new Interface("People",["setName","getName","setAge","getAge","addHobby","getHobby","sayName","sayAge"]);

var Person = function(name,age){ //implement People
  this.setName(name);
  this.setAge(age);
  this._hobbys = [];
}

Person.prototype = {
  //校验函数
  checkName:function(name){
    re = /\d/;
    return re.test(name);
  },
  sayName:function(){
    console.log(this._name);
  },
  sayAge:function(){
    console.log(this._age);
  },
  addHobby:function(hobbys){
    this._hobbys = this._hobbys.concat(hobbys);
  },
  getHobby:function(){
    return this._hobbys;
  },
  setName:function(name){
    if(this.checkName(name)){
      throw new Error("名字 "+name+" 不能含有数字");
    }
    this._name = name;
  },
  getName:function(){
    return this._name;
  },
  setAge:function(age){
    this._age = age || "未设置"; 
  },
  getAge:function(){
    return this._age;
  }

}

请看下面的例子:

var Person = function(name,age){
  this.name = name;
  this.age = age || "未填写";
  this.hobbys = [];
}

Person.prototype = {
  sayName:function(){
    console.log(this.name);
  },
  sayAge:function(){
    console.log(this.age);
  },
  addHobby:function(hobbys){
    this.hobbys = this.hobbys.concat(hobbys);
  }
}

var person1 = new Person("Jane","20");
var person2 = new Person("TabWeng","21");

person1.addHobby(['sing','drawing']);
person2.addHobby(['football','study','running']);

person1.sayName();
console.log(person1.hobbys.toString());

person2.sayName();
console.log(person2.hobbys.toString());

运行结果:

Jane  
sing,drawing
TabWeng  
football,study,running

这在JavaScript创建对象中讲过,把可以共用的属性和方法写在原型上,需要每个实例各自都有的副本的属性和方法放在构造函数中。

现在有个问题,名称的输入不能有数字,要怎么解决呢?解决的方法可以写一个检查名称的函数,这个函数写在原型上。

var Person = function(name,age){
  //校验名称
  if(this.checkName(name)){
    throw new Error("名字 "+name+" 不能存在数字");
  }
  this.name = name;
  this.age = age || "未填写";
  this.hobbys = [];
}

Person.prototype = {
  //校验函数
  checkName:function(name){
    re = /\d/;
    return re.test(name);
  },
  sayName:function(){
    console.log(this.name);
  },
  sayAge:function(){
    console.log(this.age);
  },
  addHobby:function(hobbys){
    this.hobbys = this.hobbys.concat(hobbys);
  }
}

var person1 = new Person("Helen666","20");
var person2 = new Person("TabWeng","21");

person1.addHobby(['sing','drawing']);
person2.addHobby(['football','study','running']);

person1.sayName();
console.log(person1.hobbys.toString());

person2.sayName();
console.log(person2.hobbys.toString());

这段代码中,我们写了一个checkName()函数,来校验名称,暂且只是校验不能有数字吧,然后再构造函数里的第一行代码中进行校验,若校验不通过,则抛出异常。

这里我传入一个名称Helen666,结果抛出如下异常:

Error: 名字 Helen666 不能存在数字

这样就做到了一个基本的封装,实现内部校验。

但是又有个问题,我们还可以这样来定义名称:

var person1 = new Person("Helen","20");
person1.name = "Helen666";
person1.sayName(); //Helen666

这样名称还是可以修改为不合法的名称,于是我们想到用get方法 和set方法来做控制,只能通过set方法来赋值,同时通过set方法进行校验,而通过get方法来获得值。现在的代码修改如下:

// Interface
var People = new Interface("People",["setName","getName","setAge","getAge","addHobby","getHobby","sayName","sayAge"]);

var Person = function(name,age){ //implement People
  this.setName(name);
  this.setAge(age);
  this._hobbys = [];
}

Person.prototype = {
  //校验函数
  checkName:function(name){
    re = /\d/;
    return re.test(name);
  },
  sayName:function(){
    console.log(this._name);
  },
  sayAge:function(){
    console.log(this._age);
  },
  addHobby:function(hobbys){
    this._hobbys = this._hobbys.concat(hobbys);
  },
  getHobby:function(){
    return this._hobbys;
  },
  setName:function(name){
    if(this.checkName(name)){
      throw new Error("名字 "+name+" 不能含有数字");
    }
    this._name = name;
  },
  getName:function(){
    return this._name;
  },
  setAge:function(age){
    this._age = age || "未设置"; 
  },
  getAge:function(){
    return this._age;
  }

}