web前端進(jìn)階之Javascript設(shè)計模式面向?qū)ο笃?/h1>

前言:在此說明Javascript設(shè)計模式所講內(nèi)容和知識點(diǎn)來自雙越老師(wangEditor富文本開源作者)的視頻墨林,內(nèi)容通俗易懂宽菜,受益匪淺盼理,結(jié)合自己的學(xué)習(xí)心得整理成筆記,與大家分享智亮,愿在前端的道路上越走越遠(yuǎn).....

從“寫好代碼”到“設(shè)計代碼”的過程忆某,不僅是技術(shù)的提升,更是編程思維的提升鸽素,而這其中最關(guān)鍵的就是設(shè)計模式褒繁,是否理解并掌握設(shè)計模式,也是衡量程序員能力的標(biāo)準(zhǔn)之一馍忽。

學(xué)習(xí)前提

  • 使用過jquery類庫
  • 有ES6基礎(chǔ)棒坏,用過node.js和npm
  • 對vue、react有所了解

搭建開發(fā)環(huán)境

代碼是基于ES6的遭笋,需要webpack和Babel進(jìn)行轉(zhuǎn)義

1坝冕、初始化npm環(huán)境

  • npm init 會出現(xiàn)提示,一直按回車瓦呼,最后輸入yes即可


    image.png

2喂窟、安裝webpack(當(dāng)下流行的打包工具)

3、安裝webpack-dev-server(是webpack集成本地服務(wù)的一個環(huán)境央串,寫完代碼需要在本地預(yù)覽磨澡,修改文件后可以自動刷新)

  • npm install webpack-dev-server html-webpack-plugin --save-dev

4、安裝babel(解析ES6語法)

  • npm install babel-core babel-loader babel-polyfill babel-preset-es2015 babel-preset-latest babel-plugin-transform-decorators-legacy --save-dev

5质和、創(chuàng)建文件

  • 文件目錄結(jié)構(gòu)


    image.png
  • 創(chuàng)建webpack.dev.config.js文件進(jìn)行配置

// 引入 node.js path文件 
const path = require('path')
// require 網(wǎng)頁模板插件
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // 入口文件
    entry: './src/index.js',
    /*
      出口文件
      @param  __dirname  當(dāng)前目錄
      @param  filename   目錄文件名
    */
    output: {
        path: __dirname,
        filename: './release/bundle.js' // release 文件夾運(yùn)行時會自動創(chuàng)建
    },
    /*
      plugins插件列表稳摄,是一個數(shù)組
      @param  HtmlWebpackPlugin html模板
    */
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html' // 自動生成的bundle.js 會自動注入到index.html
        })
    ],
     // 本地開發(fā)環(huán)境服務(wù)器
    devServer: {
        // 需要獲取文件,從本地release文件夾里面獲取
        contentBase: path.join(__dirname, "./release"), // 根目錄
        open: true, // 自動打開瀏覽器
        port: 9000, // 端口
    },
     // 模塊
    module: {
        // 規(guī)定
        rules: [{
             // 檢驗(yàn)js文件
            test: /\.js?$/,
            // 忽略的文件
            exclude: /(node_modules)/,
             // 進(jìn)行babel處理
            loader: 'babel-loader'
        }]
    }
}
  • 創(chuàng)建.babelrc文件
{
    "presets": ["es2015", "latest"],
    "plugins": ["transform-decorators-legacy"]
}
  • 更改package.json文件(json文件里面不能添加注釋)
 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    // 運(yùn)行webpack命令,將配置指向webpack.dev.config.js文件,生成開發(fā)模式--mode development
    "dev": "webpack-dev-server --config ./webpack.dev.config.js --mode development"
  },
  • 運(yùn)行npm run build,自動生成release文件


    image.png
  • 運(yùn)行npm run dev,自動打開瀏覽器


    image.png

面向?qū)ο?/h2>

概念

1饲宿、類厦酬,即模板胆描,通過模板實(shí)例化很多對象,和es5的構(gòu)造函數(shù)原理相同,里面放屬性和方法

//1仗阅、創(chuàng)建一個人(People)的模板
//2昌讲、人具有姓名(name),年齡(age)的屬性
//3减噪、人可以執(zhí)行動作吃飯(eat())短绸、講話(speak())等方法,方法里面執(zhí)行邏輯操作

//1旋廷、創(chuàng)建一個人(People)的模板
class People {

    constructor(name, age) {
    //2鸠按、人具有姓名(name),年齡(age)的屬性
        this.name = name,
        this.age = age
    }
    //3饶碘、人可以執(zhí)行動作吃飯(eat())、講話(speak())等方法馒吴,方法里面執(zhí)行邏輯操作
    eat() {
        console.log('this is eat')
    }
    speak() {
        console.log(this.name, this.age)
    }
}


2扎运、對象(實(shí)例),通過類可以賦值給很多對象

