Heim  >  Artikel  >  Web-Frontend  >  Teilen und Funktionalisieren von JavaScript-Grundkenntnissen_Grundkenntnisse

Teilen und Funktionalisieren von JavaScript-Grundkenntnissen_Grundkenntnisse

WBOY
WBOYOriginal
2016-05-16 15:15:52968Durchsuche
1.对象适合于收集和管理数据,容易形成树型结构。
Javascript包括一个原型链特性,允许对象继承另一对象的属性。正确的使用它能减少对象的初始化时间和内存消耗。
2.函数它们是javascript的基础模块单元,用于代码复用、信息隐藏和组合调用。函数用于指定对象的行为。一般来说,编程就是将一组需求分解成一组函数和数据结构的技能。
3.模块我们可以使用函数和闭包来构造模块。模块是一个提供接口却隐藏实现状态和实现的函数或对象。

1. Benutzerdefinierter Typ – Konstruktormodus (Pseudoklassenmodus)

In einem klassenbasierten System wird ein Objekt definiert, indem eine Klasse verwendet wird, um zu beschreiben, wie es ist. Wenn Architektur ein klassenbasiertes System wäre, würde der Architekt zunächst einen Bauplan des Hauses zeichnen und dann würden die Häuser nach diesem Bauplan gebaut.

Wenn wir das benutzerdefinierte Typmuster zum Implementieren der Vererbung verwenden, müssen wir nur die Parameter an den Konstruktor übergeben und sie dann im Instanzobjekt bereitstellen. Andere Methoden des Instanzobjekts müssen keine Parameter übergeben, da über diese innerhalb der vom Instanzobjekt aufgerufenen Methode auf die Parameter zugegriffen werden kann. Auf diesem Objekt der Instanz gemountete Variablen werden Instanzvariablen genannt.

Zusammensetzung – Vererbung

function Person (name, age, job) {
  // 实例变量
  this.name = name;
  this.age = age;
  this.job = job;
}
Person.prototype.sayName = function () {
  alert(this.name);
}

var person1 = new Person('Nicholas', 29, 'Software Engineer');
var person2 = new Person('Greg', 27, 'Doctor');
function SuperType (name) {
  this.name = name;
  this.colors = ['red','blue', 'green'];
}

SuperType.prototype.sayName = function () {
  console.log(this.name);
}

function SubType (name, age) {
  // 继承属性
  SuperType.call(this,name);
  this.age = age;
}

// 继承方法
SubType.prototype = new SuperType();

SubType.prototype.sayAge = function () {
  console.log(this.age)
}

var instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black')
console.log(instance1.colors);
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType('Greg', 27)
console.log(instance2.colors);
instance2.sayName();
instance2.sayAge();

In Bezug auf geerbte Eigenschaften und geerbte Methoden haben wir den Superklassenkonstruktor zweimal aufgerufen, um den Prototyp des Unterklassenkonstruktors zu erstellen. Jetzt ist es so Eine Instanz des Superklassenkonstruktors, daher werden dem Instanzobjekt this im Superklassenkonstruktor auch Attribute hinzugefügt, aber der Wert ist undefiniert. Das heißt, die Superklassenkonstruktorfunktion wird über new aufgerufen, um den Unterklassentransformator zu ändern Der Prototyp des Unterklassenkonstruktors wird verwendet. Der Prototyp des Unterklassenkonstruktors weist redundante Attribute auf. Dadurch entsteht Abfall. Was wir tatsächlich brauchen, ist, dass der Prototyp des Unterklassenkonstruktors die Methoden des Oberklassenkonstruktorprototyps erben kann. Was wir also brauchen,

1. Erstellen Sie ein Unterklassen-Konstruktor-Prototypobjekt.

2. Der Prototyp dieses Unterklassenkonstruktors erbt vom Prototyp des Oberklassenkonstruktors.

3. Da wir das Prototypobjekt des Unterklassenkonstruktors in 1 neu geschrieben haben, dh das Prototypobjekt neu erstellt haben, müssen wir das Konstruktorattribut zum neu erstellten Prototypobjekt hinzufügen und es der Unterklassenkonstruktorfunktion zuweisen.

Schreiben Sie den obigen Code wie folgt um.

Über das Konstruktorattribut: Dieses Attribut ist nur für den Prototyp der Konstruktorfunktion verfügbar und verweist auf den Konstruktor. Das neu geschriebene Prototypobjekt verfügt standardmäßig nicht über das Konstruktorattribut.

Parasitäre Kombination – Vererbung

