[JavaScript学習ノート]対象、プロトタイプ、プロトタイプチェーン

4002 ワード

オブジェクト&原型チェーン
オブジェクト指向プログラミング(Object Oriented Programeming、OOP)は、現実世界の複雑な関係を一つのオブジェクトに抽象化し、対象間の分担協力によってリアル世界に対するシミュレーションを完成させる.
オブジェクト
オブジェクトは一つの容器で、属性と方法があります.
JavaScriptでは、各オブジェクトは別のオブジェクトから継承されます.オブジェクトの構築はコンストラクタによって実現され,コンストラクタはオブジェクトのテンプレートとして理解できる.実例オブジェクトはその構造関数によって作成されるので、各オブジェクトは他のオブジェクトに引き継がれ、ここで継承されるオブジェクトは「プロトタイプ」オブジェクトと呼ばれます.この中にはnullだけを除いて、自分の原型の対象がありません.
JavaScriptでは、構造関数によってインスタンスオブジェクトを生成すると、インスタンスオブジェクトにプロトタイプオブジェクトが割り当てられます.各コンストラクタにはプロトタイプ属性があります.この属性はインスタンスオブジェクトのプロトタイプオブジェクトであり、プロトタイプオブジェクトに定義された属性と方法はすべてのインスタンスオブジェクトに共有されます.したがって、各インスタンスオブジェクトには、そのプロトタイプオブジェクトがあり、インスタンスオブジェクトがプロトタイプオブジェクトに継承されることを示し、インスタンスオブジェクトは、その属性または方法を呼び出すことができる.
function animal (name){
  this.name = name
}
animal.prototype.color = "white"  //  animal prototype        

var dog = new animal('  ')
dog.color  // 'white'             //           

オブジェクトの最大の役割は、共有属性のメモリ占有を節約し、多重化を提供することである.
原型チェーン
オブジェクトの属性または方法は、自身に定義されたり、プロトタイプオブジェクトに定義されたりすることができます.原型の対象自体も対象ですので、自分の原型があります.すべてのオブジェクトのプロトタイプは最終的にObject.prototypeにまで遡り、Objectのプロトタイプはnullを指し、プロトタイプチェーンはnullに終端し、nullは属性がない.
プロトタイプチェーンの役割は、オブジェクトの属性を読み取り、JavaScriptエンジンは優先的に自身の属性を探しています.もしプロトタイプが見つからなかったら、プロトタイプのプロトタイプを探してください.Object.prototypeまで見つけられなかったら、undefinedに戻ります.自身と原型に同名の属性がある場合は、自分の属性を優先的に読み取り、これを上書きといいます.
トラック
prototypeオブジェクトにはconstructor属性、プロトタイプがある構造関数があります.オブジェクトの継承に注意する必要があります.必ずしも立体関数が必要ではありません.
function Constr(){}
var x = new Constr()

var y = new x.constructor() 
y instanceof Constr // true
//                   

Constr.prototype.createCopy = function(){
  return new this.constructor()
}
//                 
this指向
コンストラクタ内のthisはインスタンスオブジェクトを指し、その原理は以下の通りである.
var fn = function (){
  this.foo = 'bar'
}
var f = new fn()
//    
var f = Object.setPrototypeOf({}, fn.prototype)
fn.call(f)   // this      
// new      ? call           ,  this      
instanceof演算子
指定されたオブジェクトが配置関数であるかどうかを示すブール値を返します.右の構造関数が左のプロトタイプチェーン上にあるかを確認します.
var v new Vehicle()
v instanceof Vehicle // true
//    
Vehicle.prototype.isPrototypeOf(v)
一般的な方法Object.getPrototypeOf():
//            
Object.getPrototypeOf()  
Object.getPrototypeOf([]) === Array.prototype // true 
Object.setPrototypeOf():
//       ,     ,      (    ,    )
Object.setPrototypeOf()  
var a = {x:1}
var b = Object.setPrototypeOf({},a)
b.x // 1  
//  b   a       a          ,  b     a       ,   
//     var b = Object.create(a)

var fn = function (){
  this.foo = 'bar'
}
var f = new fn()
//    
var f = Object.setPrototypeOf({}, fn.prototype)
fn.call(f)  //   this      
Object.create():
var A = {
  print: function(){
    console.log('hello')
  }
}
var B = Object.create(a)
B.print() //hello
B.print === A.print // true
//    
var A = function(){}
A.prototype = {
  print:function(){
    console.log('hello')
  }
}
var B = new A()
B.print === A.prototype.print
個人的には違いがあります.一つは原型上の属性です.一つはA自身の属性です.
newnewコマンドは、コンストラクタを実行し、インスタンスオブジェクトを返します.
var a = function (){
  this.bala = 123;
}
var b = new a()
b.bala // 123
その原理:
  • は、戻る対象例
  • として空のオブジェクトを作成する.
  • この空のオブジェクトのプロトタイプをプロトタイプ属性に向ける
  • は、この空のオブジェクトの値を関数内部のthisキー
  • に割り当てる.
  • 構築関数内部コードの実行を開始しました.
  • 前の方法を参考にして、まとめました.
    var a = function(){
      this.balaba = 123;
    }
    var b 
    b = {}
    Object.setPrototypeOf(b, a)
    a.call(b)
    
    newの忘れ方
    //       
    function foo (a,b){
      'use strict';
      this.a = 'a';
      this.b = 'b';
    }
    foo() //      ,this        ,    undefined,JavaScript    undefined    ,    
    
    // instanceof
    
    function bar (){
      if(!(this instanceof bar)){
        return new bar()
      }
      this.a = 1
      this.b = 2
    }
    bar() 
    
    名前を付ける
    コンストラクタは大文字で始めます.例もオブジェクトを表します.