Heim >Web-Frontend >js-Tutorial >JavaScript verwendet Kapselung

JavaScript verwendet Kapselung

高洛峰
高洛峰Original
2016-11-30 16:59:45978Durchsuche

Grundlegende Kapselungsmethode

Bitte sehen Sie sich das folgende Beispiel an:

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());

Laufergebnis:

Jane
singen, zeichnen
TabWeng
Fußball, Lernen, Laufen

Dies wird in der JavaScript-Objekterstellung erwähnt. Schreiben Sie die Eigenschaften und Methoden, die für jede Instanz eine eigene Kopie benötigen im Konstruktor.

Es gibt jetzt ein Problem. Der Eingabename darf keine Zahlen enthalten. Die Lösung besteht darin, eine Funktion zu schreiben, die den Namen überprüft, und diese Funktion in den Prototyp zu schreiben.

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());

In diesem Code haben wir eine checkName()-Funktion geschrieben, um den Namen zu überprüfen. Vorerst dient dies nur dazu, zu überprüfen, ob keine Zahlen vorhanden sein können, und dann die Überprüfung in der ersten Zeile durchzuführen des Codes im Konstruktor. Wenn die Überprüfung fehlschlägt, wird eine Ausnahme ausgelöst.
Hier habe ich einen Namen Helen666 übergeben und die folgende Ausnahme wurde ausgelöst:

Fehler: Der Name Helen666 darf keine Zahlen enthalten

Auf diese Weise wird eine grundlegende Kapselung erreicht und die interne Umsetzungsprüfung.

Aber es gibt noch ein anderes Problem: Wir können den Namen auch so definieren:

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

Auf diese Weise kann der Name immer noch in einen illegalen Namen geändert werden, also haben wir darüber nachgedacht, ihn zu verwenden Zur Steuerung können Sie Werte nur über die Set-Methode zuweisen, über die Set-Methode überprüfen und den Wert über die Get-Methode abrufen. Die aktuelle Codeänderung lautet wie folgt:

// Interfacevar 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 person1 = new Person("Helen","20");person1.addHobby(['sing','drawing']);function record(person){
  Interface.ensureImplements(person,People);
  person.sayName();
  console.log(person.getHobby().toString());}record(person1);

Laufende Ergebnisse:

Helen
singen, zeichnen

Zunächst verwenden wir die Schnittstelle Für diesen Code wird die People-Schnittstelle definiert und die Person implementiert diese Schnittstelle. Achten Sie auf den Inhalt der Kommentare. (Informationen zu Schnittstellen finden Sie in diesem Artikel über die Verwendung von JavaScript-Schnittstellen.)
Zweitens verwenden wir die Get-Methode und die Set-Methode, um Werte abzurufen und zuzuweisen. Wir können uns darauf einigen, dass Programmierer Werte nur über Set und im Set zuweisen können Methode wir Die zugewiesenen Werte werden überprüft, um die Richtigkeit sicherzustellen. Dies ist jedoch nur eine Konvention. Programmierer können weiterhin Werte zuweisen und interne Attribute über person1.name = „123“ ändern.
Um zu standardisieren und als Erinnerung zu dienen, standardisieren wir die Benennung interner Attribute und fügen „_“ vor diesen Attributen hinzu, z. B. **_name**, **_age**, damit der Programmierer Wenn er das Attribut direkt ändern möchte, muss er person1._name = „123“ so schreiben. Dies ist offensichtlich ein bewusster Ansatz, der den meisten Programmierern als Standard und Erinnerung dient.

Trotzdem kann diese Art der Einschränkung nur durch Vorschriften die Änderung durch person1._name nicht verhindern. Die folgende Methode kann die internen Attribute wirklich privatisieren.

Kapselung durch Abschlüsse

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

var Person = function(name,age){ //implement People
  // 私有变量
  var _name,_age,_hobbys = [];

  this.addHobby = function(hobbys){
    _hobbys = _hobbys.concat(hobbys);
  },
  this.getHobby = function(){
    return _hobbys;
  },
  this.setName = function(name){
    if(this.checkName(name)){
      throw new Error("名字 "+name+" 不能含有数字");
    }
    _name = name;
  },
  this.getName = function(){
    return _name;
  },
  this.setAge = function(age){
    _age = age || "未设置"; 
  },
  this.getAge = function(){
    return _age;
  }

  this.setName(name);
  this.setAge(age);
}

Person.prototype = {
  checkName:function(name){
    re = /\d/;
    return re.test(name);
  },
  sayName:function(){
    console.log(this.getName());
  },
  sayAge:function(){
    console.log(this.getAge());
  }

}

var person1 = new Person("Helen","20");
person1.addHobby(['sing','drawing']);

function record(person){
  Interface.ensureImplements(person,People);
  person.sayName();
  console.log(person.getHobby().toString());
}

record(person1);

Wenn das Attribut dies im Konstruktor nicht verwendet, kann von außen nicht auf das Attribut zugegriffen werden, während der Abschluss über die Bereichskette darauf zugreifen kann. Dann legen wir den einzigen Eintrag für die Zuweisung von Werten zu Attributen durch Abschlüsse fest und überprüfen so diese Attribute streng.

Allerdings ist es oft unnötig, Methoden im Konstruktor zu definieren, da jedes Mal, wenn eine Instanz erstellt wird, eine Kopie der Methode generiert wird, die Speicherunterstützung erfordert, also während der Verwendung, wenn Sie die verwenden können Versuchen Sie, die obige grundlegende Kapselungsmethode zu verwenden, es sei denn, es bestehen sehr strenge Überprüfungsanforderungen für private Attribute.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Javascript-VariablenbereichNächster Artikel:Javascript-Variablenbereich