JavaScriptのパッケージと継承特性を簡単に理解する

4091 ワード

JavaScriptのパッケージは、外部からオブジェクトにしかアクセスできない共有変数と関数、詳細とデータを隠します.jsには三つの方法でオブジェクトを作成し、それぞれのドアを大きく開け、命名規範でプライベート変数を区別し、クローズドで本物のプライベート変数を作成する.1.門戸を大きく開くことは、対象を実現するための最も基本的な方法であり、すべての方法と変数は共通の外部からアクセスできる.

var Book = function(name){ 
  if(this.check(name)){ 
    console.log("error"); 
    throw new Error("name null"); 
  } 
  this.name = name; 
} 
Book.prototype = { 
  check:function(name){ 
    if(!name){ 
      return true; 
    } 
  }, 
  getName:function(){ 
    return this.name; 
  } 
} 
 
var book = new Book("  "); 
//output:      
console.log(book.name,book.getName()); 
この例は、門戸が大きく開かれた典型的なもので、外部から直接にオブジェクトにアクセスできる属性と方法です.属性と変数には「this」があります.  2.命名規範で私有変数を区別する.この方法は門戸が大きく開いている最適化バージョンであり、私有変数または方法の前で「_」で区別するだけで、プログラマーが意図的に_を使う場合get Name()の方法で方法を呼び出すか、それとも止めることができないか、本当に変数を隠すのではない.  3.クローズドは、jsにおいて関数のみが作用領域の特性を持つ、構造関数の作用領域に関連変数を定義する真のプライベート変数を作成します.これらの変数は、ドメインとその作用領域のすべての関数によってアクセスできるようになります.

var Book2 = function(name){ 
  if(check(name)){ 
    console.log("error"); 
    throw new Error("name null"); 
  } 
  name = name; 
  function check(name){ 
    if(!name){ 
      return true; 
    } 
  } 
  this.getName = function(){ 
    return name; 
  } 
} 
Book2.prototype = { 
  display:function(){ 
    //      name 
    return "display:"+this.getName(); 
  } 
} 
var book2 = new Book2("  "); 
//output:undefined "  " "display:  " 
console.log(book2.name,book2.getName(),book2.display()); 
 この例の結果は、直接nameにアクセスしてundefinedの結果を返すことができます.この例は門戸の大開型と区別され、門戸の大開型における変数は「this」を用いて作成されているが、この例ではvarを用いて作成され、check関数もこのようにして、nameとcheck関数は構造関数の作用領域にしかアクセスできず、外部から直接アクセスできない.この方法は前の二つの方法の問題を解決したが、一定の欠点もある.ポータルオープンオブジェクト作成モードでは、すべての方法がプロトタイプオブジェクトに作成されますので、いくつかのオブジェクトインスタンスを生成するに関わらず、これらの方法はメモリの中に一つしか存在しません.この方法によって、新しいオブジェクトを生成するたびに、各プライベート変数と方法のために新しいコピーを作成します.
JavaScriptにおけるBookベースクラスの継承:

var Book = function(name){ 
  if(this.check(name)){ 
    console.log("error"); 
    throw new Error("name null"); 
  } 
  this.name = name; 
} 
Book.prototype = { 
  check:function(name){ 
    if(!name){ 
      return true; 
    } 
  }, 
  getName:function(){ 
    return this.name; 
  } 
} 

継承方法:

function extend(subClz,superClz){ 
var F = function(){} 
F.prototype = superClz.prototype; 
subClz.prototype = new F(); 
subClz.prototype.constructor = subClz; 
subClz.superClass = superClz.prototype; 
if(superClz.prototype.constructor == Object.prototype.constructor){ 
  superClz.prototype.constructor = superClz; 
} 
  空の関数Fをブリッジとして使用して、直接的な実用化を避けることができます.父のクラスの構造関数を呼び出して、追加のオーバーヘッドをもたらすことができます.また、父のクラスの構造関数にパラメータがある場合は、直接にsubClass.prototype=new superClass();親構造関数の呼び出しとプロトタイプチェーンの継承を実現することはできません.

subClz.superClass = superClz.prototype; 
if(superClz.prototype.constructor == Object.prototype.constructor){ 
  superClz.prototype.constructor = superClz; 
} 
  この三つの文を追加すれば、子類が父類を継承してBook.cal(this,name)を書くことを避けることができます.ArtBook.superClass.sostruct.callを簡単に書くと実現できます.また、サブクラスで親メソッドを書き換える場合は、親タイプのメソッドを呼び出すことができます.

ArtBook.prototype.getName = functiion(){ 
  return ArtBook.superClass.getName.call(this) + "!!!"; 
} 

Art Bookクラス:

var ArtBook = function(name,price){ 
  ArtBook.superClass.Constructor.call(this,name); 
  this.price = price; 
} 
extend(ArtBook,Book); 
ArtBook.prototype.getPrice = function(){ 
    return this.price; 
} 
ArtBook.prototype.getName = function(){ 
   return ArtBook.superClass.getName.call(this)+"!!!"; 
 }