jsオブジェクト指向継承の知識を詳しく解説

小云云
リリース: 2018-02-05 09:35:23
オリジナル
1445 人が閲覧しました

この継承について言えば、オブジェクト指向を知っている友人は、ほとんどの oo 言語には 2 つのタイプがあることを知っています。1 つはインターフェイスの継承 (メソッドの署名のみを継承)、もう 1 つは実装の継承 (実際のメソッドを継承) です。この記事では、js オブジェクト指向の継承に関連する知識を紹介し、この知識ポイントを理解する際の読者の学習体験を共有します。必要な友人はそれを参照できます。皆さんのお役に立てれば幸いです。

ただし、jsには署名がないため、継承のみを実装し、プロトタイプチェーンに依存します。 js の継承について正式に説明しましょう

1。 プロトタイプ チェーン

プロトタイプ チェーン: 継承を実装する主な方法は、プロトタイプを使用して、ある参照型のプロパティとメソッドを継承させることです。

レビュー: コンストラクター、プロトタイプ、インスタンスの関係

各コンストラクターにはプロトタイプ オブジェクト (person.prototype) があり、プロトタイプ オブジェクトにはコンストラクター (コンストラクター) へのポインターが含まれます。各インスタンスにはコンストラクターへのポインターが含まれます。オブジェクト (目に見えない _proto_ ポインター)

プロトタイプ チェーンはどこから来たのでしょうか?

コンストラクターのプロトタイプ オブジェクトは別のコンストラクターのインスタンスです。このコンストラクターのプロトタイプ オブジェクトは、別のコンストラクターのプロトタイプ オブジェクトを指す (目に見えない _proto_ ポインター) を持ちます。

そのプロトタイプ オブジェクトがコンストラクターの別のインスタンス? このようにして、レイヤーごとにプロトタイプ チェーンを形成していきます。詳しく見てみましょう


    //第一个构造函数;有一个属性和一个原型方法
    function SuperType(){
        this.property=true;
    } 
    
    SuperType.prototype.getSuperValue=function(){
        return this.property
    }


    //第二个构造函数;目前有一个属性
    function SubType(){
        this.subproperty=false
    }
    
    //继承了SuperType;SubType原型成了SuperType的实例;实际就是重写SubType的原型对象;给SuperType原型对象继承了
    SubType.prototype=new SuperType()
    
    //现在这个构造函数有两个属性(一个本身的subproperty,一个继承的存在原型对象的property);两个方法(一个原型对象的getSubValue,一个原型对象的原型对象的getSuperValue)
    SubType.prototype.getSubValue=function(){
        return this.subproperty
    }
    
    var instance=new SubType()  //创建第二个构造函数的实例

    console.log(instance.getSuperValue())  //true 先查找instance这个实例有没有此方法;显然没有,再查找SubType原型对象有没有此方法;也没有,再查找SubType原型对象的原型对象;显然是存在的
ログイン後にコピー

注: インスタンスのコンストラクターは、元の SubType コンストラクターを指すようになりました。プロトタイプは書き直されており、その内部コンストラクターは、SubType.prototype のプロトタイプ オブジェクトのコンストラクターとともに、コンストラクター SuperType を指しています。プロトタイプの検索メカニズムがどのように動作するかについては、上記のコードをよく読んでください。 1.1 完成したプロトタイプ

プロトタイプの項でも触れましたが、もう一度お話しします。完全なプロトタイプには Object が含まれています。

すべての関数のデフォルトのプロトタイプは Object のインスタンスです。各デフォルトのプロトタイプには Object.prototype を指す _proto_ ポインターがあり、そのため、カスタム型は toString や valueOf

などのメソッドを継承し、Object.prototype の _proto を指します。プロトタイプチェーンを終了するには null。 Person コンストラクターを例として、完全なプロトタイプ チェーン図を見てみましょう

1.2 プロトタイプとインスタンスの関係の判断

