成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

面向切面編程與裝飾器

lunaticf / 2579人閱讀

摘要:面向切面編程嗯,百度百科一下為的縮寫,意為面向切面編程,通過預(yù)編譯方式和運(yùn)行期動態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。

面向切面編程

~~~~ 嗯,百度百科一下 ~~~~

AOP 為 Aspect Oriented Programming 的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期動態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP 是 OOP 的延續(xù),是軟件開發(fā)中的一個熱點(diǎn),也是 Spring 框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用 AOP 可以對業(yè)務(wù)邏輯的各個部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。

作為前端的小萌理解為,就是將除主流程外的其他業(yè)務(wù)剝離出來,然后從側(cè)面切入。對原功能無侵入式的修改。

話不多說,來個網(wǎng)上的經(jīng)典例子:

業(yè)務(wù)邏輯:

主業(yè)務(wù):修改數(shù)據(jù)庫

切入點(diǎn) 1:修改前打印日志

切入點(diǎn) 2:修改后打印日志

Function.prototype.before = function(beforeFunc) {
  let that = this
  return function() {
    beforeFunc.apply(this, arguments)
    return that.apply(this, arguments)
  }
}

Function.prototype.after = function(afterFunc) {
  let that = this
  return function() {
    let ret = that.apply(this, arguments)
    afterFunc.apply(this, arguments)
    return ret
  }
}

function updateDb() {
  console.log(`update db`)
}
function beforeUpdateDb() {
  console.log(`before update db`)
}
function afterUpdateDb() {
  console.log(`updated db`)
}
updateDb = updateDb.before(beforeUpdateDb).after(afterUpdateDb)
updateDb()

原理:其實(shí)就是將主業(yè)務(wù)updateDb包裹2次,返回一個新的方法。新方法會在原方法調(diào)用前后調(diào)用切入方法,避免在主方法上直接改動。

這樣的可讀性和代碼維護(hù)性是不是很差,下面用裝飾器看看如何實(shí)現(xiàn)切面編程,

裝飾器 decorator

裝飾器是ES7現(xiàn)代游覽器并不兼容,需要babel轉(zhuǎn)譯,插件(babel-plugin-transform-decorators-legacy)

裝飾器只能作用于類本身、類的方法或?qū)傩?、訪問操作符

修飾器“@”為標(biāo)識符

1 對類的裝飾
@create
class Apes {
 
}

// 修飾類本身
function create(className) {
  className.prototype.create = function() {
    console.log("制造工具")
  }
  return descriptor
}

let apes1 = new Apes()
apes1.create() 
// 制造工具

對類本身修飾:create(className)。裝飾器本質(zhì)就是編譯時執(zhí)行的函數(shù)。

要修飾子類,通過要className.prototype修飾子類。

2 對類的方法修飾
class Apes {
  @eatMore
  eat() {
    console.log("吃水果")
  }
}
// 修飾方法
function eatMore(className, propName, descriptor) {
  //console.log(descriptor)
  let value = descriptor.value
  descriptor.value = function() {
    console.log("吃土")
    value()
  }
  return descriptor
}

let apes1 = new Apes()
apes1.eat()

對類的方法裝飾 eatMore(className, propName, descriptor)

className - 被修飾的類
propName - 被修飾的屬性名
descriptor - 該屬性的描述對象

通過descriptor屬性描述符看出 依賴于ES5的Object.defineProperty

復(fù)習(xí)一下Object.defineProperty

value:屬性的值,默認(rèn)為undefined

writable:能否修改屬性的值,默認(rèn)值為true

enumerable:能否通過for-in循環(huán)返回屬性。默認(rèn)為ture

configurable:能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,能否把屬性修改為訪問器屬性,默認(rèn)為true.

上面對類的方法修飾 實(shí)際是通過 descriptor.value 拿到其方法,在進(jìn)行包裝返回

同時也可以直接修改descriptor上的其他屬性或者返回一個新的descriptor

3. 針對 訪問操作符的裝飾
class test {
  //@nonenumerable
  get kidCount() {
    return 111
  }
}

function disWirte(target, name, descriptor) {
  descriptor.writable = false
  return descriptor
}
let p = new test()
console.log(p.kidCount)
p.kidCount = 222n descriptor;

// 拋出異常
// TypeError: Cannot set property kidCount of # which has only a getter
4. 修飾傳參
class Apes {
  @say("可以說漢語了")
  say() {
    console.log("厵爨癵驫寶麣纞虋讟钃鸜麷鞻韽顟顠饙饙騳騱龗鱻爩麤")
  }
}

// 修飾方法并傳遞參數(shù)
function say(str) {
  return function(className, propName, descriptor) {
    descriptor.value = function() {
      console.log(str)
    }
    return descriptor
  }
}

通過柯里化的方式傳遞參數(shù)

應(yīng)用 1. 應(yīng)用在斐波那契數(shù)列計(jì)算中
const memory = () => {
  const cache = {} //緩存池
  return (target, name, descriptor) => {
    // 原方法
    const method = descriptor.value
    // 包裹原方法
    descriptor.value = function(key) {
      if (cache[key]) {
        return cache[key]
      }
      const ret = method.apply(target, [key])
      cache[key] = ret
      return ret
    }
    return descriptor
  }
}