// 1饮戳、創(chuàng)建一個叫zhang的對象
// 2豪治、因?yàn)槿说腸onstructor里面需要傳參數(shù),所以將zhang的姓名(name)和年齡(age)傳進(jìn)去
// 3扯罐、zhang便有人(People)的方法负拟,可以吃(eat()),可以說(speak())
const zhang = new People('zhang', 20)
console.log(zhang.eat())    // zhangeat
console.log(zhang.speak())  // 20

// 創(chuàng)建實(shí)例2
const wang = new People('wang', 30)
console.log(wang.eat())
console.log(wang.speak())

三要素:繼承、封裝歹河、多態(tài)

1掩浙、繼承,子類繼承父類
  • 父類
//1秸歧、創(chuàng)建一個人(People)的模板厨姚,相當(dāng)于父類
class People {

    constructor(name, age) {
    //2、人具有姓名(name)键菱,年齡(age)的屬性
        this.name = name,
        this.age = age
    }
    //3谬墙、人可以執(zhí)行動作吃飯(eat())、講話(speak())等方法经备,方法里面執(zhí)行邏輯操作
    eat() {
        console.log(`${this.name}eat`)
    }
    speak() {
        console.log(`${this.age}`)
    }
}
  • 子類(學(xué)生)
// 實(shí)現(xiàn)子類繼承父類
// 人分為好多種拭抬,比如學(xué)生、白領(lǐng),通過extends繼承人的屬相和方法
class Student extends People {
    constructor(name,age,schoolNum){
        // 通過關(guān)鍵字super將name,age交給父類處理
        super(name,age)
        // 自己處理學(xué)號
        this.schoolNum = schoolNum
    }
    // 因?yàn)槭菍W(xué)生侵蒙,具有學(xué)習(xí)的方法
    study(){
        console.log(`學(xué)號為${this.schoolNum}的學(xué)生學(xué)習(xí)`)
    }
}

// 創(chuàng)建實(shí)例(學(xué)生jialin)
const jiaLin = new Student('jialin',20,20120102)
// jialin具有學(xué)習(xí)的方法造虎,同時也具有人(People)的吃飯(eat())方法和說話(speak())方法
console.log(jiaLin.study())
console.log(jiaLin.eat())
console.log(jiaLin.speak())
  • 子類(白領(lǐng))
// 創(chuàng)建白領(lǐng)這個類,繼承人的屬性和方法
class whiteCollar extends People{
    constructor(name,age,workNum){
        // 通過關(guān)鍵字super將name,age交給父類構(gòu)造函數(shù)處理
        super(name,age)
        // 自己處理工號
        this.workNum = workNum
    }
    // 因?yàn)槭前最I(lǐng),具有工作的方法
    work(){
        console.log(`工號號為${this.workNum}的人工作`)
    }
}
// 創(chuàng)建實(shí)例(白領(lǐng)mumu)
const mumu = new whiteCollar('mumu',30,123)
// mumu具有工作的方法蘑志,同時也具有人(People)的吃飯(eat())方法和說話(speak())方法
console.log(mumu.work())   // 工號號為123的人工作
console.log(mumu.eat())
console.log(mumu.speak())

通過以上案列可以知道子類(學(xué)生累奈、白領(lǐng))不僅繼承(擁有)了父類(人People)的屬性和方法贬派,還有屬于自己的方法(學(xué)習(xí)study、工作work)澎媒,自己也可以定義屬性和方法

  • 總結(jié)

1搞乏、People 是父類,公共的戒努,不僅僅服務(wù)于Student和whiteCollar
2请敦、繼承可將公共方法抽離出來,提高復(fù)用储玫,減少冗余侍筛,這是軟件設(shè)計最基礎(chǔ)和最高效的方式

2、封裝撒穷,數(shù)據(jù)的權(quán)限和保密匣椰。簡單來說,將對象里面的某些屬性和方法不想讓別人看見端礼,有一些是可以開放出去(javascript不是很明顯禽笑,typescript[是js的超集]具有明顯的特征,如public蛤奥、private佳镜、protexted關(guān)鍵字)

public 完全開放
protectted 受保護(hù)的
private 私有的

class People {
    // ts中的屬性要先聲明
    name  
    // 默認(rèn)的是public 相當(dāng)于public age
    age 
    // 定義protected 受保護(hù)的屬性凡桥,只有自己或者子類可以訪問
    protected weigth 
     // 定義private 私有的屬性蟀伸,別人用不了
    private girlFriend
    constructor(name, age) {
        this.name = name
        this.age = age
        // 給weigth賦值
        this.weigth = 120
        this.girlFriend = "zdy"
    }
    eat() {
        console.log(`${this.name}eat`)
    }
    
}
class Student extends People{
    schoolNum
   
    constructor(name,age,schoolNum) {
        super(name, age)
        this.schoolNum = schoolNum
      
    }
   
    getWeight() {
     // 獲取weight,這個屬性來自父類,對子類是開放的
        console.log(this.weigth)
    //  這里獲取不到 girlFriend缅刽,是父類私有的啊掏,不對外開放
        
    }
}

// 創(chuàng)建實(shí)例
let mumu = new Student('mumu',20,201210)
mumu.getWeight() //120
// console.log(mumu.girlFriend) 編譯是會報錯,因?yàn)間irFriend是私有屬性
  • 總結(jié)

1拷恨、減少耦合脖律,不該外露的不外露
2、利于數(shù)據(jù)腕侄、接口的權(quán)限管理
3小泉、es6目前不支持,一般認(rèn)為_開頭的屬性是private冕杠,比如var _num = 20

3微姊、多態(tài),同一接口的不同實(shí)現(xiàn)分预,簡單來講就是父類定義一個接口兢交,子類實(shí)現(xiàn)不同的功能
  • 代碼演示
    class People{
        constructor(name){
            this.name = name
        }
        saySomething(){

        }
    }
    // a繼承 People
    class A extends People {
        constructor(name){
            super(name)
        }
        saySomething(){
            alert(`${this.name}`)
        }
    }
// b繼承 People
    class B extends People {
        constructor(name){
            super(name)
        }
        saySomething(){
            alert(`${this.name}`)
        }
    }
    // a、b使用父類People的saySomething()方法笼痹,展示不一樣的結(jié)果配喳,此為多態(tài)
    let a = new A('jialin')
    alert(a.saySomething())
    let b = new A('mumu')
    alert(b.saySomething())
  • 總結(jié)

1酪穿、保持子類的開放性和靈活性
2、面向接口編程(不用管子類如何實(shí)現(xiàn)晴裹,就看父類有多少接口)

面向?qū)ο笤谇岸藢?shí)際應(yīng)用

1被济、可以理解jquery就是個class
2、$('p')是jquery的一個實(shí)例

  • 代碼演示
    class jQuery {
    constructor(selector) {
        // 獲取數(shù)組的slice
        let slice = Array.prototype.slice
        // 獲取節(jié)點(diǎn)涧团,利用slice.call將其結(jié)果返回給一個數(shù)組只磷,因?yàn)榭赡苁嵌鄠€dom節(jié)點(diǎn)
        let dom = slice.call(document.querySelectorAll(selector))
        
        // 獲取dom的長度
        let len = dom ? dom.length : 0
        // 進(jìn)行循環(huán)
        for (let i = 0; i < len; i++) {
            // 將dom的數(shù)組元素賦值給this也就是實(shí)例的元素,元素的k就是數(shù)組的k泌绣,0,1,2...
            this[i] = dom[i]
        }
        // 賦值數(shù)組的長度
        this.length = len
        this.selector = selector || ''

    }
    append(node) {
        //...
    }
    addClass(name) {
        //...
    }
    html(data) {
        //...
    }
    // 此處省略若干 API
}
// 入口
window.$ = function(selector) {
    // 這里其實(shí)就是工廠模式
    return new jQuery(selector)
}

console.log($('p'))

為什么使用面向?qū)ο?/h4>

1钮追、程序的執(zhí)行離不開順序、判斷阿迈、循環(huán)操作元媚,也就是將其結(jié)構(gòu)化
2、面向?qū)ο缶褪菍⒘闵⒌臄?shù)據(jù)結(jié)構(gòu)化
3苗沧、對于計算機(jī)而言惠毁,結(jié)構(gòu)化的才是最簡單的
4、編程應(yīng)該是 簡單&抽象崎页,簡單的前提是抽象,抽象后才簡單

關(guān)于抽象:抽取事物的共同特征就是抽取事物的本質(zhì)特征腰埂,舍棄非本質(zhì)的特征飒焦。所以抽象的過程也是一個裁剪的過程。在抽象時屿笼,同與不同牺荠,決定于從什么角度上來抽象。抽象的角度取決于分析問題的目的驴一。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末休雌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肝断,更是在濱河造成了極大的恐慌杈曲,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胸懈,死亡現(xiàn)場離奇詭異担扑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)趣钱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門涌献,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人首有,你說我怎么就攤上這事燕垃∈嗳埃” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵卜壕,是天一觀的道長您旁。 經(jīng)常有香客問我,道長印叁,這世上最難降的妖魔是什么被冒? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮轮蜕,結(jié)果婚禮上昨悼,老公的妹妹穿的比我還像新娘。我一直安慰自己跃洛,他們只是感情好率触,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汇竭,像睡著了一般葱蝗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上细燎,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天两曼,我揣著相機(jī)與錄音,去河邊找鬼玻驻。 笑死悼凑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的璧瞬。 我是一名探鬼主播户辫,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嗤锉!你這毒婦竟也來了渔欢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘟忱,失蹤者是張志新(化名)和其女友劉穎奥额,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酷誓,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡披坏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盐数。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棒拂。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帚屉,到底是詐尸還是另有隱情谜诫,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布攻旦,位于F島的核電站喻旷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏牢屋。R本人自食惡果不足惜且预,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烙无。 院中可真熱鬧锋谐,春花似錦、人聲如沸截酷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迂苛。三九已至三热,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間三幻,已是汗流浹背就漾。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留念搬,地道東北人从藤。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像锁蠕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子懊蒸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

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