method_missingのjavascriptのメタプログラミング

method_missingのjavascriptのメタプログラミング

入門

この技術を書くために、今日のヒントでも多くを言うためにRubyのメタプログラミングは、ルビーのインスピレーションから来ています。

Rubyでこのメソッドを呼び出すために転送されない場合はmethod_missingオブジェクトは、このメソッドを呼び出します。

JavaScriptでこの機能を達成するためにどのように、今のプロキシが、この考え方があります。

実現

class Base {
  constructor () {
    return new Proxy(this, {
      get (target, property) {
        if (Reflect.has(target, property)) {
          return Reflect.get(target, property)
        } else {
          return function () {
            if (target.method_missing) {
              return target.method_missing(property, ...arguments)
            } else {
              throw new ReferenceError('Property "' + property + '" does not exist.')
            }
          }
        }
      }
    })
  }
}

クラス、プロキシ機能を、説明するためのコード。

どのようにそれを使用するには?

あなたがそれを行うだろう通常の環境で使用したい場合、私はどのように、単一のページのフロントエンドで、AJAXインターフェースがたくさんあり、シナリオの話を?

する最初のネットワークライブラリ(jqueryの、axios)シール層、HTTP、及び要求に、サブ層のリクエストには、各界面層のための最終的な閉鎖は、この方法は、メソッド呼び出しとなり、にフォルダ管理APIは、その後、別の場所で参照します。

もちろん、これは動作することができます。問題は、あまりにも冗長インターフェイス情報は、3ヶ所、URL、パラメータ、メソッド名、変更をすることがあれば、それは3ヶ所かもしれにおけるインタフェース情報を変更しなければならないということです。

そして、各ジョブ機能のために再びそれをしなければならないします。

例としては、以下のとおりです。


// http 方法

import $ from 'jquery'

window.jQuery = $

$.ajaxSetup({
  cache: false,
  dataType: 'json'
})

// request 方法
export function request (url, setting) {
  return new Promise((resolve, reject) => {
    $.ajax(url, setting)
      .then(resolve)
      .fail(reject)
  })
}

export function get (url, params) {
  return request(url, {
    method: 'GET',
    data: params
  })
}

export function post (url, params) {
  return request(url, {
    method: 'POST',
    data: params
  })
}

// 具体的方法
import { post } from '@/lib/http'

export function getPermission (params = {}) {
  return post('/passport/permission', params)
}

私たちは、意味を表現し、実際に具体的な方法は、関数名とURLを参照してください、私はそれをしなければならない場合は、再度のインタフェースすることができます。

重複したコードです20の以上のインタフェース、場合、それを行うべきではありません。

実現

方法は?

再生するにはmethod_missingメソッドの上に書かれた、と私たちは、直接書き込み機能を方法を封印して、統一されたメソッド呼び出しをmethod_missing委託し、私たちは、シール方法、他のドライ何かから解放繰り返すことはできません。

import Base from './base'
import { request } from './http'
import * as _ from 'lodash'

let METHOD = {
  GET: ['get', 'show'],
  POST: ['post', 'update', 'change', 'create', 'delete', 'remove']
}

class ApiService extends Base {
  constructor () {
    super()
    this.baseURL = '/api/web'
  }

  method_missing (property, ...args) {
    let [url, setting] = args

    if (_.isObject(url)) {
      setting = {
        data: url
      }

      // 这里通过方法名生成 url
      const url_parts = property.split('_')
      const method = url_parts[0].toLowerCase()

      if (METHOD.GET.includes(method)) {
        setting.method = 'GET'
        url_parts.shift()
      } else if (METHOD.POST.includes(method)) {
        setting.method = 'POST'
        url_parts.shift()
      } else {
        setting.method = 'GET'
      }

      url = '/' + url_parts.join('/')
    }

    return request(this.baseURL + url, setting)
  }
}

export default new ApiService()


// 执行代码
import apiService from './api-service'

// 调用,神奇的代码
apiService.get_passport_permission({
})

ビューのコード実行の点から、私はmethod_missingの回でapiserverを落ちるこのメソッドを、定義されていません。

その後、パラメータを追加し、あなたがリクエストを送信することができ、生成されたURLに記載の方法の名前で、私は物事が可能であった、メソッド名とパラメータリストを取得します。

結論

コードのインターフェイス上のこのメソッドは、あなたがしている場合は特に、あなたは定型コードを大幅に節約することができますが、method_missingクラスを達成するために追加することができ、コードの特殊なケースがある場合は、より良い、より一般的なコードです。

このような共通のコードとアカウントに特殊なケースを取るためのコードは、もちろん、互換性が考慮されることはまだあります。

おすすめ

転載: www.cnblogs.com/htoooth/p/11367829.html