JavaScript基礎④原型に基づく対象向けプログラミング

6026 ワード

前編のJavaScript基礎に続く③引用と関数
前言
「世の中の万物はすべて対象」とは何ですか?対象は風であることができて、雨であることができて、万物の星であることができて、あなたと私です.Javaプログラミングの中で、世の中の万物を分類して、オブジェクトを創建するのは必ず種類があって、種類は対象の模版で、対象は種類の実例です.JavaScriptの初期には純粋なOOPはなく、プロトタイプに基づいた擬似OOPのみがあります.今日は主にJavaScriptのプロトタイプに基づく対象に向けて、最新サポートのOOPプログラミングを紹介します.
概要
JavaScriptは、従来のオブジェクト指向言語の中にクラスの概念がなく、一連の無秩序属性の集合であり、その属性には基本値、関数、オブジェクトが含まれています.これらを組み合わせてオブジェクトを生成します.各オブジェクトは一つの参照タイプに基づいて作成されます.
参照に基づくオブジェクト
//     Object    
var person = new Object();
//           
person.name = "zeno";
person.age = 20 ;
person.job = "Software Engineer";
//         
person.sayName = function(){
    alert(this.name);
};

person.sayName(); // out : zeno
クラスのコンストラクタを呼び出します.
//           
function Person(name,age,job) {
    var obj = new Object();
    obj.name = name ;
    obj.age = age;
    obj.job = job;

    obj.sayName = function() {
        alert(this.name);
    };
    return obj;
}

var p1 = Person("zeno",20,"Software Engineer");
var p2 = Person("lily",23,"Teacher");

p1.sayName(); // out : zeno
p2.sayName(); // out : lily
文字の量を使ってオブジェクトを作成します.
//            
var person = {
    //        :    ,        ,         ,       
    name:"zeno",
    age:20,
    job:"Software Engineer",
    sayName:function(){
        alert(this.name);
    }
}

person.sayName();  // out : zeno
字面の量を使って作成する対象の方式が一般的で、書きやすく、JSON形式に似ているため、広く使われています.
原型オブジェクト
プロトタイプを使用してオブジェクトを作成し、Functionをクラス識別と見なす.
原型オブジェクトを作成
//      ,     Person 
function Person() {
    //     
    Person.prototype.name = "zeno";
    Person.prototype.age = 20;
    Person.prototype.job = "Software Engineer";
    //     
    Person.prototype.sayHello = function(){
                alert("Hello "+this.name);
            };
}

//   Person  
var person = new Person();
alert(person.name); // out : zeno
person.sayHello(); // out : Hello zeno
プロトタイプ時代にはfunctionをクラスとして扱い、functionに属性と方法を作成する.
簡単な作成方法
//           
function Person1(){}

Person1.prototype = {
    name:"xiaojiu",
    age:20,
    job:"Teacher",
    sayName:function(){
        alert(this.name);
    }
};
私たちが作成した各関数にはプロトタイプの属性があります.この属性はポインタでオブジェクトを指します.このオブジェクトの用途は特定のタイプのすべてのインスタンスで共有できる属性と方法を含んでいます.
原型オブジェクト
いずれにしても、新しい関数を作成すると、特定のルールのセットに従ってプロトタイプ属性を作成します.この属性は関数のプロトタイプオブジェクトを指します.デフォルトでは、すべてのプロトタイプオブジェクトが自動的にconstructor属性を取得します.この属性にはプロトタイプ属性の所在関数を指すポインタが含まれています.
引き継ぐ
JavaScript継承は、プロトタイプチェーンによって継承され、JavaScript継承によって実現される本質は、プロトタイプのオブジェクトを書き換え、新しいタイプのインスタンスで代用することである.JavaScriptは単に継承することしかできません.子類は父類を一つしか継承できません.多重継承時に継承される父類の属性と方法は前に継承された父類の属性と方法をカバーします.
単一引継ぎ
//   
function SuperType() {
    this.property = true;
    this.name = "zeno"
}

