最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單理解JavaScript中的封裝與繼承特性

 更新時間:2016年03月19日 15:07:36   作者:sjpsega  
這篇文章主要介紹了JavaScript中的封裝與繼承特性,封裝與繼承是基于對象編程概念中的基本特性,需要的朋友可以參考下

JavaScript中的封裝
封裝簡單地說就是讓外界只能訪問對象的共有變量和函數(shù),隱藏細節(jié)和數(shù)據(jù)。
js中有三種方法創(chuàng)建對象,分別為門戶大開型、用命名規(guī)范區(qū)分私有變量、閉包創(chuàng)建真正的私有變量三種。
1.門戶大開型,是實現(xiàn)對象的最基礎的方法,所有方法與變量都是共有的外界可以訪問。

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"來創(chuàng)建。
 
2.用命名規(guī)范區(qū)分私有變量,該方法是門戶大開型的優(yōu)化版本,只不過是在私有變量或方法前面用"_"區(qū)分,如果有程序員有意使用_getName()的方法來調(diào)用方法,還是無法阻止的,不是真正地將變量隱藏。
 
3.閉包創(chuàng)建真正的私有變量,該方法利用js中只有函數(shù)具有作用域的特性,在構造函數(shù)的作用域中定義相關變量,這些變量可以被定義域該作用域中的所有函數(shù)訪問。

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的結果??梢钥吹竭@個例子與門戶大開型的區(qū)別,門戶大開型中的變量使用"this"來創(chuàng)建,而這個例子中使用var來創(chuàng)建,check函數(shù)也是如此,使得name與check函數(shù)只能在構造函數(shù)的作用域中訪問,外界無法直接訪問。
該方法解決了前兩種方法的問題,但是也有一定的弊端。在門戶大開型對象創(chuàng)建模式中,所有方法都創(chuàng)建在原型對象中,因此不管生成多少對象實例,這些方法在內(nèi)存中只存在一份,而采用該方法,每生成一個新的對象都會為每個私有變量和方法創(chuàng)建一個新的副本,故會耗費更多的內(nèi)存。

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; 
} 

 
使用空函數(shù)F作為橋接,可以避免直接實例化父類時調(diào)用父類的構造函數(shù)帶來額外開銷,而且當父類的構造函數(shù)有參數(shù)時,想直接通過subClass.prototype = new superClass();實現(xiàn)父類構造函數(shù)的調(diào)用和原型鏈的繼承是不行的。

subClz.superClass = superClz.prototype; 
if(superClz.prototype.constructor == Object.prototype.constructor){ 
  superClz.prototype.constructor = superClz; 
} 

 
添加這三句可以避免子類繼承父類寫B(tài)ook.call(this,name);而是簡單地寫ArtBook.superClass.Constructor.call(this,name)便能實現(xiàn)。
并且在子類重寫父類方法的時候,可以調(diào)用到父類的方法:

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

ArtBook子類:

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)+"!!!"; 
 } 

相關文章

最新評論

拜泉县| 嫩江县| 台中市| 汉寿县| 双桥区| 达日县| 上犹县| 佳木斯市| 衡阳县| 南宁市| 汤阴县| 旺苍县| 道孚县| 天镇县| 霍邱县| 麦盖提县| 滨海县| 句容市| 祁阳县| 望城县| 古浪县| 甘泉县| 开江县| 普安县| 武鸣县| 大同市| 海林市| 收藏| 柘城县| 平原县| 南宁市| 新源县| 五莲县| 阿克苏市| 天水市| 柳河县| 名山县| 乐业县| 榕江县| 乌兰浩特市| 修水县|