首頁  >  文章  >  後端開發  >  Decorator 簡介及相關教學課程

Decorator 簡介及相關教學課程

小云云
小云云原創
2017-12-05 10:11:141467瀏覽

Decorator 簡介

Decorator 是一種透過註解表達式就可以擴充類別或方法的函數。 Decorator 可以套用在任何一個 class 或property 上。列如:

@myDecorator class A {} // 作用class

@myDecorator
doSomething() {}  // 作用表达式

 

Javascript Decorator 目前任然是ES7提案狀態,更多此特性的進度可以存取 proposal-decorators 查看。

Decorator原理

說到更改物件的屬性或方法,大家一定會想到Object.defineProperty(obj, prop, descriptor) 方法,透過該方法,我們可以輕易的修改或者重寫物件的行為或屬性,先前Vue 中提到的雙向綁定,即是透過重寫set 和get 方法來實現的。所以在我們還未正式用上 Decorator 前,都是透過 Object.defineProperty 方法來實現。先來簡單的認識下這個方法:

/**

  • obj : 需要修改屬性的物件

  • #prop : 需要修改物件的屬性名稱

  • descriptor: 用來定義屬性具體行為的描述物件
    **/
    Object.defineProperty(obj, prop, descriptor)

descriptor 屬性說明

  • configurable : 定義屬性物件是否可以被配置,也就是如果為false ,定義修改的描述操作(writeable, get 等等)都無效

  • #enumerable : 是否可以透過for-in 來遍歷,或者Object.keys 列舉

  • value : 定義物件value 屬性的值,value 可以是number, object, function 等等

  • writable: 定義value 值是否可以被重寫

  • get: 一個存取value 屬性時會觸發的function 物件

  • set: 一個設定value 屬性時會觸發的function 物件

修改一個屬性為唯讀(readonly)

了解Object .defineProperty 的基本語法後,我透過它先簡單實作一個readonly 實例。具體程式碼如下:

Decorator 的基本語法與使用

``javascript
# 定义
function myDecoration(target, name, descriptor) {}

# 对property使用
 class A {
 @myDecorator
 test() {}
 }

 # 对class使用
 @myDecorator
 class A {}

 # 带参数
 function myDescorator(a) {
 return function (target, name, descriptor) {
 console.llog('params:', a)
 }
 }
 @myDescorator(a) 
 class A {}

 # 时使用多个装饰器(Decorator)
 @myDecorator1
 @myDecorator2
 class A {}

 

利用Decorator 語法糖修改一個屬性為唯讀法(readonly)

利用Decorator給React 元件封裝PureRender

我們都知道,在React 生命週期裡有一個shouldComponentUpdate 方法,該方法透過返回ture 或false 來確定元件是否重新render 元件。也就是說,透過這個方法我們可以過濾掉些無效的資料渲染事件,進而提升效能。例如我們針對 props 傳遞過來的資料物件進行對比,如果 props 物件的屬性以及值並未變更的情況下,則無需執行render方法。

顯然透過比較 props 下資料物件的屬性與值是否變更,這種邏輯是可以重複使用的,而不是在單獨的在每個元件中去在重複的寫 shouldComponentUpdate 方法。說到改變元件物件的方法行為,這裡我們顯然就可以使用

Decorator 來這個特性來做了,也就是我們對應用 Decorator 物件的 shouldComponentUpdate 進行重寫。透過遍歷 props 物件的屬性和值,並與舊 props 的屬性與值進行對比,從而確定是否需要重新渲染。具體代碼如下:

function isEqual(a, b) {
  for (const key in a) {
    if ({}.hasOwnProperty.call(a, key) &&
      (!{}.hasOwnProperty.call(b, key) || a[key] !== b[key])) {
      return false;
    }
  }
  for (const key in b) {
    if ({}.hasOwnProperty.call(b, key) && !{}.hasOwnProperty.call(a, key)) {
      return false;
    }
  }
  return true;
}

export default function pureRender(targetComponent) {
  targetComponent.prototype.shouldComponentUpdate = function (props, state) {
    return !isEqual(this.state, state) || !isEqual(this.props, props)
  }
}

// 使用
@pureRender
class ComponentA extends React.Component {}

 

透過 Babel 使用 Decorator

由於 Decorator 是ES7中的草案,現在需要透過 Bable 才能使用。使用方法如下:

安裝

npm install --save-dev babel-plugin-transform-decorators

使用

方法一、透過設定.babelrc

{
  "plugins": ["transform-decorators"]
}

 

方法二、透過CLI

babel --plugins transform-decorators script.js

方法三、透過Node API

require("babel-core").transform("code", {
  plugins: ["transform-decorators"]
});

 

#總結

透過Decorator 這種不需要直接在物件或方法中寫額外邏輯的方式,就可以輕易的擴充物件或方法的能力,既滿足了功能需求,也精簡了程式碼,保證了程式碼的可維護性,例如我們已經常見的@log, @test, @mixin等等工具類。所以,以後的工作可以多嘗試。

 

參考

  • 細說ES7 JavaScript Decorators

  • Decorator specification

  • Exploring EcmaScript Decorators

  • Object.defineProperty

  • Babel Legacy Decorator plugin

  • #core-decorators

 以上內容就是Decorator 簡介及相關教學課程,希望能幫助大家。

先關推薦:

JavaScript中函數Decorator實例詳解

#裝飾器decorator詳解及實例

#php設計模式 Decorator(裝飾模式)

#

以上是Decorator 簡介及相關教學課程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn