JS OOP (面向?qū)ο缶幊蹋?/h1>

類 Class

1.通過一系列特性、行為對事物的特征進行描述。
2.在類定義中般此,通過 屬性(數(shù)據(jù))描述事物的特性唠亚,通過 方法(操作)描述事物的 行為撬槽。

const Animal= function(name, type) {
  /* private members */
  var type = type                                                                // 私有屬性
  var isAnimal = function() { return type === 'animal' }      // 私有方法

  /* protect members */
  this.color = 'blue'
  Object.defineProperty(this, 'color', {
    get: function(){ if (this instanceof Animal) return color },
    set: function(v){ if (this instanceof Animal) color = v }
  })

  /* public members */ 
  this.name = name                                                           // 實例屬性
  this.animalName = function(){                                         // 實例方法
    // 實例方法可訪問私有屬性和方法,原型方法不可以
    isAnimal() && console.log(this.name)
  }
}
Animal.prototype = {
  constructor: Animal,
  type: ' animal ',                                                                 // 原型屬性
  action: function() { console.log(' eating, drinking ') }         // 原型方法
}
Animal.number = 0                                                             // 類靜態(tài)屬性
Animal.count = function(){ return Animal.number }            // 類靜態(tài)方法


抽象 Abstract

1.沒有足夠信息描述一個具體的事物趾撵,而僅對事物進行概括性的描述侄柔。
2.無法展現(xiàn)出事物對象,必須要有事物的完整描述才能展現(xiàn)出對象占调。
3.抽象出的類 就像一張藍圖暂题,只是告訴我們寶藏的位置,但想得到寶藏就必須我們自己去尋寶究珊。

const Animal = function() { 
  this.initialize()                                           // 抽象類不可實例化薪者,在校驗抽象方法時異常
}
Animal.prototype.initialize = function() {
    this.walk()                                               // 抽象方法在初始化時進行校驗是否被派生類所實現(xiàn)
    this.yell()
  }
}


繼承 Inheritance

1.若多個事物具有很多相似的特性和行為,可以通過對基礎(chǔ)的描述進行擴充剿涮,而不需要重新描述言津。
2.派生出的類 就像繼承者,它不但獲得被繼承者的所有財產(chǎn)取试,而且也擁有自己的財產(chǎn)悬槽。

  1. 原型鏈繼承(實例化時無法向父類構(gòu)造函數(shù)傳參、原型對象的引用 屬性 被所有實例共享)
function Cat(name, type) { this.type = type }          // 無法向父類傳遞name屬性
Cat.prototype = new Animal()                                // 原型指向?qū)ο蟊凰袑嵗蚕?Cat.prototype.name = name                                  // 實例化后方可為父類初始化屬性值
  1. 構(gòu)造繼承(無法繼承原型的屬性和方法瞬浓,每個子類均包含父類方法的副本)
function Cat(name, type) {
  Animal.call(this, name)                                       // 通過父類的構(gòu)造函數(shù)對子類實例對象進行初始化
  Animal.prototype.contructor.call(this, name)      // 可多繼承 (原型的方法不會被直接繼承)
  this.type = type                                                   // 子類構(gòu)造函數(shù)初始化對象屬性(覆蓋父類)
  this.yell = function() { console.log('喵') }             // 子類構(gòu)造函數(shù)初始化對象方法(覆蓋父類)
}
  1. 實例繼承(擴展后的父類實例初婆,不支持多繼承)
function Cat(name, type) {
  var surperClass = new Animal(name)
  surperClass.type = type
  return surperClass
}
  1. 拷貝繼承(內(nèi)存占用高,無法獲取父類不可枚舉的屬性和方法)
function Cat(name) {
  var animal = new Animal()
  for(var p in animal) { Cat.prototype[p] = animal[p] }
  Cat.prototype.name = name
}
  1. 組合繼承(即可繼承實例屬性和方法猿棉,也可繼承原型屬性和方法)
function Cat(name, type) {
  Animal.call(this, name)      // 繼承父類實例的屬性和方法磅叛,并可傳參
  this.type = type      // 子類實例屬性和方法
}
Cat.prototype = new Animal()      // 原型鏈屬性和方法繼承,并支持 instanceof 指向
Cat.prototype.constructor = Cat      // 構(gòu)造函數(shù)指向萨赁,用于子類訪問父類實例屬性和方法
  1. 寄生組合繼承(剔除父類實例屬性和方法)
