Hatena::ブログ(Diary)

mizchi log

@mizchiの雑記帳

2013-03-19

javascriptのprototype拡張はどこまで許されるか


孫引きなんだけどちょっと気になった点

404 Blog Not Found:javascript - es2pi はじめました http://blog.livedoor.jp/dankogai/archives/51859796.html

本来の JavaScript の利用方法(Prototype 拡張)に立ち返り、Array.prototype, String.prototype, Number.prototype 等を拡張しています 

最近のJSは基本的に肥大化するし、DOMはグローバルな状態であり、またprototypeもどこからでもアクセスできるという点ではグローバルである。
手癖が悪い人はprototype経由で値の受け渡ししはじめる。JSではスコープチェーンなりで値の受け渡しをするように気をつけたい。

経験上、方針を決めずにprototypeを触りまくると遅かれ早かれ破綻する。が、元々プロトタイプ指向な言語だけに、うまく活用すると言語としての自由度がグンと上がる。そのバランスを取らないといけない。


以下にprototype拡張が許されると思しきケースを書く。

1. polyfill系ライブラリ


JS5未満の標準ライブラリは貧弱であり、それを補完する系のもの。ECMA Harmony もしくは Rubyインスパイアのものが多い。
このライブラリを使っている限りは、ライブラリが提供するコードを使うべきで、よくわからないからと自分で定義してしまうと、ロジックが重複して見通しが悪くなる。

2. オブジェクト宣言, prototype継承


JavaScriptでオブジェクト宣言する際は勿論prototype経由で振る舞いを定義することになる。

coffee-scriptで継承を実現する際は、次のようなスニペットが挿入される。

// Generated by CoffeeScript 1.6.1
(function() {
  var List,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) {
      for (var key in parent) {
        if (__hasProp.call(parent, key)) child[key] = parent[key];
      }
      function ctor() {
        this.constructor = child;
      }
      ctor.prototype = parent.prototype;
      child.prototype = new ctor();
      child.__super__ = parent.prototype; return child;
  };

  List = (function(_super) {

    __extends(List, _super);

    function List() {
      return List.__super__.constructor.apply(this, arguments);
    }

    return List;

  })(Array);
}).call(this);

このコードはArrayを継承したListクラスを作る。
まあ普通のprototype活用だとは思う。

3. 実装(not ライブラリ)


自分がフロントエンドを作る側で、かつ自分自身を継承する人がいない場合、独自の挙動を追加することは許されるとは思っている。
ただ、その場合1つのファイルを指定するなどの明示的なアプローチをとる必要がある。たとえば array_proto.js でArrayの拡張を書き、それ以外ではArray.prototypeは決して触れない、とか。

そしてpolyfill系ライブラリを使っている場合はある程度任せるべきで、かつ上書きしてはいけない。それでいてアプリケーションロジックの実行前に全部読み込んでおくべきだと思う。
プロトタイプはアプリケーション実行前後に同じものであってほしい。コード中で動的にprototypeオブジェクトを変更されるのは怖くて仕方ない。


まあ、便利だけど明示的に、ってのが自分の信条です。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/mizchi/20130319/1363701986