JS設(shè)計模式 -- 面向?qū)ο?-- 1 封裝

以下內(nèi)容來自張榮銘《JavaScript設(shè)計模式》第2章。

兩種編程風(fēng)格 -- 面向過程與面向?qū)ο蟆?/p>

面向?qū)ο缶幊淌侵笇⑿枨蟪橄蟪梢粋€對象纯趋,然后針對這個對象分析其特征(屬性)與動作(方法)嗅辣,這個對象我們稱之為類撼泛。

面向?qū)ο缶幊趟枷胫校渲幸粋€特點就是封裝澡谭,即把需要的功能放在一個對象里愿题,便于管理。但由于JavaScript屬于解釋性的弱類語言蛙奖,沒有經(jīng)典強類型語言中那種通過class等關(guān)鍵字實現(xiàn)的類的封裝方式潘酗。

1 封裝

1-1 創(chuàng)建一個類

首先聲明一個函數(shù),保存在一個變量內(nèi)雁仲。按照編程習(xí)慣仔夺,代表類的首字母一般會用大寫;
然后這個函數(shù)(類)的內(nèi)部通過對this(函數(shù)內(nèi)部自帶的一個變量攒砖,用于指向當(dāng)前這個對象)變量添加屬性或者方法來實現(xiàn)對類添加屬性或者方法缸兔。
也可以通過在類的原型(類也是一個對象,也有原型prototype)上添加屬性和方法吹艇。兩種方法:一種是一一為原型對象屬性賦值惰蜜,另一種則是將一個對象賦值給類的原型對象。但兩種方法不建議混用掐暮。

var Book = function (id蝎抽, bookname, price) {
  this.id = id;
  this.bookname = bookname;
  this.price = price;
}

Book.prototype.display = function () {};
// 或者
Book.prototype = {
  display: function () {}
}

使用:
new 關(guān)鍵字來實例化(創(chuàng)建)新的對象。使用實例化對象的屬性或者方法時樟结,可以通過點語法訪問养交。

JavaScript是一種基于原型prototype的語言,所以在創(chuàng)建一個對象時都有一個原型prototype用于指向其繼承的屬性瓢宦、方法碎连。這樣通過prototype繼承的方法并不是對象自身的,在使用這些方法時需要通過prototype一級一級查找得到驮履。

通過 this 添加的屬性鱼辙、方法是在當(dāng)前對象上添加的,是該對象自身擁有的玫镐,通過類創(chuàng)建一個新對象時倒戏,this 指向的屬性和方法都會得到相應(yīng)的創(chuàng)建。通過prototype繼承的屬性或者方法是每個對象通過prototype訪問到恐似,每次通過類創(chuàng)建一個新對象時這些屬性和方法不會再次創(chuàng)建杜跷。

1-2 constructor屬性

當(dāng)創(chuàng)建一個函數(shù)或者對象時都會為其創(chuàng)建一個原型對象prototype,在prototype對象中會創(chuàng)建一個constructor屬性矫夷。constructor屬性指向的就是擁有整個原型對象的函數(shù)或?qū)ο蟆?/p>

1-3 屬性與方法封裝

通過JS函數(shù)級作用域的特征來實現(xiàn)在函數(shù)內(nèi)部創(chuàng)建外界訪問不到的私有化變量和私有化方法葛闷。

//  私有屬性 與 私有方法  , 特權(quán)方法双藕, 對象公有屬性和對象共有方法淑趾, 構(gòu)造器
var Book = functiion (id, name, price) {
  //  私有屬性
  var num = 1;
  // 私有方法
  function checkId () {};
  //  特權(quán)方法
  this.getName = function () {};
  this.getPrice = function () {};
  this.setName = function () {};
  this.setPrice = function () {};
  //  對象公有屬性
  this.id = id;
  // 對象公有方法
  this.copy = function () {};
  //  構(gòu)造器
  this.setName(name);
  this.setPrice(price);
}

通過new關(guān)鍵字實例化對象時,由于對類執(zhí)行一次忧陪,所以類的內(nèi)部 this上定義的屬性和方法復(fù)制到新創(chuàng)建的對象上扣泊,成為對象公有化的屬性和方法,而其中的一些方法能訪問到類的私有屬性和方法嘶摊。
通過new關(guān)鍵字創(chuàng)建的新對象旷赖,無法獲取類外面通過點語法添加的屬性和方法,但是可以通過類來使用更卒。因此在類外面通過點語法定義的屬性以及方法被稱為類的靜態(tài)共有屬性和類的靜態(tài)共有方法。
而類通過prototype創(chuàng)建的屬性或者方法在類實例的對象中是可以通過this訪問到的稚照,所有prototype對象中的屬性和方法稱為共有屬性和共有方法蹂空。

//  類靜態(tài)公有屬性(對象不能訪問)
Book.isChinese = true;
//  類靜態(tài)公有方法(對象不能訪問)
Book.resetTime = function () {
  console.log('new-Time');
}
Book.prototype = {
  //  公有屬性
  isJSBook: false,
  //  公有方法
  display: function () {}
}