最初のコンストラクターは、instanceof 演算子を使用します。インスタンスに表示されるコンストラクターをテストし、プロトタイプチェーンに出現し、結果は true になります

2 番目のメソッド isPrototypeOf(): プロトタイプチェーンに出現するプロトタイプである限り、プロトタイプチェーンから派生したインスタンスのプロトタイプであると言えます

    console.log(instance instanceof Object)   //都为true
    console.log(instance instanceof SuperType)
    console.log(instance instanceof SubType)

   
    console.log(Object.prototype.isPrototypeOf(instance)) //都为true
    console.log(SuperType.prototype.isPrototypeOf(instance))
    console.log(SubType.prototype.isPrototypeOf(instance))
ログイン後にコピー

1.3 メソッドを慎重に定義してください

注: プロトタイプを与える オブジェクト追加メソッドは、置換プロトタイプの前に見つからず、プロトタイプが書き換えられるため、置換プロトタイプの後に配置する必要があります。プロトタイプ チェーンも書き換えられるため、オブジェクト リテラルを使用してプロトタイプ メソッドを作成することはできません。

    function SuperType(){
        this.property=true;
    } 
    
    SuperType.prototype.getSuperValue=function(){
        return this.property
    }
    
    function SubType(){
        this.subproperty=false
    }
    
    //继承SuperType
    SubType.prototype=new SuperType()
    
    //使用字面量添加新方法,导致上一行无效   因为现在的原型替换了Object实例而非SuperType的实例,关系中断
    SubType.prototype={
       getSubValue:function(){
           return this.subproperty;
       },
       somOtherMethod:function(){
           return false
       }
    };

    var instance=new SubType()
    console.log(instance.getSuperValue())  //error
ログイン後にコピー

1.4 プロトタイプ チェーンの問題

1. インスタンスが別の関数のプロトタイプの場合、参照型の値がプロトタイプになります。プロパティは別の関数のインスタンスによって共有されます。

    function SuperType(){
       this.colors=["yellow","red","olive"]
    }

    function SubType(){
    }

    SubType.prototype=new SuperType()  //color实际上就是原型上的了

    var instance1=new SubType()
    instance1.colors.push("purple")
    var instance2=new SubType()

    console.log(instance1.colors==instance2.colors)  //true
ログイン後にコピー

2. サブタイプのインスタンスを作成する場合、スーパータイプのコンストラクターにパラメーターを渡すことはできません (すべてのオブジェクト インスタンスに影響を与えずにスーパータイプのコンストラクターにパラメーターを渡す方法はありません)。コンストラクターのヘルプ

プロトタイプ内の参照型値によって引き起こされる問題を解決するには、コンストラクターを使用して解決します

サブタイプ コンストラクター内でスーパータイプ コンストラクターを呼び出します (関数は、サブタイプ コンストラクター内でコードを実行するオブジェクトです)特定の環境で、apply または call を介して渡すことができます)

    function SuperType(){
        this.color=["yellow","red","olive"]
    }

    function SubType(){
        //继承了SuperType
        SuperType.call(this)
    }

    var instance1=new SubType()
    instance1.color.push("purple")
    var instance2=new SubType()

    console.log(instance1.color)  //["yellow","red","olive","purple"]
    console.log(instance2.color)  //["yellow","red","olive"]


    //传递参数
    function SuperType(name){
       this.name=name
    }
    function SubType(){
        SuperType.call(this,"double")
        this.age=12
    }

    var instance1=new SubType()
    console.log(instance1.name)  //double
    console.log(instance1.age)  //12
ログイン後にコピー

問題: コンストラクターからのみ学習する場合、メソッドはすべてコンストラクター内で定義されており、関数は回避できません。再利用できます