let count = 0

class Test {
  @memory()
  fb(n) {
    count++
    if (n === 1) return 1
    if (n === 2) return 1
    return this.fb(n - 1) + this.fb(n - 2)
  }
}

const t = new Test()
console.log(t.fb(10))
console.log(count)
2. 訪問操作符-set 上作類型檢查
class test {
  constructor() {
    this.a = 1
  }
  get a() {
    return this.a
  }
  @check("number")
  set a(v) {
    return v
  }
}

function check(type) {
  return function(target, prop, descriptor) {
    let v = descriptor.value
    return {
      enumerable: true,
      configurable: true,
      get: function() {
        return v
      },
      set: function(c) {
        var curType = typeCheck(c)
        if (curType !== type) {
          throw `${prop}必須為${type}類型`
        }
        v = c
      }
    }
  }
}

function typeCheck(c) {
  if (c === undefined) {
    return undefined
  }
  if (c === null) {
    return null
  }
  let type = typeof c
  if (type === "object") {
    return c.constructor == Array ? "array" : "object"
  }
  return type
}

let t = new test(11)
t.a = 2
console.log(t.a) // 2

t.a = []
console.log(t.a)
// throw a必須為number類型

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/106576.html

相關(guān)文章

  • 前端裝飾,AOP的使用

    摘要:中的裝飾在前端編程中,我們可以采用裝飾器,來實(shí)現(xiàn)編程。裝飾器使用我們先建立一個簡單的類,這個類的作用,就是在執(zhí)行的時候,打印出。至此,一個簡單的裝飾器范例已經(jīng)完成。 什么是裝飾器? 了解AOP 在學(xué)習(xí)js中的裝飾器之間,我們需要了解AOP(面向切面編程)編程思想。 AOP是一種可以通過預(yù)編譯方式和運(yùn)行期動態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP實(shí)際是Go...

    lewinlee 評論0 收藏0
  • 面向復(fù)雜應(yīng)用,Node.js中的IoC容 -- Rockerjs/core

    摘要:項(xiàng)目地址項(xiàng)目主頁基于和注解的輕量級容器,提供了依賴注入面向切面編程及異常處理等功能??稍谌我夤こ讨幸?,是一個框架無關(guān)的容器。模塊不依賴于任何框架,并與現(xiàn)有框架庫類等保持兼容。 Rockerjs Core 項(xiàng)目地址 項(xiàng)目主頁 基于 TypeScript 和注解的輕量級IoC容器,提供了依賴注入、面向切面編程及異常處理等功能。Rockerjs Core可在任意工程中引入,是一個框架無...

    jasperyang 評論0 收藏0
  • 面向復(fù)雜應(yīng)用,Node.js中的IoC容 -- Rockerjs/core

    摘要:項(xiàng)目地址項(xiàng)目主頁基于和注解的輕量級容器,提供了依賴注入面向切面編程及異常處理等功能??稍谌我夤こ讨幸?,是一個框架無關(guān)的容器。模塊不依賴于任何框架,并與現(xiàn)有框架庫類等保持兼容。 Rockerjs Core 項(xiàng)目地址 項(xiàng)目主頁 基于 TypeScript 和注解的輕量級IoC容器,提供了依賴注入、面向切面編程及異常處理等功能。Rockerjs Core可在任意工程中引入,是一個框架無...

    Kosmos 評論0 收藏0
  • 5 分鐘即可掌握的 JavaScript 裝飾者模式 AOP

    摘要:下裝飾者的實(shí)現(xiàn)了解了裝飾者模式和的概念之后,我們寫一段能夠兼容的代碼來實(shí)現(xiàn)裝飾者模式原函數(shù)拍照片定義函數(shù)裝飾函數(shù)加濾鏡用裝飾函數(shù)裝飾原函數(shù)這樣我們就實(shí)現(xiàn)了抽離拍照與濾鏡邏輯,如果以后需要自動上傳功能,也可以通過函數(shù)來添加。 showImg(https://segmentfault.com/img/bVbueyz?w=852&h=356); 什么是裝飾者模式 當(dāng)我們拍了一張照片準(zhǔn)備發(fā)朋友...

    chunquedong 評論0 收藏0
  • es6/es7之Decorator裝飾

    摘要:裝飾器顧名思義就是裝飾某種東西的方法,可以用來裝飾屬性變量函數(shù)類實(shí)例方法本質(zhì)上是個函數(shù)。以符開頭,函數(shù)名稱自擬。愛吃蘋果裝飾器裝飾類愛吃蘋果結(jié)果是這個類本身就可以通過修改類的屬性增加屬性被裝飾的對象可以使用多個裝飾器。 @Decorator 裝飾器是es7的語法,這個方法對于面向切面編程有了更好的詮釋,在一些情境中可以使用,比如路人A的代碼實(shí)現(xiàn)了一需求,路人B希望用A的方法來實(shí)現(xiàn)一個新...

    yanest 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<