聽過new關(guān)鍵字創(chuàng)建的對象實質(zhì)是對新對象this的不斷賦值,并將prototype指向類的prototype所指向的對象果录,而類的構(gòu)造函數(shù)外面通過點語法定義的屬性方法是不會添加到新創(chuàng)建的對象上去的上枕。因此想要在新創(chuàng)建的對象中使用 isChinese需要通過Book類,而不能通過this弱恒, 如 Book.isChinese辨萍。
通過類的原型prototype上定義的屬性在新對象里可以直接使用點方法訪問。原因:新對象的prototype和類的prototype指向的是同一個對象。

例:

var b = new Book(11, 'javascript設(shè)計模式', 50);
console.log(b.num); //  undefined
console.log(b.isJSBook); // false
console.log(b.id); // 11
console.log(b.isChinese); // undefined

console.log(Book.isChinese); // true
Book.resetTime();  //  new-Time
1-4 閉包

閉包是有權(quán)訪問另外一個函數(shù)作用域中變量的函數(shù)锈玉,即在一個函數(shù)內(nèi)部創(chuàng)建另外一個函數(shù)爪飘。

//  利用閉包實現(xiàn)
var Book = (function () {
  // 靜態(tài)私有變量
  var bookNum = 0;
  //  靜態(tài)私有方法
  function checkBook (name) { };
  //  返回構(gòu)造函數(shù)
  return function (newId, newName, newPrice) {
    //  私有變量
    var name, price;
    //  私有方法
    function checkID (id) { };
    //  特權(quán)方法
    this.getName = function () {};
    this.getPrice = function () {};
    this.setName = function () {};
    this.setPrice = function () {};
    // 公有屬性
    this.id = newId;
    //  公有方法
    this.copy = function () {};
    bookNum++;
    if (bookNum > 100)  throw new Error('我們僅出版100本書');
    //  構(gòu)造器
    this.setName(name);
    this.setPrice(price);
  }
})();

Book.prototype = {
  //  靜態(tài)公有屬性
  isJSBook: false;
  //  靜態(tài)公有方法
  display: function () {}
}
//  利用閉包實現(xiàn)
var Book = (function () {
  // 靜態(tài)私有變量
  var bookNum = 0拉背;
  //  靜態(tài)私有方法
  function checkBook (name) { };
  //  創(chuàng)建類
  function book(newId, newName, newPrice) {
    //  私有變量
    var name, price;
    //  私有方法
    function checkID (id) { };
    //  特權(quán)方法
    this.getName = function () {};
    this.getPrice = function () {};
    this.setName = function () {};
    this.setPrice = function () {};
    // 公有屬性
    this.id = newId;
    //  公有方法
    this.copy = function () {};
    bookNum++;
    if (bookNum > 100)  throw new Error('我們僅出版100本書');
    //  構(gòu)造器
    this.setName(name);
    this.setPrice(price);
  }

// 構(gòu)建原型
  _book.prototype = {
    //   靜態(tài)公有屬性
    isJSBook: false;
    //  靜態(tài)公有方法
    display: function () {}
  }

//   返回類
return _book;
})();

1-5 安全模式
//  圖書安全類
var Book = function (title, time, type) {
  //  判斷執(zhí)行過程中师崎, this是否是當(dāng)前這個對象(如果是說明是用new創(chuàng)建的)
  if (this instanceof Book) {
    this.title = title;
    this.time = time;
    this.type = type;
    //  否則重新創(chuàng)建這個對象
  } else {
    return new Book(title, time, type);
  }
}

var book = Book('JavaScript', '2014', 'js');
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市椅棺,隨后出現(xiàn)的幾起案子犁罩,更是在濱河造成了極大的恐慌,老刑警劉巖两疚,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件床估,死亡現(xiàn)場離奇詭異,居然都是意外死亡诱渤,警方通過查閱死者的電腦和手機(jī)丐巫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來源哩,“玉大人鞋吉,你說我怎么就攤上這事±常” “怎么了谓着?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坛掠。 經(jīng)常有香客問我赊锚,道長,這世上最難降的妖魔是什么屉栓? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任舷蒲,我火速辦了婚禮,結(jié)果婚禮上友多,老公的妹妹穿的比我還像新娘牲平。我一直安慰自己,他們只是感情好域滥,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布纵柿。 她就那樣靜靜地躺著,像睡著了一般启绰。 火紅的嫁衣襯著肌膚如雪昂儒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天委可,我揣著相機(jī)與錄音渊跋,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛拾酝,可吹牛的內(nèi)容都是我干的燕少。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼微宝,長吁一口氣:“原來是場噩夢啊……” “哼棺亭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蟋软,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤镶摘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后岳守,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凄敢,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年湿痢,在試婚紗的時候發(fā)現(xiàn)自己被綠了涝缝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡譬重,死狀恐怖拒逮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情臀规,我是刑警寧澤滩援,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站塔嬉,受9級特大地震影響玩徊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谨究,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一恩袱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胶哲,春花似錦畔塔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碾盟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間技竟,已是汗流浹背冰肴。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熙尉。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓联逻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親检痰。 傳聞我的和親對象是個殘疾皇子包归,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容