function inheritPrototype (subType,superType) {
  var prototype = Object.creat(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
};

function SuperType (name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
  console.log(this.name);
}
function SubType(name, age) {
  //继承属性
  SuperType.call(this,name);
  this.age = age;
}
//继承方法
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function () {
  console.log(this.age);
}

var instance = new SubType();

Durch das Ausblenden dieser sogenannten Prototyp-Betriebsdetails sieht es jetzt weniger seltsam aus. Aber hast du wirklich etwas entdeckt?
Es gibt keine private Umgebung, alle Immobilien sind öffentlich. Auf die Methoden der übergeordneten Klasse kann nicht zugegriffen werden. Schwierig zu debuggen

2. Prototyp

In einem reinen Prototypenmuster würden wir Klassen aufgeben und uns stattdessen auf Objekte konzentrieren. Die prototypbasierte Vererbung ist konzeptionell einfacher als die klassenbasierte Vererbung: Ein neues Objekt kann die Eigenschaften eines alten Objekts erben. Sie beginnen damit, ein nützliches Objekt zu konstruieren, und dann können Sie weitere Objekte konstruieren, die diesem Objekt ähneln. Dadurch kann der Klassifizierungsprozess, bei dem eine Anwendung in eine Reihe verschachtelter abstrakter Klassen zerlegt wird, vollständig vermieden werden
In einem prototypbasierten System erstellen wir Objekte, die wie alle gewünschten Objekte dieses Typs aussehen, und teilen dann der JavaScript-Engine mit, dass wir weitere Objekte dieser Art wünschen. Wenn Architektur auf Prototypen basieren würde, würde der Architekt zuerst ein Haus bauen und dann alle Häuser so bauen, dass sie so aussehen.

Die Methode Object.creat() ist eine Alternative zum neuen Operator. Wenn sie zum Erstellen von JavaScript-Objekten verwendet wird, kann sie ein eher prototypbasiertes Gefühl vermitteln.

function myMammal = {
  name : 'Herb the Mammal',
  get_name : function () {
    return this.name;
  },
  says : function () {
    return this.saying || '';
  }
}

var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function (n) {
  var i, s = '';
  for (i = 0;i < n; i += 1) {
    if(s) {
      s += '-'
    }
    s += 'r';
  }
  return s;
}

myCat.get_name = function () {
  return this.says + ' ' + this.name + this.says;
}

这是一种"差异化继承"。通过定制一个新的对象,我们指明它与所基于的基本对象的区别。
有时候,它对某些数据结构继承于其他数据结构的情形非常有用。

3.函数化--工厂模式

在伪类模式里,构造器函数Cat不得不重复构造器Mammal已经完成的工作。在函数化模式中那不再需要了,因为构造器Cat将会调用构造器Mammal,让Mammal去做对象创建中的大部分工作,所有Cat只关注自身的差异即可。
函数化模式有很大的灵活性。它相比伪类模式不仅带来的工作更少,还让我们得到更好的封装和信息隐藏,以及访问父类方法的能力。

如果我们用函数化得样式去创建对象,并且该对象的所有方法都不用this或that,那么该对象就是持久性的。一个持久性的对象就是一个简单功能函数的集合。

私有变量:任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。

闭包

闭包是阻止垃圾回收器将变量从内存中移除的方法,使的在创建变量的执行环境的外面能够访问到该变量。
请记住:闭包由函数创建。每次调用函数会创建一个唯一的执行环境对象。函数执行完后,执行对象就会被丢弃,除非调用者引用了它。当然,如果函数返回的是数字,就不能引用函数的执行环境对象。但是如果函数返回的是一个更复杂的结构,像是函数、对象或者数组,将返回值保存到一个变量上,就创建了一个对执行环境的引用。

Function.prototype.method = function (name,func) {
  this.prototype[name] = func;
  return this; 
}
// 工厂mammal函数
var mammal = function (spec) {
  var that = {};

  that.get_name = function () {
    return spec.name;
  }
  that.says = function (spec) {
    return spec.saying || '';
  } 

  return that;
}

// 工厂cat函数(基于mammal的函数)
var cat = function (spec) {
  spec.saying = spec.saying || 'meow';
  var that = mammal(spec);
  that.purr = function (n) {
    var i, s = '';
    for (i = 0; i < n; i += 1) {
      if(s) {
        s += '-';
      }
      s += 'r';
    }
  }
  that.get_name = function () {
    return that.says() + ' ' + spec.name + ' ' + that.says();
  }
  return that;
}

// 创建myCat对象
var myCat = cat({name: 'Henrietta'});

Object.method('superior',function (name) {
  var that = this,
    method = that[name];
  return function () {
    return method.apply(that, arguments)
  }
})

// 工厂coolcat函数(基于cat函数)
var coolcat = function (spec) {
  var that = cat(spec),
    super_get_name = that.superior('get_name');
  that.get_name = function (n) {
    return 'like ' + super_get_name() + ' baby';
  }
  return that;
}

var myCoolCat = coolcat({name : 'Bix'});

var name = myCoolCat.get_name();

函数化模块模式有很大的灵活性。它相比构造函数模式不仅带来的工作更少,还让我们得到更好的封装休息和隐藏,以及访问父类方法的能力。如果对象的所有状态都是私有的,那么该对象就成为一个"防伪(tamper-proof)"对象。该对象的属性是可以被替换或者删除,当该对象的完整性不会受到损坏。我们用函数式的样式创建一个对象,并且该对象的所有方法都不使用this或者that,那么该对象就是持久性对象。一个持久性对象,就是一个简单的函数功能的集合。
一个持久性的对象不会被入侵。访问一个持久性的对象时,除非有方法授权,否则攻击者不会访问对象的内部状态。

模块模式

前面的模式是用于 自定义类型创建私有变量和特权方法的。而道格拉斯所说的模块模式则是为 单例创建私有变量和特权方法。所谓单例指的就是只有一个实例的对象。(就是用对象字面量表示法创建的对象)

var singleton = function () {
  // 私有变量和函数
  var privateVariable = 10;

  function privateFunction () {
    return false;
  }
  //特权/公有方法和属性
  return {
    publicProvperty: true;

    publicMethod: function () {
      privateVariable++;
      return privateFunction();
    }
  }
}

从本质上讲,这个对象字面量定义的是单例的公共接口。这种模式在需要对单例进行某些初始化,同时又需要维护其私有变量时非常有用。简言之,如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法。

增强的模块模式

这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和方法对其加以增强的例子。

var singleton = function () {
  // 私有变量和函数
  var privateVariable = 10;

  function privateFunction () {
    return false
  }
  // 创建对象
  var object = new CustomType();

  // 添加特权/公有属性和方法
  object.publicProperty = true;
  object.publicMethod = function () {
    privateVariable++;
    return privateFunction();
  }

  return object;
}()

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