//   
function SubType(){
    this.subProperty = false;
}

//         
SubType.prototype = new SuperType();

var sub = new SubType();
alert(sub.name); // out : zeno;
多重継承
//   
function SuperType() {
    this.property = true;
    this.name = "zeno"
}
//   2
function SuperType2() {
    this.name = "lily";
}

//   
function SubType(){
    this.subProperty = false;
}
//         
SubType.prototype = new SuperType();
SubType.prototype = new SuperType2();

var sub = new SubType();
alert(sub.name); // out : lily
上記のコードから分かるように、JavaScriptが複数継承されている場合、後続の親は前に継承された親の属性をカバーします.
call関数を使って簡単な継承を実現します.
サブクラスでは、親タイプのプロトタイプで定義された方法は使用できません.父類は2回の構造方法を呼び出します.1回はサブタイプのプロトタイプを作成する場合、もう1回はサブタイプのコンストラクタの内部にあります.
function Person(name,age) {
    this.name = name ;
    this.age = age ;
}

Person.prototype = {
    showInfo : function() {
        alert("name = "+this.name+"    age = "+this.age);
    }
};

function Teacher() {
    Person.call(this,"zeno",20);
}

var teacher = new Teacher();
alert(teacher.showInfo()); //   
alert(teacher.name); // out : name
call関数を使って相続を実現する場合、functionの中の属性と方法しか使えません.対象のプロトタイプの方法は呼び出しられません.属性方法を呼び出した時に方法のエラーが発生します.call関数を使って相続を実現し、少しの柔軟性が欠けています.原型継承とcall関数を結合したいなら、より完璧に継承できます.
グループ引継ぎ
function Person(name,age) {
    this.name = name ;
    this.age = age ;
}

Person.prototype = {
    showInfo : function() {
        alert("name = "+this.name+"    age = "+this.age);
    }
};

function Teacher() {
    Person.call(this,"zeno",20);
}

Teacher.prototype = new Person();

var teacher = new Teacher();
alert(teacher.showInfo()); // name = zeno    age = 20  // undefined
運行後、私達は2回目のalertを発見しました.初めてのname=zeno age=20、2回目のundefinedは、なぜ2回目のパチンコがありますか?私たちはPersonを二回実例化したので、teacherオブジェクトの中に二つのshow Info()の方法が存在し、一つは価値があり、一つは値がない.解決策は、callがfunction内部の属性と方法を継承する場合、親タイプのプロトタイプ属性をサブクラスのプロトタイプで受信することができる.
組み合わせ強化
//     
function inheritPrototype(subType,superType) {
    var prototype = superType.prototype;
    prototype.constructor = subType;
    subType.prototype = prototype;
}

//   
function SuperType(name) {
    this.name = name;
    this.books=["Java","JavaScript"];
}

//       
SuperType.prototype = {
    age:20,
    sayAge:function(){
        alert(this.age);
    }
};

//       
function SubType(){
    SuperType.call(this,"sub");
}

//     
inheritPrototype(SubType,SuperType);


var sub = new SubType();
sub.sayAge();  // out : 20
alert(sub.books); // out : Java , JavaScript
親の属性をサブクラスの属性に割り当て、親の構造関数もサブクラスによって実現させることで、複数の親オブジェクトの作成を避けることができます.
おわりに
JavaScriptのプロトタイプを使って、対象に向けた基本的な継承を実現するのは面倒で、Javaのような比較的にさわやかな感じが全くなく、複雑な子類継承の父を実現する必要があります.最新の標準(ES 6)のJavaScriptは、classextendsというキーワードを使用してOOPを実現することができ、基本的にJavaのような形を比較した.
最後に歌で夢を応援します.「夢を追う赤子の心」
            
              
            
           
             
              
            
           
       
       
           
....