3. 組み合わせの継承 (一般的に使用されるのは組み合わせであり、プロトタイプとコンストラクターの組み合わせは同じです)


    function SuperType(name){
        this.name=name;
        this.color=["yellow","red","olive"];
    }

    SuperType.prototype.sayName=function(){
        console.log(this.name);
    }
 
    function SubType(name,age){
        //继承属性,创建属性副本
        SuperType.call(this,name);
        this.age=age;
    }
    
    //继承属性和方法,只是原型中属性被后来的函数调用生成的属性副本遮盖
    SubType.prototype=new SuperType();

    alert(SubType.prototype.constructor)  //指向的是SuperType

    SubType.prototype.constructor=SubType; //将constructor回归到SubType构造函数身上
    SubType.prototype.sayAge=function(){
        console.log(this.age)
    }
    
    
    var instance1=new SubType("double",23)
    instance1.color.push("pink")
    console.log(instance1.color)     //["yellow","red","olive","pink"]
    instance1.sayName()         //double
    instance1.sayAge()          //23

    var instance2=new SubType("single",34)
    console.log(instance2.color)     //["yellow","red","olive"]
    instance2.sayName()         //single
    instance2.sayAge()          //34
ログイン後にコピー

他にも継承がありますので、少し書き留めてください

1.

Crockford によって作成されました。プロトタイプの助けを借りて、既存のオブジェクトに基づいて新しいオブジェクトを作成できます。同時に、カスタム型を作成する必要はありません


    function object(o){      //本质上object()函数对其中对象的浅复制
        function F(){}      //创建一个新的构造函数
        F.prototype=o      //构造函数原型为传入的对象
      return new F()      //返回构造函数的实例
    }

    var person={
        name:"double",
        friends:["tom","jack","mike"]
    }

    var person1=object(person)   //事实上为原型共享
    person1.name="grey"
    person1.friends.push("single")
    
    console.log(person1.friends)  //["tom", "jack", "mike", "single"]

    var person2=object(person)
    person2.name="red"
    console.log(person2.friends)   //["tom", "jack", "mike", "single"]
ログイン後にコピー

プロトタイプの継承を標準化するために、ES5 には次の機能があります。便宜上、IE9 以降で使用できる Object.create() を使用します。1 つのオブジェクトを別のオブジェクトと同様に保ちたい場合は、このメソッドを実行できます

    var person={
        name:"double",
        friends:["tom","jack","mike"]
    }

    var person1=Object.create(person)
    person1.name="single"
    person1.friends.push("singles")

    var person2=Object.create(person)

    console.log(person1.friends==person2.friends) //true

    //Object.create()接受两个参数,一个为作为新对象原型的对象,一个为新对象定义额外属性对象
    var person={
        name:"double",
        friends:["tom","jack","mike"]
    }

    var person1=Object.create(person,{
         name:{ 
            value:"single"  //每个属性都是通过自己描述符定义的
         }
    })
ログイン後にコピー

2. 寄生継承

アイデアは次のとおりです。プロトタイプの継承と同様に、継承プロセスをカプセル化する関数を作成し、メソッドを通じてオブジェクトを内部的に強化し、オブジェクトを返すことを主に検討する場合に使用します


組み合わせ継承です。継承でよく使用されますが、スーパータイプ コンストラクターは 2 回呼び出されます。寄生結合の継承は、この問題を解決するためのものです

function object(o){
       function F(){}
       F.prototype=o
       return new F()
    }

    function createPerson(original){
       var clone=object(original)   //继承原型
       clone.sayName=function(){ 
           alert("name")
       }
       return clone
    }

    var person={
       name:"double",
       friends:["single","tom","jack"]
    }

    var person1=createPerson(person)
    person1.sayName()  //name   引用类型值还是共享的
ログイン後にコピー

以上、もうすぐ終わりです。スクリプト ハウスのサポートに感謝します。コンテンツが提供されることを願っています。コンパイルされたものが役に立ちます。


関連するおすすめ:

JavaScriptのオブジェクト指向継承_javascriptスキルを詳しく解説

以上がjsオブジェクト指向継承の知識を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート