JavaScript API の設計原則

黄舟
黄舟オリジナル
2017-02-07 14:52:28891ブラウズ

少し前に、ネイティブ モジュール API (iOS および Android モジュールは JavaScript インターフェイスにカプセル化されています) を整理して最適化したので、JavaScript API の設計に関するいくつかの記事を勉強しました。古い記事ですが、非常に有益だったので記録しておきます。ここ。

優れた API 設計: 自己記述的でありながら抽象化の目標を達成します。

適切に設計された API を使用すると、開発者はマニュアルやドキュメントを頻繁に保管する必要がなく、テクニカル サポート コミュニティに頻繁にアクセスする必要もありません。

スムーズなインターフェイス

メソッドチェーン: スムーズで読みやすく、理解しやすい

//常见的 API 调用方式:改变一些颜色,添加事件监听
var elem = document.getElementById("foobar");
elem.style.background = "red";
elem.style.color = "green";
elem.addEventListener('click', function(event) {
  alert("hello world!");
}, true);
//(设想的)方法链 API
DOMHelper.getElementById('foobar')
  .setStyle("background", "red")
  .setStyle("color", "green")
  .addEvent("click", function(event) {
    alert("hello world");
  });

Set 操作と get 操作を 1 つに組み合わせることができ、メソッドが増えるほど、ドキュメントを書くのが難しくなる可能性があります

var $elem = jQuery("#foobar");
//setter
$elem.setCss("background", "green");
//getter
$elem.getCss("color") === "red";
//getter, setter 合二为一
$elem.css("background", "green");
$elem.css("color") === "red";

一貫性

関連性インターフェースはそのまま 一貫したスタイルと、使い慣れた快適な感覚を伝える一連の API により、開発者の新しいツールへの適応が大幅に容易になります。

物事に名前を付ける: 短く、自己記述的で、そして最も重要なのは一貫性です

「コンピューター サイエンスにおける難しい問題は 2 つだけです。キャッシュの無効化と名前の付け方です。」
「コンピューター サイエンス コミュニティでは、頭痛の種は 2 つだけです。それはキャッシュです。無効化と命名の問題」
— Phil Karlton

好きな言葉遣いを選んで、そのまま使いましょう。スタイルを選択し、それを維持します。

パラメータを処理するとき

、提供したメソッドが人々によってどのように使用されるかを考慮する必要があります。繰り返し呼び出されるでしょうか?なぜ繰り返し呼び出されるのですか?開発者が重複呼び出しを減らすために API はどのように役立ちますか?
マップ マッピング パラメーター、コールバック、またはシリアル化された属性名を受け取ることで、API がクリーンになるだけでなく、より快適かつ効率的に使用できるようになります。

jQuery の css() メソッドは DOM 要素のスタイルを設定できます:

jQuery("#some-selector")
  .css("background", "red")
  .css("color", "white")
  .css("font-weight", "bold")
  .css("padding", 10);

このメソッドは JSON オブジェクトを受け入れることができます:

jQuery("#some-selector").css({
  "background" : "red",
  "color" : "white",
  "font-weight" : "bold",
  "padding" : 10
});
//通过传一个 map 映射绑定事件
jQuery("#some-selector").on({
  "click" : myClickHandler,
  "keyup" : myKeyupHandler,
  "change" : myChangeHandler
});
//为多个事件绑定同一个处理函数
jQuery("#some-selector").on("click keyup change", myEventHandler);

型の処理

メソッドを定義するときは、どのパラメーターを受け取ることができるかを決定する必要があります。人々が私たちのコードをどのように使用するかはわかりませんが、より前向きになって、どのようなパラメータのタイプをサポートするかを検討することはできます。

//原来的代码
DateInterval.prototype.days = function(start, end) {
  return Math.floor((end - start) / 86400000);
};
//修改后的代码
DateInterval.prototype.days = function(start, end) {
  if (!(start instanceof Date)) {
    start = new Date(start);
  }
  if (!(end instanceof Date)) {
    end = new Date(end);
  }
  return Math.floor((end.getTime() - start.getTime()) / 86400000);
};

わずか 6 行のコードで、私たちのメソッドは Date オブジェクト、数値タイムスタンプ、さらには Sat Sep 08 2012 15:34:35 GMT+0200 (CEST) のような文字列を受け取るのに十分強力です

渡されるパラメータのタイプ (文字列、数値、ブール値) は、次のように変換できます:

function castaway(some_string, some_integer, some_boolean) {
  some_string += "";
  some_integer += 0; // parseInt(some_integer, 10) 更安全些
  some_boolean = !!some_boolean;
}

未定義の処理

API をより堅牢にするために、実際の未定義の値が渡されるかどうかを識別する必要があります。 、引数オブジェクトを確認できます:

function testUndefined(expecting, someArgument) {
  if (someArgument === undefined) {
    console.log("someArgument 是 undefined");
  }
  if (arguments.length > 1) {
    console.log("然而它实际是传进来的");
  }
}
testUndefined("foo");
// 结果: someArgument 是 undefined
testUndefined("foo", undefined);
// 结果:  someArgument 是 undefined , 然而它实际是传进来的

パラメータに名前を付けます

event.initMouseEvent(
  "click", true, true, window,
  123, 101, 202, 101, 202,
  true, false, false, false,
  1, null);

Event.initMouseEvent このメソッドは、ドキュメントを読まずに、各パラメータの意味を誰が理解できるでしょうか。

各パラメータに名前を付け、デフォルト値を割り当てます。できれば

event.initMouseEvent(
  type="click",
  canBubble=true,
  cancelable=true,
  view=window,
  detail=123,
  screenX=101,
  screenY=202,
  clientX=101,
  clientY=202,
  ctrlKey=true,
  altKey=false,
  shiftKey=false,
  metaKey=false,
  button=1,
  relatedTarget=null);

ES6、またはHarmonyには「デフォルトパラメータ値」と「残りのパラメータ」があります。

パラメータは JSON オブジェクトを受け取ります

大量のパラメータを受け取る代わりに、JSON オブジェクトを受け取る方が良いです:

function nightmare(accepts, async, beforeSend, cache, complete, /* 等28个参数 */) {
  if (accepts === "text") {
    // 准备接收纯文本
  }
}
function dream(options) {
  options = options || {};
  if (options.accepts === "text") {
    // 准备接收纯文本
  }
}

呼び出しも簡単です:

nightmare("text", true, undefined, false, undefined, /* 等28个参数 */);
dream({
  accepts: "text",
  async: true,
  cache: false
});

パラメータのデフォルト値

を持つことが最善ですjQuery.extend( ) http://underscorejs.org/#extend) および Protoype の Object.extend を介したパラメーターのデフォルト値。デフォルト値をオーバーライドできます。

var default_options = {
  accepts: "text",
  async: true,
  beforeSend: null,
  cache: false,
  complete: null,
  // …
};
function dream(options) {
  var o = jQuery.extend({}, default_options, options || {});
  console.log(o.accepts);
}
dream({ async: false });
// prints: "text"

拡張性

コールバック

コールバックを通じて、API ユーザーはコードの特定の部分をオーバーライドできます。カスタマイズが必要な一部の関数を構成可能なコールバック関数に開くと、API ユーザーがデフォルトのコードを簡単にオーバーライドできるようになります。

API インターフェースがコールバックを受け取ったら、必ずそれを文書化し、コード例を提供してください。

イベント

ネイティブ イベントとの名前の重複を避けるために、イベント インターフェイスの名前を知っておくことが最善です。

エラーの処理

すべてのエラーが開発者にとってコードのデバッグに役立つわけではありません:

// jQuery 允许这么写
$(document.body).on('click', {});
// 点击时报错
//   TypeError: ((p.event.special[l.origType] || {}).handle || l.handler).apply is not a function
//   in jQuery.min.js on Line 3

そのようなエラーはデバッグが困難です。開発者の時間を無駄にせず、開発者にどのような間違いを犯したかを直接伝えてください:

if (Object.prototype.toString.call(callback) !== '[object Function]') { // 看备注
  throw new TypeError("callback is not a function!");
}

備考: コールバックのタイプ=== 「関数」は古いブラウザでは問題が発生し、オブジェクトは関数として扱われます。

予測可能性

優れた API は予測可能であり、開発者は例に基づいてその使用法を推測できます。

Modernizr の機能検出はその一例です:

a) HTML5、CSS の概念、API に完全に一致する属性名を使用します

b) 個々の検出は一貫して true または false の値を返します

// 所有这些属性都返回 'true' 或 'false'
Modernizr.geolocation
Modernizr.localstorage
Modernizr.webworkers
Modernizr.canvas
Modernizr.borderradius
Modernizr.boxshadow
Modernizr.flexbox

開発者に依存します 馴染みのある概念は、予測可能な目的にも役立ちます。

jQuery のセレクター構文は、CSS1 ~ CSS3 セレクターを DOM セレクター エンジンで直接使用できる例です。

$("#grid") // Selects by ID
$("ul.nav > li") // All LIs for the UL with class "nav"
$("ul li:nth-child(2)") // Second item in each list

比例調整

優れた API は、必ずしも小さい API である必要はありません。API のサイズは、その機能に見合ったものでなければなりません。

たとえば、有名な日付解析および書式設定ライブラリである Moment.js は、その API が簡潔かつ機能的であると言えます。

Moment.js のような関数固有のライブラリの場合、API が焦点を絞って小さいことを確認することが重要です。

API ドキュメントの作成

ソフトウェア開発で最も難しいタスクの 1 つは、ドキュメントを作成することです。実際、最大の不満は、使いやすいドキュメント ツールがないことです。

以下は自動ドキュメント生成ツールです:

  • YUIDoc (Node.js、npmが必要)

  • JsDoc Toolkit (Node.js、npmが必要)

  • Markdox (Node.js、npmが必要) )

  • dox(node.js、npmが必要)

  • docco(node.js、python、coffeescriptが必要)

  • jsduck(ruby、gemが必要)

  • jsdoc3(Javaが必要)

最も重要なことは、ドキュメントとコードが同時に更新されていることを確認することです。

参考文献:

優れた API 設計

より良い JavaScript API の設計

素晴らしい JavaScript API 設計の秘密

経由: http://jinlong.github.io/2015/08/31/secrets-of-awesome -javascript -api-design/

上記は JavaScript API 設計原則の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。