プロトタイプチェーンおよび継承

5528 ワード

プロトタイプチェーン
プロトタイプチェーンは、ほとんどのjsオブジェクトにプロトタイプチェーンprototypeによって継承された方法または属性があり、javaおよびc#にもデフォルトの継承されたオブジェクトが存在する.jsプロトタイプチェーンによって親にメソッドとプロパティを追加すると、c#の拡張メソッドのような対応するメソッドとプロパティが生成されます.オブジェクトのプロトタイプチェーンを変更すると、継承された親を変更できます.
  • Object.prototype.test=function(){}が作成された場合、ほとんどのjsオブジェクトにtestのメソッドが存在します.
  • Number.prototype.test=function(){}が作成された場合、jsのほとんどの数値オブジェクトにはtestの方法が存在する.
  • String.prototype.test=function(){}が作成された場合、js文字列オブジェクトのほとんどにtestのメソッドが存在する.

  • このうち__proto__は必ずしもprototypeに等しいとは限らず、関数のみがprototypeおよび__proto__の属性を持ち、対象は__proto__のみである.各オブジェクトはその内部で1つの属性を初期化します.__proto__です.オブジェクトの属性にアクセスすると、このオブジェクトの内部にこの属性が存在しない場合、彼は__proto__に行ってこの属性を探します.この__proto__には自分の__proto__があります.そこで、ずっと探しています.
    継承方法について
  • 親設定prototypeメソッドをインスタンス化することによってオブジェクトを継承するメソッド
    function p(){this.log=function(){}}
    function c(){}    
    c.prototype=new p //   p   
    Object.getPrototypeOf(new c);//   c.__proto__   
    
  • .
  • 親設定prototypeメソッドをインスタンス化することによって、オブジェクトのprototypeメソッド
    function p(){}
    p.prototype.log=function(){}
    function c(){}    
    c.prototype=new p //   p   
    Object.getPrototypeOf(new c);//   c.__proto__      
    
  • を継承する.
  • 親のprototype設定prototypeメソッドによりオブジェクトを継承するprototypeメソッド
    function p(){this.logp=function(){}}
    p.prototype.log=function(){}
    function c(){}    
    c.prototype=p.prototype //   p prototype    ,    logp
    c.prototype.test=function(){}
    Object.getPrototypeOf(new c);//   c.__proto__        
    
  • .
  • 親設定子をインスタンス化する__proto__メソッドによりオブジェクトを継承するメソッド
    function p(){this.logp=function(){}}
    p.prototype.log=function(){}
    function c(){}    
    var obj=new c;
    obj.__proto__=new p; //   p prototype      logp  
    Object.getPrototypeOf(obj);//   c.__proto__      
    
  • .
  • thisの役割ドメインを変更することにより親メソッド継承親メソッドを実行する方法
    function p(){this.logp=function(){}}
    p.prototype.log=function(){}
    function c(){p.call(this)}    
    var obj=new c;  //    logp  
    
  • .
    プロトタイプチェーン関連メソッド
  • hasOwnProperty
  •  Array.prototype.log=function(){}
     Array.prototype.hasOwnProperty('log') //true
     for(key in []){console.log(key)} //log
    

    判断がなければ広がる方法を遍歴する
  • defineProperty
  •   Object.defineProperty(object, propertyname, descriptor)
    

    パラメータ
    object:定義されたオブジェクトpropertyname:パラメータ名descriptor:定義された記述情報
    descriptor
    パラメータのキー
    説明
    デフォルト
    configurable
    属性を削除または再定義できますか?
    false
    enumerable
    オブジェクトを巡回するときにアトリビュートが表示されるかどうか
    false
    value
    属性値は、設定後にgetsetを設定できません.
    undefind
    writable
    属性が変わるかどうか
    get
    プロパティを取得するとトリガーされます
    undefind
    set
    プロパティを設定するとトリガーされます
    undefind
    資料によるとwritableのデフォルト値はfalseであるが、このパラメータを設定しない場合、valueは変更可能であり、懐疑的な態度をとり、解くことができる.
      var user={};
      Object.defineProperty(user, 'name', {
            get:()=>{
                console.log(`get value:${this.name}`)
                return this.name;
            },
            set:value=>{
                console.log(`set value:${value}`)
                this.name=value;
            }
      });
    

    注意:次の設定で例外が放出されます
      var user={};
      Object.defineProperty(user, 'name', {
            value:'johe',
            get:()=>{
                console.log(`get value:${this.name}`)
                return this.name;
            },
            set:value=>{
                console.log(`set value:${value}`)
                this.name=value;
            }
      });
      //Uncaught TypeError: Invalid property descriptor. 
      //Cannot both specify accessors and a value or writable attribute, #
    
  • defineProperties
  •     Object.defineProperties(object, props)
    

    パラメータ
    object:定義されたオブジェクトprops:追加されたプロパティ、keyおよびvalueのそれぞれObject.definePropertyの2番目および3番目のパラメータ.
  • getPrototypeOf
  •     Object.getPrototypeOf("test") //String {length: 0, [[PrimitiveValue]]: ""}
    

    現在のオブジェクトのプロトタイプチェーンオブジェクトを返します__proto__prototypeの違い
  • __proto__prototypeと等しいとき
     function c(){}
     c==c.prototype.constructor //true
     c==(new c).constructor //true
     (new c).__proto__===c.prototype //true
    
  • .(new c).__proto__c.prototype,(new c).constructor.prototypeはいずれも恒等である.prototypeに属性とメソッドが付与されると、関数によって作成されたインスタンスはprototypeの属性とメソッドを継承します.
  • __proto__prototypeが等しくないとき
     function c(){}
     c.prototype={
         log:function(){}
     }
     c==c.prototype.constructor //false
     c==(new c).constructor //false
     (new c).__proto__===c.prototype //true
     (new c).constructor===Object //true;
    
  • c.prototypeを書き換えた後も、(new c).__proto__c.prototypeは一定であったが、c.prototype.constructorObjectではなくcを指した.