15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ECMA-262 (5th|Harmony|next) で宣言された プロトタイプ の拡張はアリ?ナシ?

Last updated at Posted at 2012-09-14

気になっているので質問スレ。

現況

現在、Webブラウザで実行する JavaScript における状況は基本 ECMA-262 3rd Edition 標準の実装を元にコーディングされ、開発者は(JScript|JavaScript)の実装間の差異などを自分でラッパーを書くか jQuery などでラップして開発をしているかと思います。

そして、ほぼ自動アップデートされるようになった Firefox, Chrome, Opera は着実に 5th Edition の仕様を実装しつづけており、canvas, CSS 3 もデモンストレーションの段階から、商用サイトでも利用されるようになってきています。

後押しするように、スマートフォン向けのブラウザも、HTML 5, CSS 3 がレンダリング(ベンダープレフィックスはつくものの)でき、5th Edition の実装も一部利用できるよう展開されています。

標準ライブラリへの拡張とプロトタイプ汚染

そこで気になるのが、IE 7,8,9 を始め、古いバージョンのブラウザの為に、ECMA Script の次世代仕様を実装することの是非です。

Prototype.js の流行の反動で、「標準ライブラリへのプロトタイプを書き換えるのは弊害があるので避けるべきなのでは」という流れがありました。Google JavaScript Style Guide でも「ビルトインオブジェクトのプロトタイプの書き換えはしてはならない」としています。

「もう既に実装済みのブラウザもあるし、追加しても”汚染”と呼ばなくてもよい」?

例えば

  • Array.prototype.forEach
  • Array.prototype.every
  • Object.defineProperty
  • Function.prototype.bind

などは Chrome や Firefox で実装済みであり、古いブラウザ向けに拡張しても、これまで語られてきた問題の対象になるのか?という疑問があります。

実装の実例

例えば Array.prototype.reduceMDNでこう紹介されています

if (!Array.prototype.reduce) {  
  Array.prototype.reduce = function reduce(accumulator){  
    if (this===null || this===undefined) throw new TypeError("Object is null or undefined");  
    var i = 0, l = this.length >> 0, curr;  
  
    if(typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."  
      throw new TypeError("First argument is not callable");  
  
    if(arguments.length < 2) {  
      if (l === 0) throw new TypeError("Array length is 0 and no second argument");  
      curr = this[0];  
      i = 1; // start accumulating at the second element  
    }  
    else  
      curr = arguments[1];  
  
    while (i < l) {  
      if(i in this) curr = accumulator.call(undefined, curr, this[i], i, this);  
      ++i;  
    }  
  
    return curr;  
  };  
}

この場合、Array.prototype.reduce がサポートされていないブラウザでのみ、実行されるようになっています。

自分の考える メリット・デメリット・やっても良い理由

メリット

  1. ビルトインオブジェクトの汎用性が高まって便利
  2. コードを全体で見た時にブラウザ間の違いによる条件分岐が減り、統一感が保たれる
  3. 3rd Edition で問題視されていた部分の解決が図られる
  4. 既存の js フレームワークへの疎結合を図れる

デメリット

  1. 未サポートブラウザのシェアが減るほど、デッドコード化する
  2. 自分のビルトインへの実装が間違っている可能性
  3. 手がけたものが息が長いライブラリであった場合、技術的負債を抱える可能性
  4. まだ仕様が最終勧告でないものは書き直しになる可能性

やってもよい理由

  1. 実質 Polyfill (新しい環境を基準に、古い環境へは新しい環境に近づけて差をなくす) な Web デザインがスタンダードになっている
  2. 既にサポートされているブラウザにとってパフォーマンスが低下する大きな原因となるものではない
  3. 少なくとも 5th Edition は既に仕様策定済みなので、これから仕様が変更される心配は無い
  4. 実装したプロダクトのライフサイクルが短ければデメリットの 3, 4 は杞憂では

メリット・デメリット についてコメントください

よろしくおねがいします

15
15
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?