function Cat(name, type) {
  Animal.call(this, name)
  this.type = type
}
(function() {      // 閉包的方式弊琴,避免污染全局
  var Super = function() {}      // 空的構(gòu)造函數(shù),剔除實例屬性和方法
  Super.prototype = Animal.prototype      // 保存原型屬性和方法
  Cat.prototype = new Super()
  Cat.prototype.constructor = Cat
})()


封裝 Encapsulation

1.對事物描述的具體細節(jié)(隱私)被隱藏起來杖爽,而僅僅透露出事物的表面信息敲董。

  • 封裝出的類 就像事物對象的說明書紫皇,僅告訴我們?nèi)绾稳ナ褂眠@個對象而已。
const Animal= function(name, secret) {
  this.name = name   // 表面信息(公共屬性)
  let secret = secret   // 被隱藏的信息(私有變量)
  let collect = function() { secret = 'collect something' } // 被隱藏的行為(私有方法)
  /* 由于閉包的特性臣缀,原型鏈中的方法無法訪問到私有變量 */
  this.exposure = function() {      // 暴露出來的表面行為(共有方法)可訪問被隱藏的信息
      this.collect()
      console.log(secret)
  } 
}


多態(tài) Polymorphism

事物衍生出來的坝橡,具有相似特性和行為的其它事物,在針對這些事物進行描述時精置,都具有不同的特征计寇。

  • 多態(tài)屬于繼承的一種特點,如從形狀繼承而來的 圓形 與 方形脂倦,他們繪制的結(jié)果卻完全不同番宁。
