Heim > Web-Frontend > js-Tutorial > Hauptteil

Detaillierte Erläuterung des Prinzips der Javascript-Prototyp-Kette_Javascript-Fähigkeiten

WBOY
Freigeben: 2016-05-16 15:21:42
Original
1457 Leute haben es durchsucht

In diesem Artikel wird das Prinzip der Javascript-Prototypkette anhand von Beispielen analysiert. Teilen Sie es als Referenz mit allen. Die Details lauten wie folgt:

1. JavaScript-Prototypkette

ECMAScript beschreibt das Konzept der Prototypenkette und verwendet die Prototypenkette als Hauptmethode zur Implementierung der Vererbung. Die Grundidee besteht darin, mithilfe von Prototypen einem Referenztyp die Eigenschaften und Methoden eines anderen Referenztyps erben zu lassen. In JavaScript wird das Attribut __proto__ verwendet, um die Prototypenkette eines Objekts darzustellen. Beim Nachschlagen einer Eigenschaft eines Objekts durchläuft JavaScript die Prototypenkette, bis es eine Eigenschaft mit einem bestimmten Namen findet!

Zum Beispiel haben wir jetzt den folgenden Code:

Erweitern Sie die Object-Klasse und fügen Sie Clone- und Extend-Methoden hinzu

/*扩展Object类,添加Clone,JS实现克隆的方法*/
Object.prototype.Clone = function(){
  var objClone;
  if (this.constructor == Object){
    objClone = new this.constructor(); 
  }else{
    objClone = new this.constructor(this.valueOf()); 
  }
  for(var key in this){
    if ( objClone[key] != this[key] ){ 
      if ( typeof(this[key]) == 'object' ){ 
        objClone[key] = this[key].Clone();
      }else{
        objClone[key] = this[key];
      }
    }
  }
  objClone.toString = this.toString;
  objClone.valueOf = this.valueOf;
  return objClone; 
}
/*扩展Object类,添加Extend方法来实现JS继承, 目标对象将拥有源对象的所有属性和方法*/
Object.prototype.Extend = function (objDestination, objSource) {
  for (var key in objSource) {
    if (objSource.hasOwnProperty(key) && objDestination[key] === undefined) {
      objDestination[key] = objSource[key];
    }
  }
  return objDestination;
}

Nach dem Login kopieren

Personenklasse definieren

/*定义一个Person类*/
 function Person(_name,_age){
   this.name = _name;
   this.age = _age;
}

Nach dem Login kopieren

In JavaScript ist die Object-Klasse die übergeordnete Klasse aller Klassen, daher erbt die Person-Klasse von der Object-Klasse und erbt alle öffentlichen Eigenschaften und öffentlichen Methoden der Object-Klasse, einschließlich der neu hinzugefügten Funktionen Clone und Extend Methoden der Object-Klasse

Sie können den folgenden Code verwenden, um zu beweisen, dass die Person-Klasse tatsächlich die Object-Klasse erbt