const Cat = function(name,  type) {
  Animal.call(this, name)
  this.type = type
}
(function() {
  Super = function(){}
  Super.prototype = Animal.prototype
  Cat.prototype = new Super()
  Cat.prototype.constructor = Cat
  Cat.prototype.polyFunc = function() { console.log('it's cat') }     // 由派生類重寫,從而具有不同的行為
})()


ES6 中 “類” 的定義與繼承

  1. 類的定義
const privateProperty = Symbol('privateProperty')    // closure unique property identifer
const privateMethod = Symbol('privateMethod')    // closure unique method identifer
class Person {
  constructor(name) {    // constructor initial properties
      this._name = name    // initial public property
      this[privateProperty ] = 'private information'    // initial private property
  }
  get name() { return this._name }    // validate get property (use for protect members)
  set name(value) { this._name = value }  // validate set property (use for protect members)
  say() { console.log(this.name); this[privateMethod]() }    // public method, call the private method
  [privateMethod]() { console.log(this[privateProperty ]) }    // private method
  static getInformation(){ console.log('parent static method') }    // static method
}
  1. 類的繼承
class RacePerson extends Person {    // inherit the Person class
  constructor(name, from) {
      super(name)    // must call parent constructor
      this.from = from    // create and initial it's own property
   }
   say() { 
      super.say()    // call it's parent method
      console.log('from: '  + this.from)    // handle it's own logic
   }
   static getInformation() {
       super.getInformation()    // call it's parent static method
       console.log('child static method')    // handle it's own logic
   }
}

Vue 中 “類” 的定義與繼承

  1. 類的定義
const App = new Vue.extend({
  el: '#app',
  template: '<div>Hello world! {{name}}</div>',
  props: { name: '' },
  data() { return {} },
  created() { console.log('app created') }
})
  1. extends 單繼承(生命周期和watch鉤子優(yōu)先級最高赖阻,屬性和方法繼承優(yōu)先級則最低)
const ExApp = new Vue.extend({
  extends: App,    // extends 繼承中的生命周期鉤子優(yōu)先級最高蝶押,最先被調(diào)用
  data() { return { } },  // 所有派生類的同名的共有屬性將覆蓋父類的
  methods: {},  // 所有派生類的同名的共有方法將覆蓋父類的
  created() { console.log('ExApp created') },  // 派生類的生命周期鉤子優(yōu)先級最低,最后被調(diào)用
})
  1. mixins 多繼承 (生命周期和watch鉤子優(yōu)先級次于extends火欧,屬性和方法繼承優(yōu)先級次于派生類)
const mixin1 = {
  data() { return {} },
  methods: {},
  created() { console.log('mixin1 created') }
}
const mixin2 = {
  data() { return {} },
  methods: {},
  created() { console.log('mixin2 created') }
}
const MixinApp =  Vue.extend({
  mixins: [ mixin1, mixin2 ],  // 生命周期鉤子前者優(yōu)先于后者棋电,而屬性和方法繼承后者優(yōu)先于前者
  created() { console.log('MixinApp created') }
})
  1. inheritAttrs, $attrs, $listeners 組件式繼承(模板擴展,父類作為模板的一個模塊)
const CompApp = Vue.extend({
  /* 父類將獲取派生類實例化時的所有沒有被繼承的屬性值和相應(yīng)事件處理方法*/
  template: '<div>{{component}}<app v-bind="$attrs" v-on="$listeners"></app></div>',
  props: { component: '' },    // 派生類繼承或擴展的屬性
  data() { return {} },
  created() { console.log('componentApp created') },
  components: { app: App },
  inheritAttrs: false     //設(shè)置 $attrs 僅包含沒有被繼承的屬性對象(不包含派生類props定義的屬性)
})




問題

  1. 函數(shù)內(nèi)部定義方法 與 proto原型鏈中定義方法的區(qū)別
// 函數(shù)內(nèi)部定義的 實例方法 可獲取到閉包的作用域的 私有變量 和 私有方法苇侵。
const Person = function(name) {
  var name = name
  this.call = function() { console.log(name) } 
}
// prototype 原型鏈定義的 原型方法 指向其它內(nèi)存空間獨立的函數(shù)體赶盔,無法獲取閉包的作用域。
Person.prototype = {
  constructor: Person,
  say: function() { console.log(name) }
}
  1. instanceof 操作符(遞歸判斷實例原型鏈上的原型對象指向)


    JS原型鏈.jpg
function instance_of(instance, constructor) {
  var prototype = constructor.prototype      // prototype由定義時直接掛載在構(gòu)造函數(shù)上(顯式原型)
  var __proto__ = instance.__proto__        // __proto__ 指向?qū)?yīng)原型對象 prototype (隱式原型)
  while(true) {
    if ( __proto__ === null ) return false       // 匹配失敗榆浓,僅Object.prototype.__proto__為null
    if ( __proto__ === prototype ) return true   // 當(dāng)前實例原型指向與指定構(gòu)造函數(shù)匹配
    __proto__ = __proto__.__proto__         // 實現(xiàn)遞歸檢測
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末于未,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子陡鹃,更是在濱河造成了極大的恐慌烘浦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萍鲸,死亡現(xiàn)場離奇詭異闷叉,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門榨了,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事献联。” “怎么了采转?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵堡纬,是天一觀的道長。 經(jīng)常有香客問我饥悴,道長坦喘,這世上最難降的妖魔是什么盲再? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮瓣铣,結(jié)果婚禮上答朋,老公的妹妹穿的比我還像新娘。我一直安慰自己棠笑,他們只是感情好梦碗,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蓖救,像睡著了一般洪规。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上循捺,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天斩例,我揣著相機與錄音,去河邊找鬼从橘。 笑死念赶,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恰力。 我是一名探鬼主播叉谜,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼牺勾!你這毒婦竟也來了正罢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驻民,失蹤者是張志新(化名)和其女友劉穎翻具,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體回还,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡裆泳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了柠硕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片工禾。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蝗柔,靈堂內(nèi)的尸體忽然破棺而出闻葵,到底是詐尸還是另有隱情,我是刑警寧澤癣丧,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布槽畔,位于F島的核電站,受9級特大地震影響胁编,放射性物質(zhì)發(fā)生泄漏厢钧。R本人自食惡果不足惜鳞尔,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望早直。 院中可真熱鬧寥假,春花似錦、人聲如沸霞扬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祥得。三九已至兔沃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間级及,已是汗流浹背乒疏。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留饮焦,地道東北人怕吴。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像县踢,于是被迫代替她去往敵國和親转绷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

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

  • ??面向?qū)ο螅∣bject-Oriented,OO)的語言有一個標志谴返,那就是它們都有類的概念煞肾,而通過類可以創(chuàng)建任意...
    霜天曉閱讀 2,112評論 0 6
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對象屬性創(chuàng)建對象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,428評論 3 12
  • 要拍一個專題片 完成后上交。要求并不嚴格于是偷懶決定用去年拍過的一個新聞片-校醫(yī)嗓袱。吃完早餐準備去再加幾個鏡頭 剛好...
    大家好我是美少女閱讀 286評論 0 0
  • 這個世上沒有兩片完全相同的葉子渠抹,也沒有兩個完全相同的人蝙昙,性格有相似的,但沒有相同的梧却。性格的形成主要源自于兒童時期奇颠,...
    無邪居閱讀 773評論 0 0
  • 由于在山里沒有信號,所以也沒辦法進行文字的分享放航。選擇用徒步的方式大刊,可能是希望能進一步接近大自然,欣賞到美麗的風(fēng)景三椿。...
    魚耗子閱讀 96評論 0 0