document.write("<pre class="brush:php;toolbar:false">");
var p = new Person("孤傲苍狼",24);//创建一个人,名字是孤傲苍狼
var cloneP = p.Clone();//p调用在Object类中定义的Clone方法来克隆自己,如果能得到一个cloneP,那就证明了Person类确实是继承了Object类,所以就拥有了Clone
document.writeln("p是使用Person类以构造函数的方式创建出来的对象,p.name = "+p.name+",p.age = "+p.age);
document.writeln("cloneP是p调用Clone方法克隆出来的对象,cloneP.name = "+cloneP.name+",cloneP.age = "+cloneP.age);
document.writeln("cloneP对象和p对象是两个相互独立的对象,这两个对象的内存地址肯定是不相等,p == cloneP的结果是:"+(p == cloneP));
cloneP.name="白虎神皇";//修改cloneP的名字
document.writeln("cloneP的name被修改了,cloneP.name = "+cloneP.name);
document.writeln("cloneP的name修改了,但是不影响到p,p.name = "+p.name);
document.write("
");
Nach dem Login kopieren

Laufergebnis:

Dann erbt die Person-Klasse die Object-Klasse über die Shenma-Methode. Sie wird mithilfe der Prototyp-Methode (prototye) geerbt:

/*定义一个Person类*/
function Person(_name,_age){
   this.name = _name;
   this.age = _age;
}
Person.prototype = new Object();//让Person类继承Object类

Nach dem Login kopieren

Da JavaScript vorschreibt, dass jede Klasse von der Object-Klasse erbt, also „Person.prototype = new Object();//Let the Person class inherit the Object class “ Auch wenn wir nicht schreiben Ich vermute, dass die JavaScript-Engine diesen Satz auch automatisch für uns hinzufügt oder „Person.prototype = Object.prototype;“ verwendet, damit die Person-Klasse die Object-Klasse erben kann. „Person.prototype = new Object();“, tatsächlich ist dies gleichbedeutend damit, dass das Object-Objekt ein Prototyp von Person ist, was dem Kopieren der Eigenschaften und Methoden des Object-Objekts in die Person entspricht .

2. So funktioniert der neue Operator

Schauen wir uns zuerst diesen Code an:

Code kopieren Der Code lautet wie folgt:
var p = new Person("lonewolf",24);// Erstellen Sie eine Person namens Lone Ao Canglang

Ein sehr einfacher Code. Werfen wir einen Blick darauf, was dieser neue Code bewirkt. Wir können den neuen Prozess in die folgenden drei Schritte unterteilen:

1.var p={}; Initialisieren Sie ein Objekt p.

2. p.__proto__=Person.prototype;, setze das __proto__-Attribut des Objekts p auf Person.prototype

3.Person.call(p,"lonewolf",24); Rufen Sie den Konstruktor Person auf, um p zu initialisieren.

Der Schlüssel liegt im zweiten Schritt, beweisen wir es:

var p = new Person("孤傲苍狼",24);//创建一个人,名字是孤傲苍狼
alert("p.__proto__ === Person.prototype的结果是:"+(p.__proto__ === Person.prototype));

Nach dem Login kopieren

Das Ergebnis der Ausführung unter Firefox ist:

Dieser Code gibt true zurück. Erklären Sie, dass unser Schritt 2 richtig ist.

Hinweis: Das Attribut __proto__ ist nur in Firefox- oder Chrome-Browsern öffentlich zugänglich. Daher geben andere Browser, die auf dem IE-Kernel basieren, nicht „true“ zurück.

Was ist also __proto__? Lassen Sie uns hier kurz sprechen. Jedes Objekt initialisiert ein Attribut darin, nämlich __proto__. Wenn wir auf das Attribut eines Objekts zugreifen und dieses Attribut nicht im Objekt vorhanden ist, geht er zu __proto__, um das Attribut zu finden, dieses __proto__ Es wird sein eigenes haben __proto__, also suche ich weiter danach, was wir normalerweise als Konzept der Prototypenkette bezeichnen.

Gemäß dem Standard ist __proto__ nicht für die Öffentlichkeit zugänglich, was bedeutet, dass es sich um ein privates Attribut handelt, auf das unter IE nicht zugegriffen werden kann, aber die Firefox-Engine macht es zu einem öffentlichen Attribut und extern eingestellt werden.

Okay, das Konzept ist klar, schauen wir uns den folgenden Code an:

<script type="text/javascript">
    var Person = function () { };
    Person.prototype.Say = function () {
      alert("Person say");
    }
    var p = new Person();
    p.Say();
</script>

Nach dem Login kopieren

Dieser Code ist sehr einfach. Sehen wir uns an, warum p auf Person’s Say zugreifen kann.

Zuallererst

Code kopieren Der Code lautet wie folgt:
var p=new Person();

Daraus kann geschlossen werden

Code kopieren Der Code lautet wie folgt:
p.__proto__=Person.prototype

Wenn wir also p.Say() aufrufen, gibt es zunächst kein Say-Attribut in p, also muss er es in seinem __proto__ finden, das Person.prototype ist, und wir haben es oben definiert

Person.prototype.Say=function(){
    alert("Person say");
};

Nach dem Login kopieren

于是,就找到了这个方法。

接下来,让我们看个更复杂的。

<script type="text/javascript">
    var Person = function () { };
    Person.prototype.Say = function () {
      alert("Person say");
    }
    Person.prototype.Salary = 50000;
    var Programmer = function () { };
    Programmer.prototype = new Person();//让程序员类从人这个类继承
    Programmer.prototype.WriteCode = function () {
      alert("programmer writes code");
    };
    Programmer.prototype.Salary = 500;
    var p = new Programmer();
    p.Say();
    p.WriteCode();
    alert(p.Salary);
</script>

Nach dem Login kopieren

我们来做这样的推导:

复制代码 代码如下:
var p=new Programmer();

可以得出

复制代码 代码如下:
p.__proto__=Programmer.prototype;

而在上面我们指定了

复制代码 代码如下:
Programmer.prototype=new Person();

我们来这样拆分,

var p1=new Person();
Programmer.prototype=p1;

Nach dem Login kopieren

那么:

p1.__proto__=Person.prototype;
Programmer.prototype.__proto__=Person.prototype;

Nach dem Login kopieren

由根据上面得到

复制代码 代码如下:
p.__proto__=Programmer.prototype

可以得到:

复制代码 代码如下:
p.__proto__.__proto__=Person.prototype

好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去 p.__proto__,也就是Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去 p.__proto__.__proto__,也就是Person.prototype中去找,于是就找到了Say方法。这也就是原型链的实现原理。

以下代码展示了JS引擎如何查找属性:

function getProperty(obj, prop) {
  if (obj.hasOwnProperty(prop))
    return obj[prop];
  else if (obj.__proto__ !== null)
    return getProperty(obj.__proto__, prop);//递归
  else
    return undefined;
}

Nach dem Login kopieren

范例:查找p对象的Say方法

<script type="text/javascript">
  /*查找obj对象的prop属性*/
   function getProperty(obj, prop) {
    if (obj.hasOwnProperty(prop))
      return obj[prop];
    else if (obj.__proto__ !== null)
      return getProperty(obj.__proto__, prop);//递归
    else
      return undefined;
  }
  var Person = function () { };//定义Person类
  Person.prototype.Say = function () {
    alert("Person say");
  }
  Person.prototype.Salary = 50000;
  var Programmer = function () { };//定义Programmer类
  //Programmer.prototype = new Person();//让程序员类从人这个类继承,写法一
  Programmer.prototype = Person.prototype;//让程序员类从人这个类继承,写法二
  Programmer.prototype.WriteCode = function () {
    alert("programmer writes code");
  };
  Programmer.prototype.Salary = 500;
  var p = new Programmer();
  var SayFn = getProperty(p,"Say");//查找p对象的Say方法
  SayFn.call(p);//调用找到的Say方法
</script>

Nach dem Login kopieren

在火狐下的运行结果:

其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有着一定的价值,而原型链的本质,其实在于__proto__。

希望本文所述对大家JavaScript程序设计有所帮助。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage